[iOS] Upstream WebCore and Tools miscellaneous changes
authordbates@webkit.org <dbates@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 10 Jan 2014 17:06:52 +0000 (17:06 +0000)
committerdbates@webkit.org <dbates@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 10 Jan 2014 17:06:52 +0000 (17:06 +0000)
https://bugs.webkit.org/show_bug.cgi?id=126698

Reviewed by David Kilzer.

Source/WebCore:

* Configurations/Base.xcconfig:
* Configurations/WebCore.xcconfig:
* Configurations/WebCoreTestSupport.xcconfig:
* Configurations/iOS.xcconfig: Added.
* DerivedSources.make:
* English.lproj/Localizable.strings:
* Modules/airplay/WebKitPlaybackTargetAvailabilityEvent.cpp: Copied from Source/WebCore/editing/TextAffinity.h.
(WebCore::stringForPlaybackTargetAvailability):
(WebCore::WebKitPlaybackTargetAvailabilityEvent::WebKitPlaybackTargetAvailabilityEvent):
* Modules/airplay/WebKitPlaybackTargetAvailabilityEvent.h: Added.
(WebCore::WebKitPlaybackTargetAvailabilityEventInit::WebKitPlaybackTargetAvailabilityEventInit):
(WebCore::WebKitPlaybackTargetAvailabilityEvent::~WebKitPlaybackTargetAvailabilityEvent):
(WebCore::WebKitPlaybackTargetAvailabilityEvent::create):
(WebCore::WebKitPlaybackTargetAvailabilityEvent::availability):
* Modules/airplay/WebKitPlaybackTargetAvailabilityEvent.idl: Copied from Source/WebCore/editing/DeleteButton.h.
* Modules/geolocation/Geolocation.cpp:
(WebCore::Geolocation::Geolocation):
(WebCore::Geolocation::canSuspend):
(WebCore::Geolocation::suspend):
(WebCore::Geolocation::resume):
(WebCore::Geolocation::resumeTimerFired):
(WebCore::Geolocation::resetAllGeolocationPermission):
(WebCore::Geolocation::stop):
(WebCore::Geolocation::setIsAllowed):
(WebCore::Geolocation::positionChanged):
(WebCore::Geolocation::setError):
* Modules/geolocation/Geolocation.h:
* Modules/geolocation/NavigatorGeolocation.cpp:
(WebCore::NavigatorGeolocation::resetAllGeolocationPermission):
* Modules/geolocation/NavigatorGeolocation.h:
* Modules/speech/SpeechSynthesis.cpp:
(WebCore::SpeechSynthesis::SpeechSynthesis):
(WebCore::SpeechSynthesis::speak):
* Modules/speech/SpeechSynthesis.h:
(WebCore::SpeechSynthesis::userGestureRequiredForSpeechStart):
(WebCore::SpeechSynthesis::removeBehaviorRestriction):
* Modules/webaudio/AudioContext.cpp:
* Modules/webaudio/AudioContext.h:
* Modules/webaudio/AudioScheduledSourceNode.cpp:
* Modules/webdatabase/Database.cpp:
* Modules/webdatabase/DatabaseBackendBase.cpp:
(WebCore::DatabaseBackendBase::performOpenAndVerify):
(WebCore::DatabaseBackendBase::incrementalVacuumIfNeeded):
* Modules/webdatabase/DatabaseContext.cpp:
(WebCore::DatabaseContext::DatabaseContext):
(WebCore::DatabaseContext::databaseThread):
(WebCore::DatabaseContext::setPaused):
* Modules/webdatabase/DatabaseContext.h:
* Modules/webdatabase/DatabaseManagerClient.h:
* Modules/webdatabase/DatabaseTask.cpp:
(WebCore::DatabaseTask::performTask):
(WebCore::Database::DatabaseTransactionTask::shouldPerformWhilePaused):
* Modules/webdatabase/DatabaseTask.h:
* Modules/webdatabase/DatabaseThread.cpp:
(WebCore::DatabaseThread::DatabaseThread):
(WebCore::DatabaseThread::requestTermination):
(WebCore::DatabaseUnpauseTask::create):
(WebCore::DatabaseUnpauseTask::shouldPerformWhilePaused):
(WebCore::DatabaseUnpauseTask::DatabaseUnpauseTask):
(WebCore::DatabaseUnpauseTask::doPerformTask):
(WebCore::DatabaseUnpauseTask::debugTaskName):
(WebCore::DatabaseThread::setPaused):
(WebCore::DatabaseThread::handlePausedQueue):
(WebCore::DatabaseThread::databaseThread):
* Modules/webdatabase/DatabaseThread.h:
* Modules/webdatabase/DatabaseTracker.cpp:
(WebCore::DatabaseTracker::setQuota):
(WebCore::DatabaseTracker::deleteOrigin):
(WebCore::DatabaseTracker::deleteDatabase):
(WebCore::DatabaseTracker::deleteDatabaseFile):
(WebCore::DatabaseTracker::removeDeletedOpenedDatabases):
(WebCore::isZeroByteFile):
(WebCore::DatabaseTracker::deleteDatabaseFileIfEmpty):
(WebCore::DatabaseTracker::openDatabaseMutex):
(WebCore::DatabaseTracker::emptyDatabaseFilesRemovalTaskWillBeScheduled):
(WebCore::DatabaseTracker::emptyDatabaseFilesRemovalTaskDidFinish):
(WebCore::DatabaseTracker::setDatabasesPaused):
* Modules/webdatabase/DatabaseTracker.h:
* Modules/webdatabase/SQLTransactionBackend.cpp:
(WebCore::SQLTransactionBackend::shouldPerformWhilePaused):
* Modules/webdatabase/SQLTransactionBackend.h:
* Resources/DictationPhraseWithAlternativesDot.png: Added.
* Resources/DictationPhraseWithAlternativesDot@2x.png: Added.
* Resources/SpellingDot.png: Added.
* Resources/SpellingDot@2x.png: Added.
* Resources/decrementArrow.tiff: Added.
* Resources/hScrollControl_left.png: Added.
* Resources/hScrollControl_middle.png: Added.
* Resources/hScrollControl_right.png: Added.
* Resources/incrementArrow.tiff: Added.
* Resources/markedLeft.png: Added.
* Resources/markedMiddle.png: Added.
* Resources/markedRight.png: Added.
* Resources/vScrollControl_bottom.png: Added.
* Resources/vScrollControl_middle.png: Added.
* Resources/vScrollControl_top.png: Added.
* WebCore.xcodeproj/project.pbxproj:
* bindings/js/GCController.cpp:
(WebCore::GCController::garbageCollectNow):
(WebCore::GCController::releaseExecutableMemory):
* bindings/js/GCController.h:
* bindings/js/JSCallbackData.h:
(WebCore::JSCallbackData::~JSCallbackData):
* bindings/js/JSDOMWindowBase.cpp:
(WebCore::JSDOMWindowBase::supportsProfiling):
(WebCore::JSDOMWindowBase::shouldInterruptScriptBeforeTimeout):
(WebCore::JSDOMWindowBase::commonVM):
(WebCore::JSDOMWindowBase::commonVMExists):
(WebCore::JSDOMWindowBase::commonVMInternal):
* bindings/js/JSDOMWindowCustom.cpp:
(WebCore::JSDOMWindow::touch):
(WebCore::JSDOMWindow::touchList):
* bindings/js/JSDeviceOrientationEventCustom.cpp:
(WebCore::JSDeviceOrientationEvent::webkitCompassHeading):
(WebCore::JSDeviceOrientationEvent::webkitCompassAccuracy):
(WebCore::JSDeviceOrientationEvent::initDeviceOrientationEvent):
* bindings/js/JSMainThreadExecState.h:
* bindings/js/JSTouchCustom.cpp:
* bindings/js/JSTouchListCustom.cpp:
* bindings/js/PageScriptDebugServer.cpp:
(WebCore::PageScriptDebugServer::didContinue):
* bindings/js/ScriptController.cpp:
(WebCore::ScriptController::initializeThreading):
* bindings/js/ScriptDebugServer.cpp:
(WebCore::ScriptDebugServer::handlePause):
* bindings/js/ios/TouchConstructors.cpp: Added.
* bindings/objc/DOM.mm:
(WebCore::wkQuadFromFloatQuad):
(WebCore::kit):
(WebCore::min4):
(WebCore::max4):
(WebCore::emptyQuad):
(-[WKQuadObject initWithQuad:]):
(-[WKQuadObject quad]):
(-[WKQuadObject boundingBox]):
(-[DOMNode boundingBox]):
(-[DOMNode absoluteQuad]):
(-[DOMNode absoluteQuadAndInsideFixedPosition:]):
(-[DOMNode boundingBoxUsingTransforms]):
(-[DOMNode lineBoxQuads]):
(-[DOMNode _linkElement]):
(-[DOMNode hrefURL]):
(-[DOMNode hrefTarget]):
(-[DOMNode hrefFrame]):
(-[DOMNode hrefLabel]):
(-[DOMNode hrefTitle]):
(-[DOMNode boundingFrame]):
(-[DOMNode innerFrameQuad]):
(-[DOMNode computedFontSize]):
(-[DOMNode nextFocusNode]):
(-[DOMNode previousFocusNode]):
(-[DOMRange boundingBox]):
(-[DOMRange renderedImageForcingBlackText:renderedImageForcingBlackText:]):
(-[DOMElement _font]):
(-[DOMHTMLLinkElement _mediaQueryMatchesForOrientation:]):
(-[DOMHTMLLinkElement _mediaQueryMatches]):
* bindings/objc/DOMEvents.h:
* bindings/objc/DOMEvents.mm:
(kitClass):
* bindings/objc/DOMExtensions.h:
* bindings/objc/DOMHTML.mm:
(-[DOMHTMLElement scrollYOffset]):
(-[DOMHTMLElement setScrollXOffset:scrollYOffset:]):
(-[DOMHTMLElement setScrollXOffset:scrollYOffset:adjustForIOSCaret:]):
(-[DOMHTMLElement absolutePosition::::]):
(-[DOMHTMLInputElement _autocapitalizeType]):
(-[DOMHTMLTextAreaElement _autocapitalizeType]):
(-[DOMHTMLInputElement setValueWithChangeEvent:]):
(-[DOMHTMLInputElement setValueAsNumberWithChangeEvent:]):
* bindings/objc/DOMInternal.h:
* bindings/objc/DOMInternal.mm:
(wrapperCacheLock):
(getDOMWrapper):
(addDOMWrapper):
(removeDOMWrapper):
* bindings/objc/DOMPrivate.h:
* bindings/objc/DOMUIKitExtensions.h: Added.
* bindings/objc/DOMUIKitExtensions.mm: Added.
* bindings/objc/PublicDOMInterfaces.h:
* bindings/scripts/CodeGeneratorJS.pm:
(GenerateHeaderContentHeader):
(GenerateImplementationContentHeader):
(GenerateHeader):
(GenerateImplementation):
(GenerateCallbackImplementation):
* bindings/scripts/CodeGeneratorObjC.pm:
(ReadPublicInterfaces):
(GetClassName):
(IsCoreFoundationType):
(GetObjCType):
(AddIncludesForType):
(GenerateHeader):
(GenerateImplementation):
(WriteData):
* bindings/scripts/IDLAttributes.txt:
* bindings/scripts/preprocessor.pm:
(applyPreprocessor):
* bridge/objc/objc_class.mm:
(JSC::Bindings::ObjcClass::fieldNamed):
* bridge/objc/objc_instance.mm:
* config.h:
* dom/Document.cpp:
(WebCore::Document::addAutoSizingNode):
* dom/Document.h:
* dom/Document.idl:
* dom/ios/TouchEvents.cpp: Added.
* editing/ApplyStyleCommand.cpp:
(WebCore::ApplyStyleCommand::applyBlockStyle):
* editing/CompositeEditCommand.cpp:
(WebCore::EditCommandComposition::unapply):
(WebCore::CompositeEditCommand::apply):
(WebCore::CompositeEditCommand::inputText):
(WebCore::CompositeEditCommand::replaceTextInNodePreservingMarkers):
(WebCore::CompositeEditCommand::moveParagraphs):
* editing/CompositeEditCommand.h:
* editing/DeleteButton.h:
* editing/DeleteButtonController.cpp:
(WebCore::DeleteButtonController::enable):
(WebCore::DeleteButtonController::disable):
* editing/DeleteSelectionCommand.cpp:
(WebCore::DeleteSelectionCommand::doApply):
* editing/DeleteSelectionCommand.h:
* editing/EditAction.h:
* editing/EditCommand.h:
(WebCore::EditCommand::isInsertTextCommand):
* editing/EditingStyle.cpp:
* editing/Editor.cpp:
(WebCore::ClearTextCommand::ClearTextCommand):
(WebCore::ClearTextCommand::editingAction):
(WebCore::ClearTextCommand::CreateAndApply):
(WebCore::Editor::handleTextEvent):
(WebCore::Editor::clearText):
(WebCore::Editor::insertDictationPhrases):
(WebCore::Editor::setDictationPhrasesAsChildOfElement):
(WebCore::Editor::confirmMarkedText):
(WebCore::Editor::setTextAsChildOfElement):
(WebCore::Editor::notifyComponentsOnChangedSelection):
(WebCore::Editor::ensureLastEditCommandHasCurrentSelectionIfOpenForMoreTyping):
(WebCore::Editor::copy):
(WebCore::Editor::setBaseWritingDirection):
(WebCore::Editor::setComposition):
(WebCore::Editor::showSpellingGuessPanel):
(WebCore::Editor::markMisspellingsAfterTypingToWord):
(WebCore::Editor::markMisspellingsOrBadGrammar):
(WebCore::Editor::changeBackToReplacedString):
(WebCore::Editor::updateMarkersForWordsAffectedByEditing):
(WebCore::Editor::setIgnoreCompositionSelectionChange):
(WebCore::Editor::changeSelectionAfterCommand):
(WebCore::Editor::shouldChangeSelection):
(WebCore::Editor::respondToChangedSelection):
(WebCore::Editor::resolveTextCheckingTypeMask):
* editing/Editor.h:
* editing/EditorCommand.cpp:
(WebCore::executeClearText):
(WebCore::enabledCopy):
(WebCore::enabledCut):
(WebCore::enabledClearText):
(WebCore::createCommandMap):
* editing/FrameSelection.cpp:
(WebCore::FrameSelection::FrameSelection):
(WebCore::FrameSelection::setSelection):
(WebCore::FrameSelection::modifyExtendingRight):
(WebCore::FrameSelection::modifyExtendingForward):
(WebCore::FrameSelection::modifyMovingRight):
(WebCore::FrameSelection::modifyMovingForward):
(WebCore::FrameSelection::modifyExtendingLeft):
(WebCore::FrameSelection::modifyExtendingBackward):
(WebCore::FrameSelection::modifyMovingLeft):
(WebCore::FrameSelection::modifyMovingBackward):
(WebCore::FrameSelection::setSelectedRange):
(WebCore::FrameSelection::focusedOrActiveStateChanged):
(WebCore::FrameSelection::updateAppearance):
(WebCore::FrameSelection::shouldDeleteSelection):
(WebCore::FrameSelection::revealSelection):
(WebCore::FrameSelection::setSelectionFromNone):
(WebCore::FrameSelection::shouldChangeSelection):
(WebCore::FrameSelection::expandSelectionToElementContainingCaretSelection):
(WebCore::FrameSelection::elementRangeContainingCaretSelection):
(WebCore::FrameSelection::expandSelectionToWordContainingCaretSelection):
(WebCore::FrameSelection::wordRangeContainingCaretSelection):
(WebCore::FrameSelection::expandSelectionToStartOfWordContainingCaretSelection):
(WebCore::FrameSelection::characterInRelationToCaretSelection):
(WebCore::FrameSelection::characterBeforeCaretSelection):
(WebCore::FrameSelection::characterAfterCaretSelection):
(WebCore::FrameSelection::wordOffsetInRange):
(WebCore::FrameSelection::spaceFollowsWordInRange):
(WebCore::FrameSelection::selectionAtDocumentStart):
(WebCore::FrameSelection::selectionAtSentenceStart):
(WebCore::FrameSelection::selectionAtWordStart):
(WebCore::FrameSelection::rangeByMovingCurrentSelection):
(WebCore::FrameSelection::rangeByExtendingCurrentSelection):
(WebCore::FrameSelection::selectRangeOnElement):
(WebCore::FrameSelection::wordSelectionContainingCaretSelection):
(WebCore::FrameSelection::actualSelectionAtSentenceStart):
(WebCore::FrameSelection::rangeByAlteringCurrentSelection):
(WebCore::FrameSelection::clearCurrentSelection):
(WebCore::FrameSelection::setCaretBlinks):
(WebCore::FrameSelection::setCaretColor):
* editing/FrameSelection.h:
(WebCore::FrameSelection::suppressCloseTyping):
(WebCore::FrameSelection::restoreCloseTyping):
(WebCore::FrameSelection::setUpdateAppearanceEnabled):
(WebCore::FrameSelection::suppressScrolling):
(WebCore::FrameSelection::restoreScrolling):
* editing/InsertIntoTextNodeCommand.cpp:
(WebCore::InsertIntoTextNodeCommand::doReapply):
* editing/InsertIntoTextNodeCommand.h:
* editing/InsertTextCommand.h:
* editing/ReplaceSelectionCommand.cpp:
(WebCore::ReplaceSelectionCommand::doApply):
* editing/TextAffinity.h:
* editing/TextCheckingHelper.cpp:
* editing/TextGranularity.h:
* editing/TextIterator.cpp:
(WebCore::isRendererReplacedElement):
* editing/TypingCommand.cpp:
(WebCore::TypingCommand::ensureLastEditCommandHasCurrentSelectionIfOpenForMoreTyping):
(WebCore::TypingCommand::markMisspellingsAfterTyping):
(WebCore::TypingCommand::deleteKeyPressed):
(WebCore::TypingCommand::forwardDeleteKeyPressed):
(WebCore::FriendlyEditCommand::setEndingSelection):
(WebCore::TypingCommand::setEndingSelectionOnLastInsertCommand):
* editing/TypingCommand.h:
* editing/VisiblePosition.h:
(WebCore::operator<):
(WebCore::operator>):
(WebCore::operator<=):
(WebCore::operator>=):
* editing/VisibleSelection.cpp:
(WebCore::VisibleSelection::setStartAndEndFromBaseAndExtentRespectingGranularity):
(WebCore::VisibleSelection::adjustSelectionToAvoidCrossingEditingBoundaries):
* editing/VisibleUnits.cpp:
(WebCore::previousBoundary):
(WebCore::nextBoundary):
(WebCore::startOfDocument):
(WebCore::endOfDocument):
(WebCore::directionIsDownstream):
(WebCore::atBoundaryOfGranularity):
(WebCore::withinTextUnitOfGranularity):
(WebCore::nextCharacterBoundaryInDirection):
(WebCore::nextWordBoundaryInDirection):
(WebCore::nextSentenceBoundaryInDirection):
(WebCore::nextLineBoundaryInDirection):
(WebCore::nextParagraphBoundaryInDirection):
(WebCore::nextDocumentBoundaryInDirection):
(WebCore::positionOfNextBoundaryOfGranularity):
(WebCore::enclosingTextUnitOfGranularity):
(WebCore::distanceBetweenPositions):
(WebCore::wordRangeFromPosition):
(WebCore::closestWordBoundaryForPosition):
* editing/VisibleUnits.h:
* editing/ios/DictationCommandIOS.cpp: Added.
* editing/ios/DictationCommandIOS.h: Added.
(WebCore::DictationCommandIOS::create):
(WebCore::DictationCommandIOS::editingAction):
* editing/mac/FrameSelectionMac.mm:
(WebCore::FrameSelection::notifyAccessibilityForSelectionChange):
* fileapi/AsyncFileStream.cpp:
* generate-export-file: Added.
* inspector/InspectorCounters.h:
* inspector/InspectorFrontendHost.h:
* make-export-file-generator:
* plugins/PluginPackage.h:
* plugins/PluginViewBase.h:
(WebCore::PluginViewBase::willProvidePluginLayer):
(WebCore::PluginViewBase::attachPluginLayer):
(WebCore::PluginViewBase::detachPluginLayer):
* style/StyleResolveForDocument.cpp:
(WebCore::Style::resolveForDocument):
* style/StyleResolveTree.cpp:
(WebCore::Style::elementImplicitVisibility):
* testing/Internals.cpp:
(WebCore::Internals::getCurrentCursorInfo):
(WebCore::Internals::isSelectPopupVisible):
* workers/WorkerThread.cpp:
(WebCore::WorkerThread::workerThread):

Source/WebKit:

* WebKit.xcodeproj/project.pbxproj:

Source/WebKit/mac:

* MigrateHeaders.make:

Tools:

* Scripts/check-for-inappropriate-objc-class-names:
* Scripts/check-for-webkit-framework-include-consistency:

git-svn-id: http://svn.webkit.org/repository/webkit/trunk@161638 268f45cc-cd09-0410-ab3c-d52691b4dbfc

133 files changed:
Source/WebCore/ChangeLog
Source/WebCore/Configurations/Base.xcconfig
Source/WebCore/Configurations/WebCore.xcconfig
Source/WebCore/Configurations/WebCoreTestSupport.xcconfig
Source/WebCore/Configurations/iOS.xcconfig [new file with mode: 0644]
Source/WebCore/DerivedSources.make
Source/WebCore/English.lproj/Localizable.strings
Source/WebCore/Modules/airplay/WebKitPlaybackTargetAvailabilityEvent.cpp [new file with mode: 0644]
Source/WebCore/Modules/airplay/WebKitPlaybackTargetAvailabilityEvent.h [new file with mode: 0644]
Source/WebCore/Modules/airplay/WebKitPlaybackTargetAvailabilityEvent.idl [new file with mode: 0644]
Source/WebCore/Modules/geolocation/Geolocation.cpp
Source/WebCore/Modules/geolocation/Geolocation.h
Source/WebCore/Modules/geolocation/NavigatorGeolocation.cpp
Source/WebCore/Modules/geolocation/NavigatorGeolocation.h
Source/WebCore/Modules/speech/SpeechSynthesis.cpp
Source/WebCore/Modules/speech/SpeechSynthesis.h
Source/WebCore/Modules/webaudio/AudioContext.cpp
Source/WebCore/Modules/webaudio/AudioContext.h
Source/WebCore/Modules/webaudio/AudioScheduledSourceNode.cpp
Source/WebCore/Modules/webdatabase/Database.cpp
Source/WebCore/Modules/webdatabase/DatabaseBackendBase.cpp
Source/WebCore/Modules/webdatabase/DatabaseContext.cpp
Source/WebCore/Modules/webdatabase/DatabaseContext.h
Source/WebCore/Modules/webdatabase/DatabaseManagerClient.h
Source/WebCore/Modules/webdatabase/DatabaseTask.cpp
Source/WebCore/Modules/webdatabase/DatabaseTask.h
Source/WebCore/Modules/webdatabase/DatabaseThread.cpp
Source/WebCore/Modules/webdatabase/DatabaseThread.h
Source/WebCore/Modules/webdatabase/DatabaseTracker.cpp
Source/WebCore/Modules/webdatabase/DatabaseTracker.h
Source/WebCore/Modules/webdatabase/SQLTransactionBackend.cpp
Source/WebCore/Modules/webdatabase/SQLTransactionBackend.h
Source/WebCore/Resources/DictationPhraseWithAlternativesDot.png [new file with mode: 0644]
Source/WebCore/Resources/DictationPhraseWithAlternativesDot@2x.png [new file with mode: 0644]
Source/WebCore/Resources/SpellingDot.png [new file with mode: 0644]
Source/WebCore/Resources/SpellingDot@2x.png [new file with mode: 0644]
Source/WebCore/Resources/decrementArrow.tiff [new file with mode: 0644]
Source/WebCore/Resources/hScrollControl_left.png [new file with mode: 0644]
Source/WebCore/Resources/hScrollControl_middle.png [new file with mode: 0644]
Source/WebCore/Resources/hScrollControl_right.png [new file with mode: 0644]
Source/WebCore/Resources/incrementArrow.tiff [new file with mode: 0644]
Source/WebCore/Resources/markedLeft.png [new file with mode: 0644]
Source/WebCore/Resources/markedMiddle.png [new file with mode: 0644]
Source/WebCore/Resources/markedRight.png [new file with mode: 0644]
Source/WebCore/Resources/vScrollControl_bottom.png [new file with mode: 0644]
Source/WebCore/Resources/vScrollControl_middle.png [new file with mode: 0644]
Source/WebCore/Resources/vScrollControl_top.png [new file with mode: 0644]
Source/WebCore/WebCore.xcodeproj/project.pbxproj
Source/WebCore/bindings/js/GCController.cpp
Source/WebCore/bindings/js/GCController.h
Source/WebCore/bindings/js/JSCallbackData.h
Source/WebCore/bindings/js/JSDOMWindowBase.cpp
Source/WebCore/bindings/js/JSDOMWindowCustom.cpp
Source/WebCore/bindings/js/JSDeviceOrientationEventCustom.cpp
Source/WebCore/bindings/js/JSMainThreadExecState.h
Source/WebCore/bindings/js/JSTouchCustom.cpp
Source/WebCore/bindings/js/JSTouchListCustom.cpp
Source/WebCore/bindings/js/PageScriptDebugServer.cpp
Source/WebCore/bindings/js/ScriptController.cpp
Source/WebCore/bindings/js/ScriptDebugServer.cpp
Source/WebCore/bindings/js/ios/TouchConstructors.cpp [new file with mode: 0644]
Source/WebCore/bindings/objc/DOM.mm
Source/WebCore/bindings/objc/DOMEvents.h
Source/WebCore/bindings/objc/DOMEvents.mm
Source/WebCore/bindings/objc/DOMExtensions.h
Source/WebCore/bindings/objc/DOMHTML.mm
Source/WebCore/bindings/objc/DOMInternal.h
Source/WebCore/bindings/objc/DOMInternal.mm
Source/WebCore/bindings/objc/DOMPrivate.h
Source/WebCore/bindings/objc/DOMUIKitExtensions.h [new file with mode: 0644]
Source/WebCore/bindings/objc/DOMUIKitExtensions.mm [new file with mode: 0644]
Source/WebCore/bindings/objc/PublicDOMInterfaces.h
Source/WebCore/bindings/scripts/CodeGeneratorJS.pm
Source/WebCore/bindings/scripts/CodeGeneratorObjC.pm
Source/WebCore/bindings/scripts/IDLAttributes.txt
Source/WebCore/bindings/scripts/preprocessor.pm
Source/WebCore/bridge/objc/objc_class.mm
Source/WebCore/bridge/objc/objc_instance.mm
Source/WebCore/config.h
Source/WebCore/dom/Document.cpp
Source/WebCore/dom/Document.h
Source/WebCore/dom/Document.idl
Source/WebCore/dom/ios/TouchEvents.cpp [new file with mode: 0644]
Source/WebCore/editing/ApplyStyleCommand.cpp
Source/WebCore/editing/CompositeEditCommand.cpp
Source/WebCore/editing/CompositeEditCommand.h
Source/WebCore/editing/DeleteButton.h
Source/WebCore/editing/DeleteButtonController.cpp
Source/WebCore/editing/DeleteSelectionCommand.cpp
Source/WebCore/editing/DeleteSelectionCommand.h
Source/WebCore/editing/EditAction.h
Source/WebCore/editing/EditCommand.h
Source/WebCore/editing/EditingStyle.cpp
Source/WebCore/editing/Editor.cpp
Source/WebCore/editing/Editor.h
Source/WebCore/editing/EditorCommand.cpp
Source/WebCore/editing/FrameSelection.cpp
Source/WebCore/editing/FrameSelection.h
Source/WebCore/editing/InsertIntoTextNodeCommand.cpp
Source/WebCore/editing/InsertIntoTextNodeCommand.h
Source/WebCore/editing/InsertTextCommand.h
Source/WebCore/editing/ReplaceSelectionCommand.cpp
Source/WebCore/editing/TextAffinity.h
Source/WebCore/editing/TextCheckingHelper.cpp
Source/WebCore/editing/TextGranularity.h
Source/WebCore/editing/TextIterator.cpp
Source/WebCore/editing/TypingCommand.cpp
Source/WebCore/editing/TypingCommand.h
Source/WebCore/editing/VisiblePosition.h
Source/WebCore/editing/VisibleSelection.cpp
Source/WebCore/editing/VisibleUnits.cpp
Source/WebCore/editing/VisibleUnits.h
Source/WebCore/editing/ios/DictationCommandIOS.cpp [new file with mode: 0644]
Source/WebCore/editing/ios/DictationCommandIOS.h [new file with mode: 0644]
Source/WebCore/editing/mac/FrameSelectionMac.mm
Source/WebCore/fileapi/AsyncFileStream.cpp
Source/WebCore/generate-export-file [new file with mode: 0755]
Source/WebCore/inspector/InspectorCounters.h
Source/WebCore/inspector/InspectorFrontendHost.h
Source/WebCore/make-export-file-generator
Source/WebCore/plugins/PluginPackage.h
Source/WebCore/plugins/PluginViewBase.h
Source/WebCore/style/StyleResolveForDocument.cpp
Source/WebCore/style/StyleResolveTree.cpp
Source/WebCore/testing/Internals.cpp
Source/WebCore/workers/WorkerThread.cpp
Source/WebKit/ChangeLog
Source/WebKit/WebKit.xcodeproj/project.pbxproj
Source/WebKit/mac/ChangeLog
Source/WebKit/mac/MigrateHeaders.make
Tools/ChangeLog
Tools/Scripts/check-for-inappropriate-objc-class-names
Tools/Scripts/check-for-webkit-framework-include-consistency

index f432138..92f5f60 100644 (file)
@@ -1,5 +1,389 @@
 2014-01-10  Daniel Bates  <dabates@apple.com>
 
+        [iOS] Upstream WebCore and Tools miscellaneous changes
+        https://bugs.webkit.org/show_bug.cgi?id=126698
+
+        Reviewed by David Kilzer.
+
+        * Configurations/Base.xcconfig:
+        * Configurations/WebCore.xcconfig:
+        * Configurations/WebCoreTestSupport.xcconfig:
+        * Configurations/iOS.xcconfig: Added.
+        * DerivedSources.make:
+        * English.lproj/Localizable.strings:
+        * Modules/airplay/WebKitPlaybackTargetAvailabilityEvent.cpp: Copied from Source/WebCore/editing/TextAffinity.h.
+        (WebCore::stringForPlaybackTargetAvailability):
+        (WebCore::WebKitPlaybackTargetAvailabilityEvent::WebKitPlaybackTargetAvailabilityEvent):
+        * Modules/airplay/WebKitPlaybackTargetAvailabilityEvent.h: Added.
+        (WebCore::WebKitPlaybackTargetAvailabilityEventInit::WebKitPlaybackTargetAvailabilityEventInit):
+        (WebCore::WebKitPlaybackTargetAvailabilityEvent::~WebKitPlaybackTargetAvailabilityEvent):
+        (WebCore::WebKitPlaybackTargetAvailabilityEvent::create):
+        (WebCore::WebKitPlaybackTargetAvailabilityEvent::availability):
+        * Modules/airplay/WebKitPlaybackTargetAvailabilityEvent.idl: Copied from Source/WebCore/editing/DeleteButton.h.
+        * Modules/geolocation/Geolocation.cpp:
+        (WebCore::Geolocation::Geolocation):
+        (WebCore::Geolocation::canSuspend):
+        (WebCore::Geolocation::suspend):
+        (WebCore::Geolocation::resume):
+        (WebCore::Geolocation::resumeTimerFired):
+        (WebCore::Geolocation::resetAllGeolocationPermission):
+        (WebCore::Geolocation::stop):
+        (WebCore::Geolocation::setIsAllowed):
+        (WebCore::Geolocation::positionChanged):
+        (WebCore::Geolocation::setError):
+        * Modules/geolocation/Geolocation.h:
+        * Modules/geolocation/NavigatorGeolocation.cpp:
+        (WebCore::NavigatorGeolocation::resetAllGeolocationPermission):
+        * Modules/geolocation/NavigatorGeolocation.h:
+        * Modules/speech/SpeechSynthesis.cpp:
+        (WebCore::SpeechSynthesis::SpeechSynthesis):
+        (WebCore::SpeechSynthesis::speak):
+        * Modules/speech/SpeechSynthesis.h:
+        (WebCore::SpeechSynthesis::userGestureRequiredForSpeechStart):
+        (WebCore::SpeechSynthesis::removeBehaviorRestriction):
+        * Modules/webaudio/AudioContext.cpp:
+        * Modules/webaudio/AudioContext.h:
+        * Modules/webaudio/AudioScheduledSourceNode.cpp:
+        * Modules/webdatabase/Database.cpp:
+        * Modules/webdatabase/DatabaseBackendBase.cpp:
+        (WebCore::DatabaseBackendBase::performOpenAndVerify):
+        (WebCore::DatabaseBackendBase::incrementalVacuumIfNeeded):
+        * Modules/webdatabase/DatabaseContext.cpp:
+        (WebCore::DatabaseContext::DatabaseContext):
+        (WebCore::DatabaseContext::databaseThread):
+        (WebCore::DatabaseContext::setPaused):
+        * Modules/webdatabase/DatabaseContext.h:
+        * Modules/webdatabase/DatabaseManagerClient.h:
+        * Modules/webdatabase/DatabaseTask.cpp:
+        (WebCore::DatabaseTask::performTask):
+        (WebCore::Database::DatabaseTransactionTask::shouldPerformWhilePaused):
+        * Modules/webdatabase/DatabaseTask.h:
+        * Modules/webdatabase/DatabaseThread.cpp:
+        (WebCore::DatabaseThread::DatabaseThread):
+        (WebCore::DatabaseThread::requestTermination):
+        (WebCore::DatabaseUnpauseTask::create):
+        (WebCore::DatabaseUnpauseTask::shouldPerformWhilePaused):
+        (WebCore::DatabaseUnpauseTask::DatabaseUnpauseTask):
+        (WebCore::DatabaseUnpauseTask::doPerformTask):
+        (WebCore::DatabaseUnpauseTask::debugTaskName):
+        (WebCore::DatabaseThread::setPaused):
+        (WebCore::DatabaseThread::handlePausedQueue):
+        (WebCore::DatabaseThread::databaseThread):
+        * Modules/webdatabase/DatabaseThread.h:
+        * Modules/webdatabase/DatabaseTracker.cpp:
+        (WebCore::DatabaseTracker::setQuota):
+        (WebCore::DatabaseTracker::deleteOrigin):
+        (WebCore::DatabaseTracker::deleteDatabase):
+        (WebCore::DatabaseTracker::deleteDatabaseFile):
+        (WebCore::DatabaseTracker::removeDeletedOpenedDatabases):
+        (WebCore::isZeroByteFile):
+        (WebCore::DatabaseTracker::deleteDatabaseFileIfEmpty):
+        (WebCore::DatabaseTracker::openDatabaseMutex):
+        (WebCore::DatabaseTracker::emptyDatabaseFilesRemovalTaskWillBeScheduled):
+        (WebCore::DatabaseTracker::emptyDatabaseFilesRemovalTaskDidFinish):
+        (WebCore::DatabaseTracker::setDatabasesPaused):
+        * Modules/webdatabase/DatabaseTracker.h:
+        * Modules/webdatabase/SQLTransactionBackend.cpp:
+        (WebCore::SQLTransactionBackend::shouldPerformWhilePaused):
+        * Modules/webdatabase/SQLTransactionBackend.h:
+        * Resources/DictationPhraseWithAlternativesDot.png: Added.
+        * Resources/DictationPhraseWithAlternativesDot@2x.png: Added.
+        * Resources/SpellingDot.png: Added.
+        * Resources/SpellingDot@2x.png: Added.
+        * Resources/decrementArrow.tiff: Added.
+        * Resources/hScrollControl_left.png: Added.
+        * Resources/hScrollControl_middle.png: Added.
+        * Resources/hScrollControl_right.png: Added.
+        * Resources/incrementArrow.tiff: Added.
+        * Resources/markedLeft.png: Added.
+        * Resources/markedMiddle.png: Added.
+        * Resources/markedRight.png: Added.
+        * Resources/vScrollControl_bottom.png: Added.
+        * Resources/vScrollControl_middle.png: Added.
+        * Resources/vScrollControl_top.png: Added.
+        * WebCore.xcodeproj/project.pbxproj:
+        * bindings/js/GCController.cpp:
+        (WebCore::GCController::garbageCollectNow):
+        (WebCore::GCController::releaseExecutableMemory):
+        * bindings/js/GCController.h:
+        * bindings/js/JSCallbackData.h:
+        (WebCore::JSCallbackData::~JSCallbackData):
+        * bindings/js/JSDOMWindowBase.cpp:
+        (WebCore::JSDOMWindowBase::supportsProfiling):
+        (WebCore::JSDOMWindowBase::shouldInterruptScriptBeforeTimeout):
+        (WebCore::JSDOMWindowBase::commonVM):
+        (WebCore::JSDOMWindowBase::commonVMExists):
+        (WebCore::JSDOMWindowBase::commonVMInternal):
+        * bindings/js/JSDOMWindowCustom.cpp:
+        (WebCore::JSDOMWindow::touch):
+        (WebCore::JSDOMWindow::touchList):
+        * bindings/js/JSDeviceOrientationEventCustom.cpp:
+        (WebCore::JSDeviceOrientationEvent::webkitCompassHeading):
+        (WebCore::JSDeviceOrientationEvent::webkitCompassAccuracy):
+        (WebCore::JSDeviceOrientationEvent::initDeviceOrientationEvent):
+        * bindings/js/JSMainThreadExecState.h:
+        * bindings/js/JSTouchCustom.cpp:
+        * bindings/js/JSTouchListCustom.cpp:
+        * bindings/js/PageScriptDebugServer.cpp:
+        (WebCore::PageScriptDebugServer::didContinue):
+        * bindings/js/ScriptController.cpp:
+        (WebCore::ScriptController::initializeThreading):
+        * bindings/js/ScriptDebugServer.cpp:
+        (WebCore::ScriptDebugServer::handlePause):
+        * bindings/js/ios/TouchConstructors.cpp: Added.
+        * bindings/objc/DOM.mm:
+        (WebCore::wkQuadFromFloatQuad):
+        (WebCore::kit):
+        (WebCore::min4):
+        (WebCore::max4):
+        (WebCore::emptyQuad):
+        (-[WKQuadObject initWithQuad:]):
+        (-[WKQuadObject quad]):
+        (-[WKQuadObject boundingBox]):
+        (-[DOMNode boundingBox]):
+        (-[DOMNode absoluteQuad]):
+        (-[DOMNode absoluteQuadAndInsideFixedPosition:]):
+        (-[DOMNode boundingBoxUsingTransforms]):
+        (-[DOMNode lineBoxQuads]):
+        (-[DOMNode _linkElement]):
+        (-[DOMNode hrefURL]):
+        (-[DOMNode hrefTarget]):
+        (-[DOMNode hrefFrame]):
+        (-[DOMNode hrefLabel]):
+        (-[DOMNode hrefTitle]):
+        (-[DOMNode boundingFrame]):
+        (-[DOMNode innerFrameQuad]):
+        (-[DOMNode computedFontSize]):
+        (-[DOMNode nextFocusNode]):
+        (-[DOMNode previousFocusNode]):
+        (-[DOMRange boundingBox]):
+        (-[DOMRange renderedImageForcingBlackText:renderedImageForcingBlackText:]):
+        (-[DOMElement _font]):
+        (-[DOMHTMLLinkElement _mediaQueryMatchesForOrientation:]):
+        (-[DOMHTMLLinkElement _mediaQueryMatches]):
+        * bindings/objc/DOMEvents.h:
+        * bindings/objc/DOMEvents.mm:
+        (kitClass):
+        * bindings/objc/DOMExtensions.h:
+        * bindings/objc/DOMHTML.mm:
+        (-[DOMHTMLElement scrollYOffset]):
+        (-[DOMHTMLElement setScrollXOffset:scrollYOffset:]):
+        (-[DOMHTMLElement setScrollXOffset:scrollYOffset:adjustForIOSCaret:]):
+        (-[DOMHTMLElement absolutePosition::::]):
+        (-[DOMHTMLInputElement _autocapitalizeType]):
+        (-[DOMHTMLTextAreaElement _autocapitalizeType]):
+        (-[DOMHTMLInputElement setValueWithChangeEvent:]):
+        (-[DOMHTMLInputElement setValueAsNumberWithChangeEvent:]):
+        * bindings/objc/DOMInternal.h:
+        * bindings/objc/DOMInternal.mm:
+        (wrapperCacheLock):
+        (getDOMWrapper):
+        (addDOMWrapper):
+        (removeDOMWrapper):
+        * bindings/objc/DOMPrivate.h:
+        * bindings/objc/DOMUIKitExtensions.h: Added.
+        * bindings/objc/DOMUIKitExtensions.mm: Added.
+        * bindings/objc/PublicDOMInterfaces.h:
+        * bindings/scripts/CodeGeneratorJS.pm:
+        (GenerateHeaderContentHeader):
+        (GenerateImplementationContentHeader):
+        (GenerateHeader):
+        (GenerateImplementation):
+        (GenerateCallbackImplementation):
+        * bindings/scripts/CodeGeneratorObjC.pm:
+        (ReadPublicInterfaces):
+        (GetClassName):
+        (IsCoreFoundationType):
+        (GetObjCType):
+        (AddIncludesForType):
+        (GenerateHeader):
+        (GenerateImplementation):
+        (WriteData):
+        * bindings/scripts/IDLAttributes.txt:
+        * bindings/scripts/preprocessor.pm:
+        (applyPreprocessor):
+        * bridge/objc/objc_class.mm:
+        (JSC::Bindings::ObjcClass::fieldNamed):
+        * bridge/objc/objc_instance.mm:
+        * config.h:
+        * dom/Document.cpp:
+        (WebCore::Document::addAutoSizingNode):
+        * dom/Document.h:
+        * dom/Document.idl:
+        * dom/ios/TouchEvents.cpp: Added.
+        * editing/ApplyStyleCommand.cpp:
+        (WebCore::ApplyStyleCommand::applyBlockStyle):
+        * editing/CompositeEditCommand.cpp:
+        (WebCore::EditCommandComposition::unapply):
+        (WebCore::CompositeEditCommand::apply):
+        (WebCore::CompositeEditCommand::inputText):
+        (WebCore::CompositeEditCommand::replaceTextInNodePreservingMarkers):
+        (WebCore::CompositeEditCommand::moveParagraphs):
+        * editing/CompositeEditCommand.h:
+        * editing/DeleteButton.h:
+        * editing/DeleteButtonController.cpp:
+        (WebCore::DeleteButtonController::enable):
+        (WebCore::DeleteButtonController::disable):
+        * editing/DeleteSelectionCommand.cpp:
+        (WebCore::DeleteSelectionCommand::doApply):
+        * editing/DeleteSelectionCommand.h:
+        * editing/EditAction.h:
+        * editing/EditCommand.h:
+        (WebCore::EditCommand::isInsertTextCommand):
+        * editing/EditingStyle.cpp:
+        * editing/Editor.cpp:
+        (WebCore::ClearTextCommand::ClearTextCommand):
+        (WebCore::ClearTextCommand::editingAction):
+        (WebCore::ClearTextCommand::CreateAndApply):
+        (WebCore::Editor::handleTextEvent):
+        (WebCore::Editor::clearText):
+        (WebCore::Editor::insertDictationPhrases):
+        (WebCore::Editor::setDictationPhrasesAsChildOfElement):
+        (WebCore::Editor::confirmMarkedText):
+        (WebCore::Editor::setTextAsChildOfElement):
+        (WebCore::Editor::notifyComponentsOnChangedSelection):
+        (WebCore::Editor::ensureLastEditCommandHasCurrentSelectionIfOpenForMoreTyping):
+        (WebCore::Editor::copy):
+        (WebCore::Editor::setBaseWritingDirection):
+        (WebCore::Editor::setComposition):
+        (WebCore::Editor::showSpellingGuessPanel):
+        (WebCore::Editor::markMisspellingsAfterTypingToWord):
+        (WebCore::Editor::markMisspellingsOrBadGrammar):
+        (WebCore::Editor::changeBackToReplacedString):
+        (WebCore::Editor::updateMarkersForWordsAffectedByEditing):
+        (WebCore::Editor::setIgnoreCompositionSelectionChange):
+        (WebCore::Editor::changeSelectionAfterCommand):
+        (WebCore::Editor::shouldChangeSelection):
+        (WebCore::Editor::respondToChangedSelection):
+        (WebCore::Editor::resolveTextCheckingTypeMask):
+        * editing/Editor.h:
+        * editing/EditorCommand.cpp:
+        (WebCore::executeClearText):
+        (WebCore::enabledCopy):
+        (WebCore::enabledCut):
+        (WebCore::enabledClearText):
+        (WebCore::createCommandMap):
+        * editing/FrameSelection.cpp:
+        (WebCore::FrameSelection::FrameSelection):
+        (WebCore::FrameSelection::setSelection):
+        (WebCore::FrameSelection::modifyExtendingRight):
+        (WebCore::FrameSelection::modifyExtendingForward):
+        (WebCore::FrameSelection::modifyMovingRight):
+        (WebCore::FrameSelection::modifyMovingForward):
+        (WebCore::FrameSelection::modifyExtendingLeft):
+        (WebCore::FrameSelection::modifyExtendingBackward):
+        (WebCore::FrameSelection::modifyMovingLeft):
+        (WebCore::FrameSelection::modifyMovingBackward):
+        (WebCore::FrameSelection::setSelectedRange):
+        (WebCore::FrameSelection::focusedOrActiveStateChanged):
+        (WebCore::FrameSelection::updateAppearance):
+        (WebCore::FrameSelection::shouldDeleteSelection):
+        (WebCore::FrameSelection::revealSelection):
+        (WebCore::FrameSelection::setSelectionFromNone):
+        (WebCore::FrameSelection::shouldChangeSelection):
+        (WebCore::FrameSelection::expandSelectionToElementContainingCaretSelection):
+        (WebCore::FrameSelection::elementRangeContainingCaretSelection):
+        (WebCore::FrameSelection::expandSelectionToWordContainingCaretSelection):
+        (WebCore::FrameSelection::wordRangeContainingCaretSelection):
+        (WebCore::FrameSelection::expandSelectionToStartOfWordContainingCaretSelection):
+        (WebCore::FrameSelection::characterInRelationToCaretSelection):
+        (WebCore::FrameSelection::characterBeforeCaretSelection):
+        (WebCore::FrameSelection::characterAfterCaretSelection):
+        (WebCore::FrameSelection::wordOffsetInRange):
+        (WebCore::FrameSelection::spaceFollowsWordInRange):
+        (WebCore::FrameSelection::selectionAtDocumentStart):
+        (WebCore::FrameSelection::selectionAtSentenceStart):
+        (WebCore::FrameSelection::selectionAtWordStart):
+        (WebCore::FrameSelection::rangeByMovingCurrentSelection):
+        (WebCore::FrameSelection::rangeByExtendingCurrentSelection):
+        (WebCore::FrameSelection::selectRangeOnElement):
+        (WebCore::FrameSelection::wordSelectionContainingCaretSelection):
+        (WebCore::FrameSelection::actualSelectionAtSentenceStart):
+        (WebCore::FrameSelection::rangeByAlteringCurrentSelection):
+        (WebCore::FrameSelection::clearCurrentSelection):
+        (WebCore::FrameSelection::setCaretBlinks):
+        (WebCore::FrameSelection::setCaretColor):
+        * editing/FrameSelection.h:
+        (WebCore::FrameSelection::suppressCloseTyping):
+        (WebCore::FrameSelection::restoreCloseTyping):
+        (WebCore::FrameSelection::setUpdateAppearanceEnabled):
+        (WebCore::FrameSelection::suppressScrolling):
+        (WebCore::FrameSelection::restoreScrolling):
+        * editing/InsertIntoTextNodeCommand.cpp:
+        (WebCore::InsertIntoTextNodeCommand::doReapply):
+        * editing/InsertIntoTextNodeCommand.h:
+        * editing/InsertTextCommand.h:
+        * editing/ReplaceSelectionCommand.cpp:
+        (WebCore::ReplaceSelectionCommand::doApply):
+        * editing/TextAffinity.h:
+        * editing/TextCheckingHelper.cpp:
+        * editing/TextGranularity.h:
+        * editing/TextIterator.cpp:
+        (WebCore::isRendererReplacedElement):
+        * editing/TypingCommand.cpp:
+        (WebCore::TypingCommand::ensureLastEditCommandHasCurrentSelectionIfOpenForMoreTyping):
+        (WebCore::TypingCommand::markMisspellingsAfterTyping):
+        (WebCore::TypingCommand::deleteKeyPressed):
+        (WebCore::TypingCommand::forwardDeleteKeyPressed):
+        (WebCore::FriendlyEditCommand::setEndingSelection):
+        (WebCore::TypingCommand::setEndingSelectionOnLastInsertCommand):
+        * editing/TypingCommand.h:
+        * editing/VisiblePosition.h:
+        (WebCore::operator<):
+        (WebCore::operator>):
+        (WebCore::operator<=):
+        (WebCore::operator>=):
+        * editing/VisibleSelection.cpp:
+        (WebCore::VisibleSelection::setStartAndEndFromBaseAndExtentRespectingGranularity):
+        (WebCore::VisibleSelection::adjustSelectionToAvoidCrossingEditingBoundaries):
+        * editing/VisibleUnits.cpp:
+        (WebCore::previousBoundary):
+        (WebCore::nextBoundary):
+        (WebCore::startOfDocument):
+        (WebCore::endOfDocument):
+        (WebCore::directionIsDownstream):
+        (WebCore::atBoundaryOfGranularity):
+        (WebCore::withinTextUnitOfGranularity):
+        (WebCore::nextCharacterBoundaryInDirection):
+        (WebCore::nextWordBoundaryInDirection):
+        (WebCore::nextSentenceBoundaryInDirection):
+        (WebCore::nextLineBoundaryInDirection):
+        (WebCore::nextParagraphBoundaryInDirection):
+        (WebCore::nextDocumentBoundaryInDirection):
+        (WebCore::positionOfNextBoundaryOfGranularity):
+        (WebCore::enclosingTextUnitOfGranularity):
+        (WebCore::distanceBetweenPositions):
+        (WebCore::wordRangeFromPosition):
+        (WebCore::closestWordBoundaryForPosition):
+        * editing/VisibleUnits.h:
+        * editing/ios/DictationCommandIOS.cpp: Added.
+        * editing/ios/DictationCommandIOS.h: Added.
+        (WebCore::DictationCommandIOS::create):
+        (WebCore::DictationCommandIOS::editingAction):
+        * editing/mac/FrameSelectionMac.mm:
+        (WebCore::FrameSelection::notifyAccessibilityForSelectionChange):
+        * fileapi/AsyncFileStream.cpp:
+        * generate-export-file: Added.
+        * inspector/InspectorCounters.h:
+        * inspector/InspectorFrontendHost.h:
+        * make-export-file-generator:
+        * plugins/PluginPackage.h:
+        * plugins/PluginViewBase.h:
+        (WebCore::PluginViewBase::willProvidePluginLayer):
+        (WebCore::PluginViewBase::attachPluginLayer):
+        (WebCore::PluginViewBase::detachPluginLayer):
+        * style/StyleResolveForDocument.cpp:
+        (WebCore::Style::resolveForDocument):
+        * style/StyleResolveTree.cpp:
+        (WebCore::Style::elementImplicitVisibility):
+        * testing/Internals.cpp:
+        (WebCore::Internals::getCurrentCursorInfo):
+        (WebCore::Internals::isSelectPopupVisible):
+        * workers/WorkerThread.cpp:
+        (WebCore::WorkerThread::workerThread):
+
+2014-01-10  Daniel Bates  <dabates@apple.com>
+
         Fix the iOS build after <http://trac.webkit.org/changeset/161589>
         (https://bugs.webkit.org/show_bug.cgi?id=126654)
 
index fd4f60b..0221151 100644 (file)
@@ -21,6 +21,8 @@
 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
 
+#include "iOS.xcconfig"
+
 CLANG_CXX_LANGUAGE_STANDARD = gnu++0x;
 CLANG_CXX_LIBRARY = libc++;
 CLANG_WARN_BOOL_CONVERSION = YES;
@@ -56,6 +58,7 @@ GCC_WARN_64_TO_32_BIT_CONVERSION = $(GCC_WARN_64_TO_32_BIT_CONVERSION_$(CURRENT_
 GCC_WARN_64_TO_32_BIT_CONVERSION_ = YES;
 GCC_WARN_64_TO_32_BIT_CONVERSION_armv7 = YES;
 GCC_WARN_64_TO_32_BIT_CONVERSION_armv7s = YES;
+GCC_WARN_64_TO_32_BIT_CONVERSION_arm64 = NO;
 GCC_WARN_64_TO_32_BIT_CONVERSION_i386 = YES;
 GCC_WARN_64_TO_32_BIT_CONVERSION_x86_64 = NO;
 GCC_WARN_ABOUT_DEPRECATED_FUNCTIONS = NO;
@@ -82,7 +85,10 @@ DEBUG_DEFINES_normal = NDEBUG;
 DEBUG_DEFINES = $(DEBUG_DEFINES_$(CURRENT_VARIANT));
 
 GCC_OPTIMIZATION_LEVEL = $(GCC_OPTIMIZATION_LEVEL_$(CURRENT_VARIANT));
-GCC_OPTIMIZATION_LEVEL_normal = 2;
+GCC_OPTIMIZATION_LEVEL_normal = $(GCC_OPTIMIZATION_LEVEL_normal_$(PLATFORM_NAME));
+GCC_OPTIMIZATION_LEVEL_normal_iphoneos = 3;
+GCC_OPTIMIZATION_LEVEL_normal_iphonesimulator = 3;
+GCC_OPTIMIZATION_LEVEL_normal_macosx = 2;
 GCC_OPTIMIZATION_LEVEL_debug = 0;
 
 STRIP_INSTALLED_PRODUCT = $(STRIP_INSTALLED_PRODUCT_$(CURRENT_VARIANT));
@@ -93,7 +99,9 @@ DEAD_CODE_STRIPPING_debug = NO;
 DEAD_CODE_STRIPPING_normal = YES;
 DEAD_CODE_STRIPPING = $(DEAD_CODE_STRIPPING_$(CURRENT_VARIANT));
 
-SECTORDER_FLAGS = -Wl,-order_file,WebCore.order;
+SECTORDER_FLAGS = $(SECTORDER_FLAGS_$(PLATFORM_NAME));
+SECTORDER_FLAGS_iphoneos = -Wl,-order_file,$(SDKROOT)/AppleInternal/OrderFiles/WebCore.order;
+SECTORDER_FLAGS_macosx = -Wl,-order_file,WebCore.order;
 
 WEBCORE_SQLITE3_HEADER_SEARCH_PATHS = $(NEXT_ROOT)/usr/local/include/WebCoreSQLite3;
 SQLITE3_HEADER_SEARCH_PATHS = $(SQLITE3_HEADER_SEARCH_PATHS_$(PLATFORM_NAME));
index e1b8e30..d3e7910 100644 (file)
@@ -33,8 +33,9 @@ EXPORTED_SYMBOLS_FILE_arm64 = $(BUILT_PRODUCTS_DIR)/DerivedSources/WebCore/WebCo
 EXPORTED_SYMBOLS_FILE_i386 = $(EXPORTED_SYMBOLS_FILE_i386_$(PLATFORM_NAME));
 EXPORTED_SYMBOLS_FILE_i386_iphonesimulator = $(BUILT_PRODUCTS_DIR)/DerivedSources/WebCore/WebCore.LP64.i386.exp;
 EXPORTED_SYMBOLS_FILE_i386_macosx = $(BUILT_PRODUCTS_DIR)/DerivedSources/WebCore/WebCore.exp;
-EXPORTED_SYMBOLS_FILE_ppc = $(BUILT_PRODUCTS_DIR)/DerivedSources/WebCore/WebCore.exp;
-EXPORTED_SYMBOLS_FILE_x86_64 = $(BUILT_PRODUCTS_DIR)/DerivedSources/WebCore/WebCore.LP64.exp;
+EXPORTED_SYMBOLS_FILE_x86_64 = $(EXPORTED_SYMBOLS_FILE_x86_64_$(PLATFORM_NAME));
+EXPORTED_SYMBOLS_FILE_x86_64_iphonesimulator = $(BUILT_PRODUCTS_DIR)/DerivedSources/WebCore/WebCore.LP64.x86_64.exp;
+EXPORTED_SYMBOLS_FILE_x86_64_macosx = $(BUILT_PRODUCTS_DIR)/DerivedSources/WebCore/WebCore.LP64.exp;
 GCC_PREFIX_HEADER = WebCorePrefix.h;
 GCC_PREPROCESSOR_DEFINITIONS = $(DEBUG_DEFINES) $(FEATURE_DEFINES) WEBKIT_VERSION_MIN_REQUIRED=WEBKIT_VERSION_LATEST $(GCC_PREPROCESSOR_DEFINITIONS);
 FRAMEWORK_SEARCH_PATHS = $(FRAMEWORK_SEARCH_PATHS_$(PLATFORM_NAME));
@@ -51,7 +52,9 @@ OTHER_CPLUSPLUSFLAGS = $(OTHER_CFLAGS);
 STAGED_FRAMEWORKS_SEARCH_PATH = $(STAGED_FRAMEWORKS_SEARCH_PATH_$(USE_STAGING_INSTALL_PATH));
 STAGED_FRAMEWORKS_SEARCH_PATH_YES = $(NEXT_ROOT)$(SYSTEM_LIBRARY_DIR)/StagedFrameworks/Safari;
 
-HEADER_SEARCH_PATHS = ForwardingHeaders icu /usr/include/libxslt /usr/include/libxml2 "${BUILT_PRODUCTS_DIR}/DerivedSources/WebCore" "${BUILT_PRODUCTS_DIR}/usr/local/include" $(HEADER_SEARCH_PATHS);
+WEBKITADDITIONS_HEADER_SEARCH_PATHS = $(BUILT_PRODUCTS_DIR)/usr/local/include/WebKitAdditions $(SDKROOT)/usr/local/include/WebKitAdditions;
+
+HEADER_SEARCH_PATHS = ForwardingHeaders icu /usr/include/libxslt /usr/include/libxml2 $(SQLITE3_HEADER_SEARCH_PATHS) "${BUILT_PRODUCTS_DIR}/DerivedSources/WebCore" "$(BUILT_PRODUCTS_DIR)/usr/local/include" $(WEBKITADDITIONS_HEADER_SEARCH_PATHS) $(HEADER_SEARCH_PATHS);
 INFOPLIST_FILE = Info.plist;
 INSTALL_PATH = $(INSTALL_PATH_$(PLATFORM_NAME));
 INSTALL_PATH_iphoneos = $(SYSTEM_LIBRARY_DIR)/PrivateFrameworks;
@@ -68,8 +71,8 @@ INSTALLHDRS_SCRIPT_PHASE = YES;
 PRODUCT_NAME = WebCore;
 OTHER_LDFLAGS_BASE = -lsqlite3 -lobjc -lANGLE -allowable_client WebCoreTestSupport;
 OTHER_LDFLAGS = $(inherited) $(OTHER_LDFLAGS_$(PLATFORM_NAME));
-OTHER_LDFLAGS_iphoneos = $(OTHER_LDFLAGS_BASE) -framework CFNetwork -framework CoreFoundation -framework CoreGraphics -framework CoreText -framework Foundation -framework GraphicsServices -framework ImageIO -framework QuartzCore;
-OTHER_LDFLAGS_iphonesimulator = $(OTHER_LDFLAGS_iphoneos);
+OTHER_LDFLAGS_iphoneos = $(OTHER_LDFLAGS_iphonesimulator) -framework IOSurface;
+OTHER_LDFLAGS_iphonesimulator = $(OTHER_LDFLAGS_BASE) -framework Accelerate -framework CFNetwork -framework CoreFoundation -framework CoreGraphics -framework CoreText -framework Foundation -framework GraphicsServices -framework ImageIO -framework OpenGLES -framework QuartzCore -lMobileGestalt;
 OTHER_LDFLAGS_macosx = $(OTHER_LDFLAGS_BASE) -sub_library libobjc -umbrella WebKit -allowable_client WebKit2 -framework IOSurface;
 
 NORMAL_WEBCORE_FRAMEWORKS_DIR = $(NORMAL_WEBCORE_FRAMEWORKS_DIR_$(PLATFORM_NAME));
@@ -102,10 +105,13 @@ PRODUCTION_FRAMEWORKS_DIR_macosx_USE_STAGING_INSTALL_PATH_YES = $(NEXT_ROOT)$(SY
 JAVASCRIPTCORE_PRIVATE_HEADERS_DIR = $(JAVASCRIPTCORE_PRIVATE_HEADERS_DIR_$(CONFIGURATION));
 JAVASCRIPTCORE_PRIVATE_HEADERS_DIR_Release = $(JAVASCRIPTCORE_PRIVATE_HEADERS_engineering);
 JAVASCRIPTCORE_PRIVATE_HEADERS_DIR_Debug = $(JAVASCRIPTCORE_PRIVATE_HEADERS_engineering);
-JAVASCRIPTCORE_PRIVATE_HEADERS_DIR_Production = $(SDKROOT)$(PRODUCTION_FRAMEWORKS_DIR)/JavaScriptCore.framework/PrivateHeaders;
+JAVASCRIPTCORE_PRIVATE_HEADERS_DIR_Production = $(JAVASCRIPTCORE_PRIVATE_HEADERS_Production_$(PLATFORM_NAME));
+JAVASCRIPTCORE_PRIVATE_HEADERS_DIR_Production_iphoneos = $(SDKROOT)/$(SYSTEM_LIBRARY_DIR)/Frameworks/JavaScriptCore.framework/Headers;
+JAVASCRIPTCORE_PRIVATE_HEADERS_DIR_Production_iphonesimulator = $(JAVASCRIPTCORE_PRIVATE_HEADERS_DIR_Production_iphoneos);
+JAVASCRIPTCORE_PRIVATE_HEADERS_DIR_Production_macosx = $(SDKROOT)$(PRODUCTION_FRAMEWORKS_DIR)/JavaScriptCore.framework/PrivateHeaders;
 JAVASCRIPTCORE_PRIVATE_HEADERS_engineering = $(BUILT_PRODUCTS_DIR)/JavaScriptCore.framework/PrivateHeaders;
 
 EXCLUDED_SOURCE_FILE_NAMES = $(EXCLUDED_SOURCE_FILE_NAMES_$(PLATFORM_NAME));
-EXCLUDED_SOURCE_FILE_NAMES_iphoneos = *.tiff *Cursor.png Cursor.cpp CursorMac.mm EventHandlerMac.mm HTMLConverter.mm KillRingMac.mm PlatformEventFactoryMac.mm SSLKeyGeneratorMac.cpp SearchPopupMenuMac.mm ScrollingCoordinatorMac.mm ScrollingStateScrollingNodeMac.mm ScrollingTreeScrollingNodeMac.mm SharedTimerMac.mm WebVideoFullscreenController.mm WebVideoFullscreenHUDWindowController.mm WebWindowAnimation.mm;
+EXCLUDED_SOURCE_FILE_NAMES_iphoneos = *.tiff *Cursor.png AccessibilityObjectMac.mm AXObjectCacheMac.mm ClipboardMac.mm ColorMac.mm Cursor.cpp CursorMac.mm EditorMac.mm EventHandlerMac.mm EventLoopMac.mm GeolocationServiceMac.mm GraphicsContext3DOpenGLES.cpp IconDatabase.cpp IconMac.mm KeyEventMac.mm KillRingMac.mm LocalCurrentGraphicsContext.mm MIMETypeRegistryMac.mm MediaPlayerPrivateQTKit.mm NSScrollerImpDetails.mm NetworkStateNotifierMac.cpp PasteboardMac.mm PlatformEventFactoryMac.mm PlatformMouseEventMac.mm PlatformPasteboardMac.mm PlatformScreenMac.mm PlatformSpeechSynthesizerMac.mm PluginMainThreadScheduler.cpp RunLoopMac.mm SSLKeyGeneratorMac.cpp ScrollingCoordinatorMac.mm ScrollingStateScrollingNodeMac.mm ScrollingTreeScrollingNodeMac.mm ScrollViewMac.mm ScrollbarThemeMac.mm SharedTimerMac.mm SoundMac.mm SystemTimeMac.cpp ThemeMac.mm ThreadCheck.mm WebAccessibilityObjectWrapperMac.mm WebCoreSystemInterface.mm WebCoreURLResponse.mm WebCoreView.m WebFontCache.mm WebVideoFullscreenController.mm WebVideoFullscreenHUDWindowController.mm WebWindowAnimation.mm WheelEventMac.mm WidgetMac.mm mac/LayerPool.mm DisplayRefreshMonitorMac.mm;
 EXCLUDED_SOURCE_FILE_NAMES_iphonesimulator = $(EXCLUDED_SOURCE_FILE_NAMES_iphoneos);
 EXCLUDED_SOURCE_FILE_NAMES_macosx = *IOS.h *IOS.cpp *IOS.mm KillRingNone.cpp WAKAppKitStubs.h WAKClipView.h WAKResponder.h WAKScrollView.h WAKView.h WAKViewPrivate.h WAKWindow.h WKContentObservation.h WKGraphics.h WKTypes.h WKUtilities.h WKView.h WKViewPrivate.h WebCoreThread.h WebCoreThreadMessage.h WebCoreThreadRun.h WebCoreThreadSystemInterface.h;
index 84be763..6ce80bb 100644 (file)
 PRIVATE_HEADERS_FOLDER_PATH = $(PRIVATE_HEADERS_FOLDER_PATH_$(CONFIGURATION));
 PRIVATE_HEADERS_FOLDER_PATH_Debug = WebCoreTestSupport;
 PRIVATE_HEADERS_FOLDER_PATH_Release = $(PRIVATE_HEADERS_FOLDER_PATH_Debug);
-PRIVATE_HEADERS_FOLDER_PATH_Production = /usr/local/include/WebCoreTestSupport;
+PRIVATE_HEADERS_FOLDER_PATH_Production = $(PRIVATE_HEADERS_FOLDER_PATH_Production_$(PLATFORM_NAME));
+PRIVATE_HEADERS_FOLDER_PATH_Production_iphoneos = /usr/local/include/WebCoreTestSupport;
+PRIVATE_HEADERS_FOLDER_PATH_Production_iphonesimulator = $(INDIGO_INSTALL_PATH_PREFIX)$(PRIVATE_HEADERS_FOLDER_PATH_Production_iphoneos);
+PRIVATE_HEADERS_FOLDER_PATH_Production_macosx = /usr/local/include/WebCoreTestSupport;
 
-INSTALL_PATH = $(INSTALL_PATH_$(CONFIGURATION));
-INSTALL_PATH_Production = /usr/local/lib;
+INSTALL_PATH = $(INSTALL_PATH_$(CONFIGURATION)_$(PLATFORM_NAME));
+INSTALL_PATH_Production_iphoneos = /usr/local/lib;
+INSTALL_PATH_Production_iphonesimulator = $(INDIGO_INSTALL_PATH_PREFIX)$(INSTALL_PATH_Production_iphoneos);
+INSTALL_PATH_Production_macosx = /usr/local/lib;
 
 SKIP_INSTALL = $(SKIP_INSTALL_$(FORCE_TOOL_INSTALL));
 SKIP_INSTALL_ = YES;
diff --git a/Source/WebCore/Configurations/iOS.xcconfig b/Source/WebCore/Configurations/iOS.xcconfig
new file mode 100644 (file)
index 0000000..177b319
--- /dev/null
@@ -0,0 +1 @@
+#include "<DEVELOPER_DIR>/AppleInternal/XcodeConfig/AspenFamily.xcconfig"
index 9334daa..eca56b5 100644 (file)
@@ -28,6 +28,7 @@
 
 VPATH = \
     $(WebCore) \
+    $(WebCore)/Modules/airplay \
     $(WebCore)/Modules/encryptedmedia \
     $(WebCore)/Modules/geolocation \
     $(WebCore)/Modules/indexeddb \
@@ -67,6 +68,7 @@ VPATH = \
 #
 
 BINDING_IDLS = \
+    $(WebCore)/Modules/airplay/WebKitPlaybackTargetAvailabilityEvent.idl \
     $(WebCore)/Modules/encryptedmedia/MediaKeyMessageEvent.idl \
     $(WebCore)/Modules/encryptedmedia/MediaKeyNeededEvent.idl \
     $(WebCore)/Modules/encryptedmedia/MediaKeySession.idl \
@@ -304,9 +306,6 @@ BINDING_IDLS = \
     $(WebCore)/dom/StringCallback.idl \
     $(WebCore)/dom/Text.idl \
     $(WebCore)/dom/TextEvent.idl \
-    $(WebCore)/dom/Touch.idl \
-    $(WebCore)/dom/TouchEvent.idl \
-    $(WebCore)/dom/TouchList.idl \
     $(WebCore)/dom/TransitionEvent.idl \
     $(WebCore)/dom/TreeWalker.idl \
     $(WebCore)/dom/UIEvent.idl \
@@ -719,6 +718,12 @@ ifneq ($(SDKROOT),)
        SDK_FLAGS=-isysroot $(SDKROOT)
 endif
 
+ifeq ($(shell $(CC) -isysroot $(SDKROOT) -std=gnu++11 -x c++ -E -P -dM -F $(BUILT_PRODUCTS_DIR) $(FRAMEWORK_FLAGS) $(HEADER_FLAGS) -include "wtf/Platform.h" /dev/null | grep ' WTF_PLATFORM_IOS ' | cut -d' ' -f3), 1)
+    WTF_PLATFORM_IOS = 1
+else
+    WTF_PLATFORM_IOS = 0
+endif
+
 ifeq ($(shell $(CC) -std=gnu++11 -x c++ -E -P -dM $(SDK_FLAGS) $(FRAMEWORK_FLAGS) $(HEADER_FLAGS) -include "wtf/Platform.h" /dev/null | grep ENABLE_ORIENTATION_EVENTS | cut -d' ' -f3), 1)
     ENABLE_ORIENTATION_EVENTS = 1
 endif
@@ -727,6 +732,32 @@ ifeq ($(PLATFORM_FEATURE_DEFINES),)
 PLATFORM_FEATURE_DEFINES = Configurations/FeatureDefines.xcconfig
 endif
 
+ifeq ($(WTF_PLATFORM_IOS), 1)
+
+ADDITIONAL_BINDING_IDLS = \
+    GestureEvent.idl \
+    Touch.idl \
+    TouchEvent.idl \
+    TouchList.idl
+
+BINDING_IDLS += $(ADDITIONAL_BINDING_IDLS)
+
+all : $(ADDITIONAL_BINDING_IDLS:%.idl=JS%.h)
+
+vpath %.idl $(BUILT_PRODUCTS_DIR)/usr/local/include $(SDKROOT)/usr/local/include
+
+$(ADDITIONAL_BINDING_IDLS) : % : WebKitAdditions/%
+    cp $< .
+
+else
+
+BINDING_IDLS += \
+    $(WebCore)/dom/Touch.idl \
+    $(WebCore)/dom/TouchEvent.idl \
+    $(WebCore)/dom/TouchList.idl
+
+endif
+
 endif # MACOS
 
 ifndef ENABLE_ORIENTATION_EVENTS
@@ -1156,15 +1187,52 @@ CharsetData.cpp : platform/text/mac/make-charset-table.pl platform/text/mac/char
 
 ifneq ($(ACTION),installhdrs)
 
+ifeq ($(WTF_PLATFORM_IOS),1)
+
+ifeq ($(findstring armv6,$(ARCHS)), armv6)
+    WEBCORE_EXPORT_FILES := $(WEBCORE_EXPORT_FILES) WebCore.LP64.armv6.exp
+endif
+ifeq ($(findstring armv7f,$(ARCHS)), armv7f)
+    WEBCORE_EXPORT_FILES := $(WEBCORE_EXPORT_FILES) WebCore.LP64.armv7f.exp
+endif
+ifeq ($(findstring armv7s,$(ARCHS)), armv7s)
+    WEBCORE_EXPORT_FILES := $(WEBCORE_EXPORT_FILES) WebCore.LP64.armv7s.exp
+endif
+ifeq ($(findstring armv7,$(ARCHS)), armv7)
+    WEBCORE_EXPORT_FILES := $(WEBCORE_EXPORT_FILES) WebCore.LP64.armv7.exp
+endif
+ifeq ($(findstring arm64,$(ARCHS)), arm64)
+    WEBCORE_EXPORT_FILES := $(WEBCORE_EXPORT_FILES) WebCore.LP64.arm64.exp
+endif
+ifeq ($(findstring i386,$(ARCHS)), i386)
+    WEBCORE_EXPORT_FILES := $(WEBCORE_EXPORT_FILES) WebCore.LP64.i386.exp
+endif
+ifeq ($(findstring x86_64,$(ARCHS)), x86_64)
+    WEBCORE_EXPORT_FILES := $(WEBCORE_EXPORT_FILES) WebCore.LP64.x86_64.exp
+endif
+
+all : $(WEBCORE_EXPORT_FILES)
+
+WebCore.%.exp : generate-export-file WebCore.exp.in
+    $^ $@
+
+# Switch NSRect, NSSize and NSPoint with their CG counterparts for the 64-bit exports file.
+WebCore.LP64.%.exp : WebCore.%.exp
+    cat $^ | sed -e s/7_NSRect/6CGRect/ -e s/7_NSSize/6CGSize/ -e s/8_NSPoint/7CGPoint/ > $@
+
+else
+
 all : WebCore.exp WebCore.LP64.exp
 
 WebCore.exp : $(BUILT_PRODUCTS_DIR)/WebCoreExportFileGenerator
-       $^ > $@
+    $^ | grep -v '^# ' | sed -e 's/^#//' > $@
 
 # Switch NSRect, NSSize and NSPoint with their CG counterparts for the 64-bit exports file.
 WebCore.LP64.exp : WebCore.exp
        cat $^ | sed -e s/7_NSRect/6CGRect/ -e s/7_NSSize/6CGSize/ -e s/8_NSPoint/7CGPoint/ > $@
 
+endif # WTF_PLATFORM_IOS
+
 endif # installhdrs
 
 # --------
index c37f788..500c941 100644 (file)
 /* title for a multiple file chooser button used in HTML forms. This title should be as short as possible. */
 "Choose Files" = "Choose Files";
 
+/* PLATFORM(IOS) title for file button used in HTML forms for media files */
+"Choose Media (Single)" = "Choose Photo";
+
+/* PLATFORM(IOS) title for file button used in HTML5 forms for multiple media files */
+"Choose Media (Multiple)" = "Choose Photos";
+
 /* menu item in Recent Searches menu that empties menu's contents */
 "Clear Recent Searches" = "Clear Recent Searches";
 
 /* Default writing direction context menu item */
 "Default" = "Default";
 
+/* PLATFORM(IOS) Undo action name */
+"Delete (Undo action name)" = "Delete";
+
+/* PLATFORM(IOS) Undo action name */
+"Dictation (Undo action name)" = "Dictation";
+
 /* text to display in <details> tag when it has no <summary> child */
 "Details" = "Details";
 
 /* text to display in file button used in HTML forms when no files are selected and the button allows multiple files to be selected */
 "no files selected" = "no files selected";
 
+/* PLATFORM(IOS) text to display in file button used in HTML forms for media files when no media file is selected */
+"no media selected (single)" = "no photo selected";
+
+/* PLATFORM(IOS) text to display in file button used in HTML forms for media files when no media files are selected and the button allows multiple files to be selected */
+"no media selected (multiple)" = "no photos selected";
+
 /* HTTP result code string */
 "no longer exists" = "no longer exists";
 
diff --git a/Source/WebCore/Modules/airplay/WebKitPlaybackTargetAvailabilityEvent.cpp b/Source/WebCore/Modules/airplay/WebKitPlaybackTargetAvailabilityEvent.cpp
new file mode 100644 (file)
index 0000000..f755860
--- /dev/null
@@ -0,0 +1,59 @@
+/*
+ * Copyright (C) 2013 Apple Inc. All rights reserved.
+ *
+ * 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.
+ */
+
+#include "config.h"
+#include "WebKitPlaybackTargetAvailabilityEvent.h"
+
+#if ENABLE(IOS_AIRPLAY)
+
+namespace WebCore {
+
+static const AtomicString& stringForPlaybackTargetAvailability(bool available)
+{
+    DEFINE_STATIC_LOCAL(AtomicString, availableString, ("available", AtomicString::ConstructFromLiteral));
+    DEFINE_STATIC_LOCAL(AtomicString, notAvailableString, ("not-available", AtomicString::ConstructFromLiteral));
+
+    return available ? availableString : notAvailableString;
+}
+
+WebKitPlaybackTargetAvailabilityEvent::WebKitPlaybackTargetAvailabilityEvent()
+{
+}
+
+WebKitPlaybackTargetAvailabilityEvent::WebKitPlaybackTargetAvailabilityEvent(const AtomicString& eventType, bool available)
+    : Event(eventType, false, false)
+    , m_availability(stringForPlaybackTargetAvailability(available))
+{
+}
+
+WebKitPlaybackTargetAvailabilityEvent::WebKitPlaybackTargetAvailabilityEvent(const AtomicString& eventType, const WebKitPlaybackTargetAvailabilityEventInit& initializer)
+    : Event(eventType, initializer)
+    , m_availability(initializer.availability)
+{
+}
+
+} // namespace WebCore
+
+#endif // ENABLE(IOS_AIRPLAY)
diff --git a/Source/WebCore/Modules/airplay/WebKitPlaybackTargetAvailabilityEvent.h b/Source/WebCore/Modules/airplay/WebKitPlaybackTargetAvailabilityEvent.h
new file mode 100644 (file)
index 0000000..dbbfde7
--- /dev/null
@@ -0,0 +1,79 @@
+/*
+ * Copyright (C) 2013 Apple Inc. All rights reserved.
+ *
+ * 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.
+ */
+
+#ifndef WebKitPlaybackTargetAvailabilityEvent_h
+#define WebKitPlaybackTargetAvailabilityEvent_h
+
+#if ENABLE(IOS_AIRPLAY)
+
+#include "Event.h"
+#include "EventNames.h"
+
+namespace WebCore {
+
+struct WebKitPlaybackTargetAvailabilityEventInit : public EventInit {
+    WebKitPlaybackTargetAvailabilityEventInit()
+    {
+    };
+
+    String availability;
+};
+
+class WebKitPlaybackTargetAvailabilityEvent : public Event {
+public:
+    ~WebKitPlaybackTargetAvailabilityEvent() { }
+
+    static PassRefPtr<WebKitPlaybackTargetAvailabilityEvent> create()
+    {
+        return adoptRef(new WebKitPlaybackTargetAvailabilityEvent);
+    }
+
+    static PassRefPtr<WebKitPlaybackTargetAvailabilityEvent> create(const AtomicString& eventType, bool available)
+    {
+        return adoptRef(new WebKitPlaybackTargetAvailabilityEvent(eventType, available));
+    }
+
+    static PassRefPtr<WebKitPlaybackTargetAvailabilityEvent> create(const AtomicString& eventType, const WebKitPlaybackTargetAvailabilityEventInit& initializer)
+    {
+        return adoptRef(new WebKitPlaybackTargetAvailabilityEvent(eventType, initializer));
+    }
+
+    String availability() const { return m_availability; }
+
+    virtual EventInterface eventInterface() const OVERRIDE { return WebKitPlaybackTargetAvailabilityEventInterfaceType; }
+
+private:
+    WebKitPlaybackTargetAvailabilityEvent();
+    explicit WebKitPlaybackTargetAvailabilityEvent(const AtomicString& eventType, bool available);
+    WebKitPlaybackTargetAvailabilityEvent(const AtomicString& eventType, const WebKitPlaybackTargetAvailabilityEventInit&);
+
+    String m_availability;
+};
+
+} // namespace WebCore
+
+#endif // ENABLE(IOS_AIRPLAY)
+
+#endif // WebKitPlaybackTargetAvailabilityEvent_h
diff --git a/Source/WebCore/Modules/airplay/WebKitPlaybackTargetAvailabilityEvent.idl b/Source/WebCore/Modules/airplay/WebKitPlaybackTargetAvailabilityEvent.idl
new file mode 100644 (file)
index 0000000..00e3bfe
--- /dev/null
@@ -0,0 +1,33 @@
+/*
+ * Copyright (C) 2013 Apple Inc. All Rights Reserved.
+ *
+ * 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, 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. 
+ *
+ */
+
+[
+    Conditional=IOS_AIRPLAY,
+    ConstructorTemplate=Event
+] interface WebKitPlaybackTargetAvailabilityEvent : Event {
+    [InitializedByEventConstructor] readonly attribute DOMString availability;
+};
+
index 0735996..04712c1 100644 (file)
@@ -235,6 +235,11 @@ PassRefPtr<Geolocation> Geolocation::create(ScriptExecutionContext* context)
 Geolocation::Geolocation(ScriptExecutionContext* context)
     : ActiveDOMObject(context)
     , m_allowGeolocation(Unknown)
+#if PLATFORM(IOS)
+    , m_isSuspended(false)
+    , m_hasChangedPosition(false)
+    , m_resumeTimer(this, &Geolocation::resumeTimerFired)
+#endif
 {
 }
 
@@ -258,6 +263,123 @@ Page* Geolocation::page() const
     return document() ? document()->page() : 0;
 }
 
+#if PLATFORM(IOS)
+bool Geolocation::canSuspend() const
+{
+    return !hasListeners();
+}
+
+void Geolocation::suspend(ReasonForSuspension reason)
+{
+    // Allow pages that no longer have listeners to enter the page cache.
+    // Have them stop updating and reset geolocation permissions when the page is resumed.
+    if (reason == ActiveDOMObject::DocumentWillBecomeInactive) {
+        ASSERT(!hasListeners());
+        stop();
+        m_resetOnResume = true;
+    }
+
+    // Suspend GeoNotifier timeout timers.
+    if (hasListeners())
+        stopTimers();
+
+    m_isSuspended = true;
+    m_resumeTimer.stop();
+    ActiveDOMObject::suspend(reason);
+}
+
+void Geolocation::resume()
+{
+    ASSERT(WebThreadIsLockedOrDisabled());
+    ActiveDOMObject::resume();
+
+    if (!m_resumeTimer.isActive())
+        m_resumeTimer.startOneShot(0);
+}
+
+void Geolocation::resumeTimerFired(Timer<Geolocation>*)
+{
+    m_isSuspended = false;
+
+    if (m_resetOnResume) {
+        resetAllGeolocationPermission();
+        m_resetOnResume = false;
+    }
+
+    // Resume GeoNotifier timeout timers.
+    if (hasListeners()) {
+        GeoNotifierSet::const_iterator end = m_oneShots.end();
+        for (GeoNotifierSet::const_iterator it = m_oneShots.begin(); it != end; ++it)
+            (*it)->startTimerIfNeeded();
+        GeoNotifierVector watcherCopy;
+        m_watchers.getNotifiersVector(watcherCopy);
+        for (size_t i = 0; i < watcherCopy.size(); ++i)
+            watcherCopy[i]->startTimerIfNeeded();
+    }
+
+    if ((isAllowed() || isDenied()) && !m_pendingForPermissionNotifiers.isEmpty()) {
+        // The pending permission was granted while the object was suspended.
+        setIsAllowed(isAllowed());
+        ASSERT(!m_hasChangedPosition);
+        ASSERT(!m_errorWaitingForResume);
+        return;
+    }
+
+    if (isDenied() && hasListeners()) {
+        // The permission was revoked while the object was suspended.
+        setIsAllowed(false);
+        return;
+    }
+
+    if (m_hasChangedPosition) {
+        positionChanged();
+        m_hasChangedPosition = false;
+    }
+
+    if (m_errorWaitingForResume) {
+        handleError(m_errorWaitingForResume.get());
+        m_errorWaitingForResume = nullptr;
+    }
+}
+
+void Geolocation::resetAllGeolocationPermission()
+{
+    if (m_isSuspended) {
+        m_resetOnResume = true;
+        return;
+    }
+
+    if (m_allowGeolocation == InProgress) {
+        Page* page = this->page();
+        if (page)
+            GeolocationController::from(page)->cancelPermissionRequest(this);
+
+        // This return is not technically correct as GeolocationController::cancelPermissionRequest() should have cleared the active request.
+        // Neither iOS nor OS X supports cancelPermissionRequest() (https://bugs.webkit.org/show_bug.cgi?id=89524), so we workaround that and let ongoing requests complete. :(
+        return;
+    }
+
+    // 1) Reset our own state.
+    stopUpdating();
+    m_allowGeolocation = Unknown;
+    m_hasChangedPosition = false;
+    m_errorWaitingForResume = nullptr;
+
+    // 2) Request new permission for the active notifiers.
+    stopTimers();
+
+    // Go over the one shot and re-request permission.
+    GeoNotifierSet::iterator end = m_oneShots.end();
+    for (GeoNotifierSet::iterator it = m_oneShots.begin(); it != end; ++it)
+        startRequest((*it).get());
+    // Go over the watchers and re-request permission.
+    GeoNotifierVector watcherCopy;
+    m_watchers.getNotifiersVector(watcherCopy);
+    for (size_t i = 0; i < watcherCopy.size(); ++i)
+        startRequest(watcherCopy[i].get());
+}
+#endif // PLATFORM(IOS)
+
 void Geolocation::stop()
 {
     Page* page = this->page();
@@ -267,6 +389,10 @@ void Geolocation::stop()
     m_allowGeolocation = Unknown;
     cancelAllRequests();
     stopUpdating();
+#if PLATFORM(IOS)
+    m_hasChangedPosition = false;
+    m_errorWaitingForResume = nullptr;
+#endif // PLATFORM(IOS)
     m_pendingForPermissionNotifiers.clear();
 }
 
@@ -429,6 +555,11 @@ void Geolocation::setIsAllowed(bool allowed)
     // position.
     m_allowGeolocation = allowed ? Yes : No;
     
+#if PLATFORM(IOS)
+    if (m_isSuspended)
+        return;
+#endif
+
     // Permission request was made during the startRequest process
     if (!m_pendingForPermissionNotifiers.isEmpty()) {
         handlePendingPermissionNotifiers();
@@ -441,6 +572,11 @@ void Geolocation::setIsAllowed(bool allowed)
         error->setIsFatal(true);
         handleError(error.get());
         m_requestsAwaitingCachedPosition.clear();
+#if PLATFORM(IOS)
+        m_hasChangedPosition = false;
+        m_errorWaitingForResume = nullptr;
+#endif
+
         return;
     }
 
@@ -620,11 +756,24 @@ void Geolocation::positionChanged()
     // Stop all currently running timers.
     stopTimers();
 
+#if PLATFORM(IOS)
+    if (m_isSuspended) {
+        m_hasChangedPosition = true;
+        return;
+    }
+#endif
+
     makeSuccessCallbacks();
 }
 
 void Geolocation::setError(GeolocationError* error)
 {
+#if PLATFORM(IOS)
+    if (m_isSuspended) {
+        m_errorWaitingForResume = createPositionError(error);
+        return;
+    }
+#endif
     RefPtr<PositionError> positionError = createPositionError(error);
     handleError(positionError.get());
 }
index 5564c11..461b413 100644 (file)
@@ -54,6 +54,12 @@ public:
     static PassRefPtr<Geolocation> create(ScriptExecutionContext*);
     ~Geolocation();
 
+#if PLATFORM(IOS)
+    virtual bool canSuspend() const OVERRIDE;
+    virtual void suspend(ReasonForSuspension) OVERRIDE;
+    virtual void resume() OVERRIDE;
+    void resetAllGeolocationPermission();
+#endif // PLATFORM(IOS)
     Document* document() const;
     Frame* frame() const;
 
@@ -174,6 +180,15 @@ private:
         Yes,
         No
     } m_allowGeolocation;
+#if PLATFORM(IOS)
+    bool m_isSuspended;
+    bool m_resetOnResume;
+    bool m_hasChangedPosition;
+    RefPtr<PositionError> m_errorWaitingForResume;
+
+    void resumeTimerFired(Timer<Geolocation>*);
+    Timer<Geolocation> m_resumeTimer;
+#endif // PLATFORM(IOS)
 
     GeoNotifierSet m_requestsAwaitingCachedPosition;
 };
index 88bd4b9..cb9e97a 100644 (file)
@@ -57,6 +57,14 @@ NavigatorGeolocation* NavigatorGeolocation::from(Navigator* navigator)
     return supplement;
 }
 
+#if PLATFORM(IOS)
+void NavigatorGeolocation::resetAllGeolocationPermission()
+{
+    if (m_geolocation)
+        m_geolocation->resetAllGeolocationPermission();
+}
+#endif // PLATFORM(IOS)
+
 Geolocation* NavigatorGeolocation::geolocation(Navigator* navigator)
 {
     return NavigatorGeolocation::from(navigator)->geolocation();
index 0130a2c..c5f6540 100644 (file)
@@ -39,6 +39,10 @@ public:
     static Geolocation* geolocation(Navigator*);
     Geolocation* geolocation() const;
 
+#if PLATFORM(IOS)
+    void resetAllGeolocationPermission();
+#endif // PLATFORM(IOS)
+
 private:
     NavigatorGeolocation(Frame*);
     static const char* supplementName();
index e45632a..10c33eb 100644 (file)
@@ -30,6 +30,7 @@
 
 #include "PlatformSpeechSynthesisVoice.h"
 #include "PlatformSpeechSynthesizer.h"
+#include "ScriptController.h"
 #include "SpeechSynthesisEvent.h"
 #include "SpeechSynthesisUtterance.h"
 #include <wtf/CurrentTime.h>
@@ -44,6 +45,9 @@ PassRefPtr<SpeechSynthesis> SpeechSynthesis::create()
 SpeechSynthesis::SpeechSynthesis()
     : m_currentSpeechUtterance(0)
     , m_isPaused(false)
+#if PLATFORM(IOS)
+    , m_restrictions(RequireUserGestureForSpeechStartRestriction)
+#endif
 {
 }
     
@@ -112,6 +116,14 @@ void SpeechSynthesis::speak(SpeechSynthesisUtterance* utterance)
 {
     if (!utterance)
         return;
+    // Like Audio, we should require that the user interact to start a speech synthesis session.
+#if PLATFORM(IOS)
+    if (ScriptController::processingUserGesture())
+        removeBehaviorRestriction(RequireUserGestureForSpeechStartRestriction);
+    else if (userGestureRequiredForSpeechStart())
+        return;
+#endif
     
     m_utteranceQueue.append(utterance);
     
index 9c787a0..ce1e47c 100644 (file)
@@ -76,11 +76,26 @@ private:
     void handleSpeakingCompleted(SpeechSynthesisUtterance*, bool errorOccurred);
     void fireEvent(const AtomicString& type, SpeechSynthesisUtterance*, unsigned long charIndex, const String& name);
     
+#if PLATFORM(IOS)
+    // Restrictions to change default behaviors.
+    enum BehaviorRestrictionFlags {
+        NoRestrictions = 0,
+        RequireUserGestureForSpeechStartRestriction = 1 << 0,
+    };
+    typedef unsigned BehaviorRestrictions;
+    
+    bool userGestureRequiredForSpeechStart() const { return m_restrictions & RequireUserGestureForSpeechStartRestriction; }
+    void removeBehaviorRestriction(BehaviorRestrictions restriction) { m_restrictions &= ~restriction; }
+#endif
+    
     OwnPtr<PlatformSpeechSynthesizer> m_platformSpeechSynthesizer;
     Vector<RefPtr<SpeechSynthesisVoice>> m_voiceList;
     SpeechSynthesisUtterance* m_currentSpeechUtterance;
     Deque<RefPtr<SpeechSynthesisUtterance>> m_utteranceQueue;
     bool m_isPaused;
+#if PLATFORM(IOS)
+    BehaviorRestrictions m_restrictions;
+#endif
 };
     
 } // namespace WebCore
index 2073cd7..0f2ee7f 100644 (file)
 #include "GStreamerUtilities.h"
 #endif
 
+#if PLATFORM(IOS)
+#include "ScriptController.h"
+#include "Settings.h"
+#endif
+
 #include <runtime/ArrayBuffer.h>
 #include <wtf/Atomics.h>
 #include <wtf/MainThread.h>
index d41a974..c26bbb8 100644 (file)
@@ -96,7 +96,6 @@ public:
     virtual void stop() OVERRIDE;
 
     Document* document() const; // ASSERTs if document no longer exists.
-    bool hasDocument();
 
     AudioDestinationNode* destination() { return m_destinationNode.get(); }
     size_t currentSampleFrame() const { return m_destinationNode->currentSampleFrame(); }
index 67c0359..0dc2a82 100644 (file)
 #include <algorithm>
 #include <wtf/MathExtras.h>
 
+#if PLATFORM(IOS)
+#include "ScriptController.h"
+#endif
+
 namespace WebCore {
 
 const double AudioScheduledSourceNode::UnknownTime = -1;
index 869c85f..e182795 100644 (file)
 #include <wtf/StdLibExtras.h>
 #include <wtf/text/CString.h>
 
+#if PLATFORM(IOS)
+#include "SQLiteDatabaseTracker.h"
+#endif
+
 namespace WebCore {
 
 PassRefPtr<Database> Database::create(ScriptExecutionContext*, PassRefPtr<DatabaseBackendBase> backend)
index 5a9f71e..745d563 100644 (file)
 #include <wtf/text/CString.h>
 #include <wtf/text/StringHash.h>
 
+#if PLATFORM(IOS)
+#include "SQLiteDatabaseTracker.h"
+#endif
+
 // Registering "opened" databases with the DatabaseTracker
 // =======================================================
 // The DatabaseTracker maintains a list of databases that have been
@@ -314,6 +318,14 @@ bool DatabaseBackendBase::performOpenAndVerify(bool shouldSetVersionInNewDatabas
 
     const int maxSqliteBusyWaitTime = 30000;
 
+#if PLATFORM(IOS)
+    {
+        // Make sure we wait till the background removal of the empty database files finished before trying to open any database.
+        MutexLocker locker(DatabaseTracker::openDatabaseMutex());
+    }
+    SQLiteTransactionInProgressAutoCounter transactionCounter;
+#endif
+
     if (!m_sqliteDatabase.open(m_filename, true)) {
         errorMessage = formatErrorMessage("unable to open database", m_sqliteDatabase.lastError(), m_sqliteDatabase.lastErrorMsg());
         return false;
@@ -564,6 +576,9 @@ unsigned long long DatabaseBackendBase::maximumSize() const
 
 void DatabaseBackendBase::incrementalVacuumIfNeeded()
 {
+#if PLATFORM(IOS)
+    SQLiteTransactionInProgressAutoCounter transactionCounter;
+#endif
     int64_t freeSpaceSize = m_sqliteDatabase.freeSpaceSize();
     int64_t totalSize = m_sqliteDatabase.totalSize();
     if (totalSize <= 10 * freeSpaceSize) {
index 25b7aa0..752e29e 100644 (file)
@@ -102,6 +102,9 @@ DatabaseContext::DatabaseContext(ScriptExecutionContext* context)
     , m_hasOpenDatabases(false)
     , m_isRegistered(true) // will register on construction below.
     , m_hasRequestedTermination(false)
+#if PLATFORM(IOS)
+    , m_paused(false)
+#endif //PLATFORM(IOS)
 {
     // ActiveDOMObject expects this to be called to set internal flags.
     suspendIfNeeded();
@@ -161,6 +164,9 @@ PassRefPtr<DatabaseBackendContext> DatabaseContext::backend()
 DatabaseThread* DatabaseContext::databaseThread()
 {
     if (!m_databaseThread && !m_hasOpenDatabases) {
+#if PLATFORM(IOS)
+        MutexLocker lock(m_databaseThreadMutex);
+#endif //PLATFORM(IOS)
         // It's OK to ask for the m_databaseThread after we've requested
         // termination because we're still using it to execute the closing
         // of the database. However, it is NOT OK to create a new thread
@@ -172,11 +178,26 @@ DatabaseThread* DatabaseContext::databaseThread()
         m_databaseThread = DatabaseThread::create();
         if (!m_databaseThread->start())
             m_databaseThread = 0;
+#if PLATFORM(IOS)
+        if (m_databaseThread)
+            m_databaseThread->setPaused(m_paused);
+#endif //PLATFORM(IOS)
     }
 
     return m_databaseThread.get();
 }
 
+#if PLATFORM(IOS)
+void DatabaseContext::setPaused(bool paused)
+{
+    MutexLocker lock(m_databaseThreadMutex);
+
+    m_paused = paused;
+    if (m_databaseThread)
+        m_databaseThread->setPaused(m_paused);
+}
+#endif // PLATFORM(IOS)
+
 bool DatabaseContext::stopDatabases(DatabaseTaskSynchronizer* cleanupSync)
 {
     if (m_isRegistered) {
index ea13600..48510d3 100644 (file)
 #include <wtf/Assertions.h>
 #include <wtf/ThreadSafeRefCounted.h>
 
+#if PLATFORM(IOS)
+#include <wtf/Threading.h>
+#endif // PLATFORM(IOS)
+
 namespace WebCore {
 
 class Database;
@@ -53,6 +57,9 @@ public:
 
     PassRefPtr<DatabaseBackendContext> backend();
     DatabaseThread* databaseThread();
+#if PLATFORM(IOS)
+    void setPaused(bool);
+#endif // PLATFORM(IOS)
 
     void setHasOpenDatabases() { m_hasOpenDatabases = true; }
     bool hasOpenDatabases() { return m_hasOpenDatabases; }
@@ -75,6 +82,11 @@ private:
 
     friend class DatabaseBackendContext;
     friend class DatabaseManager;
+
+#if PLATFORM(IOS)
+    Mutex m_databaseThreadMutex;
+    bool m_paused;
+#endif // PLATFORM(IOS)
 };
 
 } // namespace WebCore
index f4da546..afc69f8 100644 (file)
@@ -38,6 +38,12 @@ public:
     virtual ~DatabaseManagerClient() { }
     virtual void dispatchDidModifyOrigin(SecurityOrigin*) = 0;
     virtual void dispatchDidModifyDatabase(SecurityOrigin*, const String& databaseName) = 0;
+
+#if PLATFORM(IOS)
+    virtual void dispatchDidAddNewOrigin(SecurityOrigin*) = 0;
+    virtual void dispatchDidDeleteDatabase() = 0;
+    virtual void dispatchDidDeleteDatabaseOrigin() = 0;
+#endif
 };
 
 } // namespace WebCore
index 7b79468..8cf8ea2 100644 (file)
@@ -85,7 +85,13 @@ void DatabaseTask::performTask()
 
     LOG(StorageAPI, "Performing %s %p\n", debugTaskName(), this);
 
+#if !PLATFORM(IOS)
     m_database->resetAuthorizer();
+#else
+    if (m_database)
+        m_database->resetAuthorizer();
+#endif
+
     doPerformTask();
 
     if (m_synchronizer)
@@ -168,6 +174,13 @@ DatabaseBackend::DatabaseTransactionTask::~DatabaseTransactionTask()
         m_transaction->notifyDatabaseThreadIsShuttingDown();
 }
 
+#if PLATFORM(IOS)
+bool Database::DatabaseTransactionTask::shouldPerformWhilePaused() const
+{
+    return m_transaction->shouldPerformWhilePaused();
+}
+#endif
+
 void DatabaseBackend::DatabaseTransactionTask::doPerformTask()
 {
     m_transaction->performNextStep();
index b3a5508..f6fced5 100644 (file)
@@ -75,6 +75,10 @@ class DatabaseTask {
 public:
     virtual ~DatabaseTask();
 
+#if PLATFORM(IOS)
+    virtual bool shouldPerformWhilePaused() const = 0;
+#endif
+
     void performTask();
 
     DatabaseBackend* database() const { return m_database; }
@@ -104,6 +108,10 @@ public:
     {
         return std::unique_ptr<DatabaseOpenTask>(new DatabaseOpenTask(db, setVersionInNewDatabase, synchronizer, error, errorMessage, success));
     }
+    
+#if PLATFORM(IOS)
+    virtual bool shouldPerformWhilePaused() const OVERRIDE { return true; }
+#endif
 
 private:
     DatabaseOpenTask(DatabaseBackend*, bool setVersionInNewDatabase, DatabaseTaskSynchronizer*, DatabaseError&, String& errorMessage, bool& success);
@@ -126,6 +134,10 @@ public:
         return std::unique_ptr<DatabaseCloseTask>(new DatabaseCloseTask(db, synchronizer));
     }
 
+#if PLATFORM(IOS)
+    virtual bool shouldPerformWhilePaused() const OVERRIDE { return true; }
+#endif
+
 private:
     DatabaseCloseTask(DatabaseBackend*, DatabaseTaskSynchronizer*);
 
@@ -145,6 +157,10 @@ public:
         return std::unique_ptr<DatabaseTransactionTask>(new DatabaseTransactionTask(transaction));
     }
 
+#if PLATFORM(IOS)
+    virtual bool shouldPerformWhilePaused() const OVERRIDE;
+#endif
+
     SQLTransactionBackend* transaction() const { return m_transaction.get(); }
 
 private:
@@ -166,6 +182,10 @@ public:
         return std::unique_ptr<DatabaseTableNamesTask>(new DatabaseTableNamesTask(db, synchronizer, names));
     }
 
+#if PLATFORM(IOS)
+    virtual bool shouldPerformWhilePaused() const OVERRIDE { return true; }
+#endif
+
 private:
     DatabaseTableNamesTask(DatabaseBackend*, DatabaseTaskSynchronizer*, Vector<String>& names);
 
index e0d4796..7ee764c 100644 (file)
@@ -42,6 +42,9 @@ namespace WebCore {
 
 DatabaseThread::DatabaseThread()
     : m_threadID(0)
+#if PLATFORM(IOS)
+    , m_paused(false)
+#endif
     , m_transactionClient(adoptPtr(new SQLTransactionClient()))
     , m_transactionCoordinator(adoptPtr(new SQLTransactionCoordinator()))
     , m_cleanupSync(0)
@@ -77,6 +80,9 @@ void DatabaseThread::requestTermination(DatabaseTaskSynchronizer *cleanupSync)
 {
     m_cleanupSync = cleanupSync;
     LOG(StorageAPI, "DatabaseThread %p was asked to terminate\n", this);
+#if PLATFORM(IOS)
+    m_pausedQueue.kill();
+#endif
     m_queue.kill();
 }
 
@@ -98,6 +104,80 @@ void DatabaseThread::databaseThreadStart(void* vDatabaseThread)
     dbThread->databaseThread();
 }
 
+#if PLATFORM(IOS)
+class DatabaseUnpauseTask : public DatabaseTask {
+public:
+    static std::unique_ptr<DatabaseUnpauseTask> create(DatabaseThread* thread)
+    {
+        return std::unique_ptr<DatabaseUnpauseTask>(new DatabaseUnpauseTask(thread));
+    }
+    
+    virtual bool shouldPerformWhilePaused() const 
+    {
+        // Since we're not locking the DatabaseThread::m_paused in the main database thread loop, it's possible that
+        // a DatabaseUnpauseTask might be added to the m_pausedQueue and performed from within ::handlePausedQueue.
+        // To protect against this, we allow it to be performed even if the database is paused.
+        // If the thread is paused when it is being performed, the tasks from the paused queue will simply be
+        // requeued instead of performed.
+        return true;
+    }
+
+private:
+    DatabaseUnpauseTask(DatabaseThread* thread)
+        : DatabaseTask(0, 0)
+        , m_thread(thread)
+    {}
+
+    virtual void doPerformTask()
+    {
+        m_thread->handlePausedQueue();
+    }
+#if !LOG_DISABLED
+    virtual const char* debugTaskName() const { return "DatabaseUnpauseTask"; }
+#endif
+
+    DatabaseThread* m_thread;
+};
+
+
+void DatabaseThread::setPaused(bool paused)
+{
+    if (m_paused == paused)
+        return;
+
+    MutexLocker pausedLocker(m_pausedMutex);
+    m_paused = paused;
+    if (!m_paused)
+        scheduleTask(DatabaseUnpauseTask::create(this));
+}
+
+void DatabaseThread::handlePausedQueue()
+{
+    Vector<std::unique_ptr<DatabaseTask> > pausedTasks;
+    while (auto task = m_pausedQueue.tryGetMessage())
+        pausedTasks.append(std::move(task));
+
+    for (unsigned i = 0; i < pausedTasks.size(); ++i) {
+        AutodrainedPool pool;
+
+        std::unique_ptr<DatabaseTask> task(pausedTasks[i].release());
+        {
+            MutexLocker pausedLocker(m_pausedMutex);
+            if (m_paused) {
+                m_pausedQueue.append(std::move(task));
+                continue;
+            }
+        }
+            
+        if (terminationRequested())
+            break;
+    
+        task->performTask();
+    }
+}
+#endif //PLATFORM(IOS)
+
+
 void DatabaseThread::databaseThread()
 {
     {
@@ -109,7 +189,14 @@ void DatabaseThread::databaseThread()
     while (auto task = m_queue.waitForMessage()) {
         AutodrainedPool pool;
 
+#if PLATFORM(IOS)
+        if (!m_paused || task->shouldPerformWhilePaused())
+            task->performTask();
+        else
+            m_pausedQueue.append(std::move(task));
+#else
         task->performTask();
+#endif
     }
 
     // Clean up the list of all pending transactions on this database thread
index 4b202ee..c05979e 100644 (file)
@@ -69,6 +69,11 @@ public:
     SQLTransactionClient* transactionClient() { return m_transactionClient.get(); }
     SQLTransactionCoordinator* transactionCoordinator() { return m_transactionCoordinator.get(); }
 
+#if PLATFORM(IOS)
+    void setPaused(bool);
+    void handlePausedQueue();
+#endif
+
 private:
     DatabaseThread();
 
@@ -80,6 +85,11 @@ private:
     RefPtr<DatabaseThread> m_selfRef;
 
     MessageQueue<DatabaseTask> m_queue;
+#if PLATFORM(IOS)
+    MessageQueue<DatabaseTask> m_pausedQueue;
+    Mutex m_pausedMutex;
+    volatile bool m_paused;
+#endif
 
     // This set keeps track of the open databases that have been used on this thread.
     typedef HashSet<RefPtr<DatabaseBackend>> DatabaseSet;
index 38ec1c5..1de1647 100644 (file)
@@ -33,6 +33,7 @@
 
 #include "Chrome.h"
 #include "ChromeClient.h"
+#include "Database.h"
 #include "DatabaseBackendBase.h"
 #include "DatabaseBackendContext.h"
 #include "DatabaseManager.h"
 #include <wtf/StdLibExtras.h>
 #include <wtf/text/CString.h>
 
+#if PLATFORM(IOS)
+#include "WebCoreThread.h"
+#endif
+
 namespace WebCore {
 
 static DatabaseTracker* staticTracker = 0;
@@ -741,6 +746,10 @@ void DatabaseTracker::setQuota(SecurityOrigin* origin, unsigned long long quota)
     openTrackerDatabase(CreateIfDoesNotExist);
     if (!m_database.isOpen())
         return;
+    
+#if PLATFORM(IOS)
+    bool insertedNewOrigin = false;
+#endif
 
     bool originEntryExists = hasEntryForOriginNoLock(origin);
     if (!originEntryExists) {
@@ -753,6 +762,10 @@ void DatabaseTracker::setQuota(SecurityOrigin* origin, unsigned long long quota)
 
             if (statement.step() != SQLResultDone)
                 LOG_ERROR("Unable to establish origin %s in the tracker", origin->databaseIdentifier().ascii().data());
+#if PLATFORM(IOS)
+            else
+                insertedNewOrigin = true;
+#endif
         }
     } else {
         SQLiteStatement statement(m_database, "UPDATE Origins SET quota=? WHERE origin=?");
@@ -769,7 +782,15 @@ void DatabaseTracker::setQuota(SecurityOrigin* origin, unsigned long long quota)
     }
 
     if (m_client)
+#if PLATFORM(IOS)
+    {
+        if (insertedNewOrigin)
+            m_client->dispatchDidAddNewOrigin(origin);
+#endif
         m_client->dispatchDidModifyOrigin(origin);
+#if PLATFORM(IOS)
+    }
+#endif
 }
 
 bool DatabaseTracker::addDatabase(SecurityOrigin* origin, const String& name, const String& path)
@@ -897,6 +918,9 @@ bool DatabaseTracker::deleteOrigin(SecurityOrigin* origin)
 
         if (m_client) {
             m_client->dispatchDidModifyOrigin(origin);
+#if PLATFORM(IOS)
+            m_client->dispatchDidDeleteDatabaseOrigin();
+#endif
             for (unsigned i = 0; i < databaseNames.size(); ++i)
                 m_client->dispatchDidModifyDatabase(origin, databaseNames[i]);
         }
@@ -1062,6 +1086,9 @@ bool DatabaseTracker::deleteDatabase(SecurityOrigin* origin, const String& name)
     if (m_client) {
         m_client->dispatchDidModifyOrigin(origin);
         m_client->dispatchDidModifyDatabase(origin, name);
+#if PLATFORM(IOS)
+        m_client->dispatchDidDeleteDatabase();
+#endif
     }
     doneDeletingDatabase(origin, name);
     
@@ -1110,8 +1137,202 @@ bool DatabaseTracker::deleteDatabaseFile(SecurityOrigin* origin, const String& n
     for (unsigned i = 0; i < deletedDatabases.size(); ++i)
         deletedDatabases[i]->markAsDeletedAndClose();
 
+#if !PLATFORM(IOS)
     return SQLiteFileSystem::deleteDatabaseFile(fullPath);
+#else
+    // On the phone, other background processes may still be accessing this database.  Deleting the database directly
+    // would nuke the POSIX file locks, potentially causing Safari/WebApp to corrupt the new db if it's running in the background.
+    // We'll instead truncate the database file to 0 bytes.  If another process is operating on this same database file after
+    // the truncation, it should get an error since the database file is no longer valid.  When Safari is launched
+    // next time, it'll go through the database files and clean up any zero-bytes ones.
+    SQLiteDatabase database;
+    if (database.open(fullPath))
+        return SQLiteFileSystem::truncateDatabaseFile(database.sqlite3Handle());
+    return false;
+#endif
+}
+    
+#if PLATFORM(IOS)
+void DatabaseTracker::removeDeletedOpenedDatabases()
+{
+    // This is called when another app has deleted a database.  Go through all opened databases in this
+    // tracker and close any that's no longer being tracked in the database.
+    
+    {
+        // Acquire the lock before calling openTrackerDatabase.
+        MutexLocker lockDatabase(m_databaseGuard);
+        openTrackerDatabase(DontCreateIfDoesNotExist);
+    }
+
+    if (!m_database.isOpen())
+        return;
+    
+    // Keep track of which opened databases have been deleted.
+    Vector<RefPtr<Database> > deletedDatabases;
+    typedef HashMap<RefPtr<SecurityOrigin>, Vector<String> > DeletedDatabaseMap;
+    DeletedDatabaseMap deletedDatabaseMap;
+    
+    // Make sure not to hold the m_openDatabaseMapGuard mutex when calling
+    // Database::markAsDeletedAndClose(), since that can cause a deadlock
+    // during the synchronous DatabaseThread call it triggers.
+    {
+        MutexLocker openDatabaseMapLock(m_openDatabaseMapGuard);
+        if (m_openDatabaseMap) {
+            DatabaseOriginMap::const_iterator originMapEnd = m_openDatabaseMap->end();
+            for (DatabaseOriginMap::const_iterator originMapIt = m_openDatabaseMap->begin(); originMapIt != originMapEnd; ++originMapIt) {
+                RefPtr<SecurityOrigin> origin = originMapIt->key;
+                DatabaseNameMap* databaseNameMap = originMapIt->value;
+                Vector<String> deletedDatabaseNamesForThisOrigin;
+
+                // Loop through all opened databases in this origin.  Get the current database file path of each database and see if
+                // it still matches the path stored in the opened database object.
+                DatabaseNameMap::const_iterator dbNameMapEnd = databaseNameMap->end();
+                for (DatabaseNameMap::const_iterator dbNameMapIt = databaseNameMap->begin(); dbNameMapIt != dbNameMapEnd; ++dbNameMapIt) {
+                    String databaseName = dbNameMapIt->key;
+                    String databaseFileName;
+                    SQLiteStatement statement(m_database, "SELECT path FROM Databases WHERE origin=? AND name=?;");
+                    if (statement.prepare() == SQLResultOk) {
+                        statement.bindText(1, origin->databaseIdentifier());
+                        statement.bindText(2, databaseName);
+                        if (statement.step() == SQLResultRow)
+                            databaseFileName = statement.getColumnText(0);
+                        statement.finalize();
+                    }
+                    
+                    bool foundDeletedDatabase = false;
+                    DatabaseSet* databaseSet = dbNameMapIt->value;
+                    DatabaseSet::const_iterator dbEnd = databaseSet->end();
+                    for (DatabaseSet::const_iterator dbIt = databaseSet->begin(); dbIt != dbEnd; ++dbIt) {
+                        Database* db = static_cast<Database*>(*dbIt);
+                        
+                        // We are done if this database has already been marked as deleted.
+                        if (db->deleted())
+                            continue;
+                        
+                        // If this database has been deleted or if its database file no longer matches the current version, this database is no longer valid and it should be marked as deleted.
+                        if (databaseFileName.isNull() || databaseFileName != pathGetFileName(db->fileName())) {
+                            deletedDatabases.append(db);
+                            foundDeletedDatabase = true;
+                        }
+                    }
+                    
+                    // If the database no longer exists, we should remember to remove it from the OriginQuotaManager later.
+                    if (foundDeletedDatabase && databaseFileName.isNull())
+                        deletedDatabaseNamesForThisOrigin.append(databaseName);
+                }
+                
+                if (!deletedDatabaseNamesForThisOrigin.isEmpty())
+                    deletedDatabaseMap.set(origin, deletedDatabaseNamesForThisOrigin);
+            }
+        }
+    }
+    
+    for (unsigned i = 0; i < deletedDatabases.size(); ++i)
+        deletedDatabases[i]->markAsDeletedAndClose();
+    
+    DeletedDatabaseMap::const_iterator end = deletedDatabaseMap.end();
+    for (DeletedDatabaseMap::const_iterator it = deletedDatabaseMap.begin(); it != end; ++it) {
+        SecurityOrigin* origin = it->key.get();
+        if (m_client)
+            m_client->dispatchDidModifyOrigin(origin);
+        
+        const Vector<String>& databaseNames = it->value;
+        for (unsigned i = 0; i < databaseNames.size(); ++i) {
+            if (m_client)
+                m_client->dispatchDidModifyDatabase(origin, databaseNames[i]);
+        }        
+    }
 }
+    
+static bool isZeroByteFile(const String& path)
+{
+    long long size = 0;
+    return getFileSize(path, size) && !size;
+}
+    
+bool DatabaseTracker::deleteDatabaseFileIfEmpty(const String& path)
+{
+    if (!isZeroByteFile(path))
+        return false;
+    
+    SQLiteDatabase database;
+    if (!database.open(path))
+        return false;
+    
+    // Specify that we want the exclusive locking mode, so after the next read,
+    // we'll be holding the lock to this database file.
+    SQLiteStatement lockStatement(database, "PRAGMA locking_mode=EXCLUSIVE;");
+    if (lockStatement.prepare() != SQLResultOk)
+        return false;
+    int result = lockStatement.step();
+    if (result != SQLResultRow && result != SQLResultDone)
+        return false;
+    lockStatement.finalize();
+
+    // Every sqlite database has a sqlite_master table that contains the schema for the database.
+    // http://www.sqlite.org/faq.html#q7
+    SQLiteStatement readStatement(database, "SELECT * FROM sqlite_master LIMIT 1;");    
+    if (readStatement.prepare() != SQLResultOk)
+        return false;
+    // We shouldn't expect any result.
+    if (readStatement.step() != SQLResultDone)
+        return false;
+    readStatement.finalize();
+    
+    // At this point, we hold the exclusive lock to this file.  Double-check again to make sure
+    // it's still zero bytes.
+    if (!isZeroByteFile(path))
+        return false;
+    
+    return SQLiteFileSystem::deleteDatabaseFile(path);
+}
+
+Mutex& DatabaseTracker::openDatabaseMutex()
+{
+    DEFINE_STATIC_LOCAL(Mutex, mutex, ());
+    return mutex;
+}
+
+void DatabaseTracker::emptyDatabaseFilesRemovalTaskWillBeScheduled()
+{
+    // Lock the database from opening any database until we are done with scanning the file system for
+    // zero byte database files to remove.
+    openDatabaseMutex().lock();
+}
+
+void DatabaseTracker::emptyDatabaseFilesRemovalTaskDidFinish()
+{
+    openDatabaseMutex().unlock();
+}
+
+void DatabaseTracker::setDatabasesPaused(bool paused)
+{
+    MutexLocker openDatabaseMapLock(m_openDatabaseMapGuard);
+    if (!m_openDatabaseMap)
+        return;
+
+    // This walking is - sadly - the only reliable way to get at each open database thread.
+    // This will be cleaner once <rdar://problem/5680441> or some other DB thread consolidation takes place.
+    DatabaseOriginMap::iterator i = m_openDatabaseMap.get()->begin();
+    DatabaseOriginMap::iterator end = m_openDatabaseMap.get()->end();
+    
+    for (; i != end; ++i) {
+        DatabaseNameMap* databaseNameMap = i->value;
+        DatabaseNameMap::iterator j = databaseNameMap->begin();
+        DatabaseNameMap::iterator dbNameMapEnd = databaseNameMap->end();
+        for (; j != dbNameMapEnd; ++j) {
+            DatabaseSet* databaseSet = j->value;
+            DatabaseSet::iterator k = databaseSet->begin();
+            DatabaseSet::iterator dbSetEnd = databaseSet->end();
+            for (; k != dbSetEnd; ++k) {
+                DatabaseContext* context = (*k)->databaseContext();
+                context->setPaused(paused);
+            }
+        }
+    }
+}
+
+#endif
 
 void DatabaseTracker::setClient(DatabaseManagerClient* client)
 {
index 3523740..f8a5d12 100644 (file)
@@ -100,6 +100,21 @@ public:
     bool deleteOrigin(SecurityOrigin*);
     bool deleteDatabase(SecurityOrigin*, const String& name);
 
+#if PLATFORM(IOS)
+    void removeDeletedOpenedDatabases();
+    static bool deleteDatabaseFileIfEmpty(const String&);
+
+    // MobileSafari will grab this mutex on the main thread before dispatching the task to 
+    // clean up zero byte database files.  Any operations to open new database will have to
+    // wait for that task to finish by waiting on this mutex.
+    static Mutex& openDatabaseMutex();
+    
+    static void emptyDatabaseFilesRemovalTaskWillBeScheduled();
+    static void emptyDatabaseFilesRemovalTaskDidFinish();
+    
+    void setDatabasesPaused(bool);
+#endif
+    
     void setClient(DatabaseManagerClient*);
 
     // From a secondary thread, must be thread safe with its data
index 568be97..244f285 100644 (file)
@@ -518,6 +518,14 @@ void SQLTransactionBackend::performNextStep()
     runStateMachine();
 }
 
+#if PLATFORM(IOS)
+bool SQLTransactionBackend::shouldPerformWhilePaused() const
+{
+    // SQLTransactions should only run-while-paused if they have progressed passed the first transaction step.
+    return m_nextState != SQLTransactionState::AcquireLock;
+}
+#endif
+
 void SQLTransactionBackend::executeSQL(PassOwnPtr<AbstractSQLStatement> statement,
     const String& sqlStatement, const Vector<SQLValue>& arguments, int permissions)
 {
index 6efc751..fec3661 100644 (file)
@@ -68,6 +68,10 @@ public:
     void lockAcquired();
     void performNextStep();
 
+#if PLATFORM(IOS)
+    bool shouldPerformWhilePaused() const;
+#endif
+
     DatabaseBackend* database() { return m_database.get(); }
     bool isReadOnly() { return m_readOnly; }
     void notifyDatabaseThreadIsShuttingDown();
diff --git a/Source/WebCore/Resources/DictationPhraseWithAlternativesDot.png b/Source/WebCore/Resources/DictationPhraseWithAlternativesDot.png
new file mode 100644 (file)
index 0000000..42e10f8
Binary files /dev/null and b/Source/WebCore/Resources/DictationPhraseWithAlternativesDot.png differ
diff --git a/Source/WebCore/Resources/DictationPhraseWithAlternativesDot@2x.png b/Source/WebCore/Resources/DictationPhraseWithAlternativesDot@2x.png
new file mode 100644 (file)
index 0000000..ff369fb
Binary files /dev/null and b/Source/WebCore/Resources/DictationPhraseWithAlternativesDot@2x.png differ
diff --git a/Source/WebCore/Resources/SpellingDot.png b/Source/WebCore/Resources/SpellingDot.png
new file mode 100644 (file)
index 0000000..761a9b7
Binary files /dev/null and b/Source/WebCore/Resources/SpellingDot.png differ
diff --git a/Source/WebCore/Resources/SpellingDot@2x.png b/Source/WebCore/Resources/SpellingDot@2x.png
new file mode 100644 (file)
index 0000000..fa8e31c
Binary files /dev/null and b/Source/WebCore/Resources/SpellingDot@2x.png differ
diff --git a/Source/WebCore/Resources/decrementArrow.tiff b/Source/WebCore/Resources/decrementArrow.tiff
new file mode 100644 (file)
index 0000000..714f024
Binary files /dev/null and b/Source/WebCore/Resources/decrementArrow.tiff differ
diff --git a/Source/WebCore/Resources/hScrollControl_left.png b/Source/WebCore/Resources/hScrollControl_left.png
new file mode 100644 (file)
index 0000000..b7bd87d
Binary files /dev/null and b/Source/WebCore/Resources/hScrollControl_left.png differ
diff --git a/Source/WebCore/Resources/hScrollControl_middle.png b/Source/WebCore/Resources/hScrollControl_middle.png
new file mode 100644 (file)
index 0000000..3c35116
Binary files /dev/null and b/Source/WebCore/Resources/hScrollControl_middle.png differ
diff --git a/Source/WebCore/Resources/hScrollControl_right.png b/Source/WebCore/Resources/hScrollControl_right.png
new file mode 100644 (file)
index 0000000..45732ec
Binary files /dev/null and b/Source/WebCore/Resources/hScrollControl_right.png differ
diff --git a/Source/WebCore/Resources/incrementArrow.tiff b/Source/WebCore/Resources/incrementArrow.tiff
new file mode 100644 (file)
index 0000000..d6f4b7f
Binary files /dev/null and b/Source/WebCore/Resources/incrementArrow.tiff differ
diff --git a/Source/WebCore/Resources/markedLeft.png b/Source/WebCore/Resources/markedLeft.png
new file mode 100644 (file)
index 0000000..268eda1
Binary files /dev/null and b/Source/WebCore/Resources/markedLeft.png differ
diff --git a/Source/WebCore/Resources/markedMiddle.png b/Source/WebCore/Resources/markedMiddle.png
new file mode 100644 (file)
index 0000000..517ae14
Binary files /dev/null and b/Source/WebCore/Resources/markedMiddle.png differ
diff --git a/Source/WebCore/Resources/markedRight.png b/Source/WebCore/Resources/markedRight.png
new file mode 100644 (file)
index 0000000..d7497d3
Binary files /dev/null and b/Source/WebCore/Resources/markedRight.png differ
diff --git a/Source/WebCore/Resources/vScrollControl_bottom.png b/Source/WebCore/Resources/vScrollControl_bottom.png
new file mode 100644 (file)
index 0000000..f8b0f2e
Binary files /dev/null and b/Source/WebCore/Resources/vScrollControl_bottom.png differ
diff --git a/Source/WebCore/Resources/vScrollControl_middle.png b/Source/WebCore/Resources/vScrollControl_middle.png
new file mode 100644 (file)
index 0000000..a21cd7d
Binary files /dev/null and b/Source/WebCore/Resources/vScrollControl_middle.png differ
diff --git a/Source/WebCore/Resources/vScrollControl_top.png b/Source/WebCore/Resources/vScrollControl_top.png
new file mode 100644 (file)
index 0000000..6a22c5c
Binary files /dev/null and b/Source/WebCore/Resources/vScrollControl_top.png differ
index db959cf..d0acc9b 100644 (file)
@@ -63,6 +63,7 @@
                01D3CF8514BD0A3000FE9970 /* WebGLContextObject.h in Headers */ = {isa = PBXBuildFile; fileRef = 01D3CF7F14BD0A3000FE9970 /* WebGLContextObject.h */; };
                01D3CF8614BD0A3000FE9970 /* WebGLSharedObject.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 01D3CF8014BD0A3000FE9970 /* WebGLSharedObject.cpp */; };
                01D3CF8714BD0A3000FE9970 /* WebGLSharedObject.h in Headers */ = {isa = PBXBuildFile; fileRef = 01D3CF8114BD0A3000FE9970 /* WebGLSharedObject.h */; };
+               01E6C2E41194B2820050821C /* SpellingDot@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 01E6C2E31194B2820050821C /* SpellingDot@2x.png */; };
                0562F9461573ECEB0031CA16 /* WebKitCSSSVGDocumentValue.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0562F9441573ECEB0031CA16 /* WebKitCSSSVGDocumentValue.cpp */; };
                0562F9471573ECEB0031CA16 /* WebKitCSSSVGDocumentValue.h in Headers */ = {isa = PBXBuildFile; fileRef = 0562F9451573ECEB0031CA16 /* WebKitCSSSVGDocumentValue.h */; };
                0562F9611573F88F0031CA16 /* PlatformLayer.h in Headers */ = {isa = PBXBuildFile; fileRef = 0562F9601573F88F0031CA16 /* PlatformLayer.h */; settings = {ATTRIBUTES = (Private, ); }; };
                A17C81220F2A5CF7005DAAEB /* HTMLElementFactory.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A17C81200F2A5CF7005DAAEB /* HTMLElementFactory.cpp */; };
                A17C81230F2A5CF7005DAAEB /* HTMLElementFactory.h in Headers */ = {isa = PBXBuildFile; fileRef = A17C81210F2A5CF7005DAAEB /* HTMLElementFactory.h */; };
                A1C7FAA2133A5D3500D6732D /* JSXPathResultCustom.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A1C7FAA1133A5D3500D6732D /* JSXPathResultCustom.cpp */; };
+               A1DE712D18612AC100734192 /* TouchEvents.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A1DE712B18612AC100734192 /* TouchEvents.cpp */; };
+               A1DE71321861322200734192 /* TouchConstructors.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A1DE71301861322200734192 /* TouchConstructors.cpp */; };
                A1E1154413015C3D0054AC8C /* DistantLightSource.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A1E1154313015C3D0054AC8C /* DistantLightSource.cpp */; };
                A1E1154613015C4E0054AC8C /* PointLightSource.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A1E1154513015C4E0054AC8C /* PointLightSource.cpp */; };
                A1E1154813015C5D0054AC8C /* SpotLightSource.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A1E1154713015C5D0054AC8C /* SpotLightSource.cpp */; };
                A5AFB34F115151A700B045CB /* StepRange.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A5AFB34D115151A700B045CB /* StepRange.cpp */; };
                A5AFB350115151A700B045CB /* StepRange.h in Headers */ = {isa = PBXBuildFile; fileRef = A5AFB34E115151A700B045CB /* StepRange.h */; settings = {ATTRIBUTES = (Private, ); }; };
                A5C566AB127A3AAD00E8A3FF /* DiskImageCacheClientIOS.h in Headers */ = {isa = PBXBuildFile; fileRef = A5C566AA127A3AAD00E8A3FF /* DiskImageCacheClientIOS.h */; settings = {ATTRIBUTES = (Private, ); }; };
+               A5DEBDA316FB908700836FE0 /* WebKitPlaybackTargetAvailabilityEvent.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A5DEBD9F16FB908700836FE0 /* WebKitPlaybackTargetAvailabilityEvent.cpp */; };
+               A5DEBDA416FB908700836FE0 /* WebKitPlaybackTargetAvailabilityEvent.h in Headers */ = {isa = PBXBuildFile; fileRef = A5DEBDA016FB908700836FE0 /* WebKitPlaybackTargetAvailabilityEvent.h */; };
                A5F6E16B132ED46E008EDAE3 /* Autocapitalize.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A5F6E16C132ED46E008EDAE3 /* Autocapitalize.cpp */; };
                A5F9EF701266750D00FCCF52 /* DiskImageCacheIOS.mm in Sources */ = {isa = PBXBuildFile; fileRef = A5F9EF6E1266750D00FCCF52 /* DiskImageCacheIOS.mm */; };
                A5F9EF711266750D00FCCF52 /* DiskImageCacheIOS.h in Headers */ = {isa = PBXBuildFile; fileRef = A5F9EF6F1266750D00FCCF52 /* DiskImageCacheIOS.h */; settings = {ATTRIBUTES = (Private, ); }; };
                BE88E0DF1715D2A200658D98 /* VideoTrack.h in Headers */ = {isa = PBXBuildFile; fileRef = BE88E0D31715D2A200658D98 /* VideoTrack.h */; settings = {ATTRIBUTES = (Private, ); }; };
                BE88E0E11715D2A200658D98 /* VideoTrackList.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BE88E0D51715D2A200658D98 /* VideoTrackList.cpp */; };
                BE88E0E21715D2A200658D98 /* VideoTrackList.h in Headers */ = {isa = PBXBuildFile; fileRef = BE88E0D61715D2A200658D98 /* VideoTrackList.h */; };
+               BE8C753110681324001E93F5 /* SpellingDot.png in Resources */ = {isa = PBXBuildFile; fileRef = BE8C753010681324001E93F5 /* SpellingDot.png */; };
                BE8EF042171C8FF9009B48C3 /* JSAudioTrack.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BE8EF03E171C8FF9009B48C3 /* JSAudioTrack.cpp */; };
                BE8EF043171C8FF9009B48C3 /* JSAudioTrack.h in Headers */ = {isa = PBXBuildFile; fileRef = BE8EF03F171C8FF9009B48C3 /* JSAudioTrack.h */; };
                BE8EF044171C8FF9009B48C3 /* JSAudioTrackList.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BE8EF040171C8FF9009B48C3 /* JSAudioTrackList.cpp */; };
                D000ED2811C1B9CD00C47726 /* SubframeLoader.h in Headers */ = {isa = PBXBuildFile; fileRef = D000ED2611C1B9CD00C47726 /* SubframeLoader.h */; settings = {ATTRIBUTES = (Private, ); }; };
                D01A27AD10C9BFD800026A42 /* SpaceSplitString.cpp in Sources */ = {isa = PBXBuildFile; fileRef = D01A27AB10C9BFD800026A42 /* SpaceSplitString.cpp */; };
                D01A27AE10C9BFD800026A42 /* SpaceSplitString.h in Headers */ = {isa = PBXBuildFile; fileRef = D01A27AC10C9BFD800026A42 /* SpaceSplitString.h */; settings = {ATTRIBUTES = (Private, ); }; };
+               D02B64B214089E56006EFA21 /* DictationPhraseWithAlternativesDot.png in Resources */ = {isa = PBXBuildFile; fileRef = D02B64B014089E56006EFA21 /* DictationPhraseWithAlternativesDot.png */; };
+               D02B64B314089E56006EFA21 /* DictationPhraseWithAlternativesDot@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = D02B64B114089E56006EFA21 /* DictationPhraseWithAlternativesDot@2x.png */; };
                D05CED290A40BB2C00C5AF38 /* FormatBlockCommand.cpp in Sources */ = {isa = PBXBuildFile; fileRef = D05CED270A40BB2C00C5AF38 /* FormatBlockCommand.cpp */; };
                D05CED2A0A40BB2C00C5AF38 /* FormatBlockCommand.h in Headers */ = {isa = PBXBuildFile; fileRef = D05CED280A40BB2C00C5AF38 /* FormatBlockCommand.h */; };
                D06C0D8F0CFD11460065F43F /* RemoveFormatCommand.h in Headers */ = {isa = PBXBuildFile; fileRef = D06C0D8D0CFD11460065F43F /* RemoveFormatCommand.h */; };
                D0B0556809C6700100307E43 /* CreateLinkCommand.h in Headers */ = {isa = PBXBuildFile; fileRef = D0B0556609C6700100307E43 /* CreateLinkCommand.h */; };
                D0B0556909C6700100307E43 /* CreateLinkCommand.cpp in Sources */ = {isa = PBXBuildFile; fileRef = D0B0556709C6700100307E43 /* CreateLinkCommand.cpp */; };
                D0BC54491443AC4A00E105DA /* CachedStyleSheetClient.h in Headers */ = {isa = PBXBuildFile; fileRef = D0BC54481443AC4A00E105DA /* CachedStyleSheetClient.h */; settings = {ATTRIBUTES = (Private, ); }; };
+               D0BD4F5C1408850F006839B6 /* DictationCommandIOS.cpp in Sources */ = {isa = PBXBuildFile; fileRef = D0BD4F5A1408850F006839B6 /* DictationCommandIOS.cpp */; };
+               D0BD4F5D1408850F006839B6 /* DictationCommandIOS.h in Headers */ = {isa = PBXBuildFile; fileRef = D0BD4F5B1408850F006839B6 /* DictationCommandIOS.h */; };
                D0CE58F8125E4CC200F3F199 /* ResourceLoadScheduler.cpp in Sources */ = {isa = PBXBuildFile; fileRef = D0CE58F6125E4CC200F3F199 /* ResourceLoadScheduler.cpp */; };
                D0CE58F9125E4CC200F3F199 /* ResourceLoadScheduler.h in Headers */ = {isa = PBXBuildFile; fileRef = D0CE58F7125E4CC200F3F199 /* ResourceLoadScheduler.h */; settings = {ATTRIBUTES = (Private, ); }; };
                D0EDA774143E303C0028E383 /* CachedRawResource.cpp in Sources */ = {isa = PBXBuildFile; fileRef = D0EDA772143E303C0028E383 /* CachedRawResource.cpp */; };
                FEB26D28167A8F2A00FDD26B /* DatabaseServer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FEB26D27167A8F2A00FDD26B /* DatabaseServer.cpp */; };
                FEBC5F3116BD0CC300659BD3 /* DatabaseBase.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FEBC5F2F16BD0CC300659BD3 /* DatabaseBase.cpp */; };
                FEBC5F3216BD0CC300659BD3 /* DatabaseBase.h in Headers */ = {isa = PBXBuildFile; fileRef = FEBC5F3016BD0CC300659BD3 /* DatabaseBase.h */; settings = {ATTRIBUTES = (Private, ); }; };
+               FED13D2A0CEA91DF00D89466 /* DOMUIKitExtensions.h in Headers */ = {isa = PBXBuildFile; fileRef = FED13D260CEA91DF00D89466 /* DOMUIKitExtensions.h */; settings = {ATTRIBUTES = (Private, ); }; };
+               FED13D2B0CEA91DF00D89466 /* DOMUIKitExtensions.mm in Sources */ = {isa = PBXBuildFile; fileRef = FED13D270CEA91DF00D89466 /* DOMUIKitExtensions.mm */; };
                FED13D3A0CEA934600D89466 /* EditorIOS.mm in Sources */ = {isa = PBXBuildFile; fileRef = FED13D390CEA934600D89466 /* EditorIOS.mm */; };
                FED13D3D0CEA936A00D89466 /* FrameIOS.mm in Sources */ = {isa = PBXBuildFile; fileRef = FED13D3B0CEA936A00D89466 /* FrameIOS.mm */; };
                FED13D400CEA939400D89466 /* IconIOS.mm in Sources */ = {isa = PBXBuildFile; fileRef = FED13D3F0CEA939400D89466 /* IconIOS.mm */; };
                01D3CF7F14BD0A3000FE9970 /* WebGLContextObject.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = WebGLContextObject.h; path = canvas/WebGLContextObject.h; sourceTree = "<group>"; };
                01D3CF8014BD0A3000FE9970 /* WebGLSharedObject.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = WebGLSharedObject.cpp; path = canvas/WebGLSharedObject.cpp; sourceTree = "<group>"; };
                01D3CF8114BD0A3000FE9970 /* WebGLSharedObject.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = WebGLSharedObject.h; path = canvas/WebGLSharedObject.h; sourceTree = "<group>"; };
+               01E6C2E31194B2820050821C /* SpellingDot@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "SpellingDot@2x.png"; sourceTree = "<group>"; };
                0562F9441573ECEB0031CA16 /* WebKitCSSSVGDocumentValue.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = WebKitCSSSVGDocumentValue.cpp; sourceTree = "<group>"; };
                0562F9451573ECEB0031CA16 /* WebKitCSSSVGDocumentValue.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WebKitCSSSVGDocumentValue.h; sourceTree = "<group>"; };
                0562F9601573F88F0031CA16 /* PlatformLayer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PlatformLayer.h; sourceTree = "<group>"; };
                A17C81200F2A5CF7005DAAEB /* HTMLElementFactory.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = HTMLElementFactory.cpp; sourceTree = "<group>"; };
                A17C81210F2A5CF7005DAAEB /* HTMLElementFactory.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = HTMLElementFactory.h; sourceTree = "<group>"; };
                A1C7FAA1133A5D3500D6732D /* JSXPathResultCustom.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSXPathResultCustom.cpp; sourceTree = "<group>"; };
+               A1DE712B18612AC100734192 /* TouchEvents.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = TouchEvents.cpp; sourceTree = "<group>"; };
+               A1DE71301861322200734192 /* TouchConstructors.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = TouchConstructors.cpp; sourceTree = "<group>"; };
                A1E1154313015C3D0054AC8C /* DistantLightSource.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = DistantLightSource.cpp; path = filters/DistantLightSource.cpp; sourceTree = "<group>"; };
                A1E1154513015C4E0054AC8C /* PointLightSource.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = PointLightSource.cpp; path = filters/PointLightSource.cpp; sourceTree = "<group>"; };
                A1E1154713015C5D0054AC8C /* SpotLightSource.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SpotLightSource.cpp; path = filters/SpotLightSource.cpp; sourceTree = "<group>"; };
                A5C566AA127A3AAD00E8A3FF /* DiskImageCacheClientIOS.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DiskImageCacheClientIOS.h; sourceTree = "<group>"; };
                A5C974CF11485FF10066F2AB /* KeyEventCocoa.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = KeyEventCocoa.h; path = cocoa/KeyEventCocoa.h; sourceTree = "<group>"; };
                A5C974D011485FF10066F2AB /* KeyEventCocoa.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = KeyEventCocoa.mm; path = cocoa/KeyEventCocoa.mm; sourceTree = "<group>"; };
+               A5DEBD9F16FB908700836FE0 /* WebKitPlaybackTargetAvailabilityEvent.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = WebKitPlaybackTargetAvailabilityEvent.cpp; sourceTree = "<group>"; };
+               A5DEBDA016FB908700836FE0 /* WebKitPlaybackTargetAvailabilityEvent.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WebKitPlaybackTargetAvailabilityEvent.h; sourceTree = "<group>"; };
+               A5DEBDA116FB908700836FE0 /* WebKitPlaybackTargetAvailabilityEvent.idl */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = WebKitPlaybackTargetAvailabilityEvent.idl; sourceTree = "<group>"; };
                A5F6E16C132ED46E008EDAE3 /* Autocapitalize.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Autocapitalize.cpp; sourceTree = "<group>"; };
                A5F9EF6E1266750D00FCCF52 /* DiskImageCacheIOS.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = DiskImageCacheIOS.mm; sourceTree = "<group>"; };
                A5F9EF6F1266750D00FCCF52 /* DiskImageCacheIOS.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DiskImageCacheIOS.h; sourceTree = "<group>"; };
                BE88E0D51715D2A200658D98 /* VideoTrackList.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = VideoTrackList.cpp; sourceTree = "<group>"; };
                BE88E0D61715D2A200658D98 /* VideoTrackList.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = VideoTrackList.h; sourceTree = "<group>"; };
                BE88E0D71715D2A200658D98 /* VideoTrackList.idl */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = VideoTrackList.idl; sourceTree = "<group>"; };
+               BE8C753010681324001E93F5 /* SpellingDot.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = SpellingDot.png; sourceTree = "<group>"; };
                BE8EF03E171C8FF9009B48C3 /* JSAudioTrack.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSAudioTrack.cpp; sourceTree = "<group>"; };
                BE8EF03F171C8FF9009B48C3 /* JSAudioTrack.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSAudioTrack.h; sourceTree = "<group>"; };
                BE8EF040171C8FF9009B48C3 /* JSAudioTrackList.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSAudioTrackList.cpp; sourceTree = "<group>"; };
                D000ED2611C1B9CD00C47726 /* SubframeLoader.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SubframeLoader.h; sourceTree = "<group>"; };
                D01A27AB10C9BFD800026A42 /* SpaceSplitString.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SpaceSplitString.cpp; sourceTree = "<group>"; };
                D01A27AC10C9BFD800026A42 /* SpaceSplitString.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SpaceSplitString.h; sourceTree = "<group>"; };
+               D02B64B014089E56006EFA21 /* DictationPhraseWithAlternativesDot.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = DictationPhraseWithAlternativesDot.png; sourceTree = "<group>"; };
+               D02B64B114089E56006EFA21 /* DictationPhraseWithAlternativesDot@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "DictationPhraseWithAlternativesDot@2x.png"; sourceTree = "<group>"; };
                D05CED270A40BB2C00C5AF38 /* FormatBlockCommand.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = FormatBlockCommand.cpp; sourceTree = "<group>"; };
                D05CED280A40BB2C00C5AF38 /* FormatBlockCommand.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = FormatBlockCommand.h; sourceTree = "<group>"; };
                D06C0D8D0CFD11460065F43F /* RemoveFormatCommand.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RemoveFormatCommand.h; sourceTree = "<group>"; };
                D0B0556609C6700100307E43 /* CreateLinkCommand.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CreateLinkCommand.h; sourceTree = "<group>"; };
                D0B0556709C6700100307E43 /* CreateLinkCommand.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CreateLinkCommand.cpp; sourceTree = "<group>"; };
                D0BC54481443AC4A00E105DA /* CachedStyleSheetClient.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CachedStyleSheetClient.h; sourceTree = "<group>"; };
+               D0BD4F5A1408850F006839B6 /* DictationCommandIOS.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = DictationCommandIOS.cpp; sourceTree = "<group>"; };
+               D0BD4F5B1408850F006839B6 /* DictationCommandIOS.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DictationCommandIOS.h; sourceTree = "<group>"; };
                D0CE58F6125E4CC200F3F199 /* ResourceLoadScheduler.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ResourceLoadScheduler.cpp; sourceTree = "<group>"; };
                D0CE58F7125E4CC200F3F199 /* ResourceLoadScheduler.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ResourceLoadScheduler.h; sourceTree = "<group>"; };
                D0EDA772143E303C0028E383 /* CachedRawResource.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CachedRawResource.cpp; sourceTree = "<group>"; };
                FEB26D27167A8F2A00FDD26B /* DatabaseServer.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = DatabaseServer.cpp; sourceTree = "<group>"; };
                FEBC5F2F16BD0CC300659BD3 /* DatabaseBase.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = DatabaseBase.cpp; sourceTree = "<group>"; };
                FEBC5F3016BD0CC300659BD3 /* DatabaseBase.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DatabaseBase.h; sourceTree = "<group>"; };
+               FED13D260CEA91DF00D89466 /* DOMUIKitExtensions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DOMUIKitExtensions.h; sourceTree = "<group>"; };
+               FED13D270CEA91DF00D89466 /* DOMUIKitExtensions.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = DOMUIKitExtensions.mm; sourceTree = "<group>"; };
                FED13D390CEA934600D89466 /* EditorIOS.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = EditorIOS.mm; sourceTree = "<group>"; };
                FED13D3B0CEA936A00D89466 /* FrameIOS.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = FrameIOS.mm; sourceTree = "<group>"; };
                FED13D3F0CEA939400D89466 /* IconIOS.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = IconIOS.mm; sourceTree = "<group>"; };
                FEDEF84016797108000E444A /* DatabaseStrategy.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DatabaseStrategy.h; sourceTree = "<group>"; };
                FEE1811116C319E800084849 /* SQLTransactionBackend.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SQLTransactionBackend.cpp; sourceTree = "<group>"; };
                FEE1811216C319E800084849 /* SQLTransactionBackend.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SQLTransactionBackend.h; sourceTree = "<group>"; };
+               FEE7D6610D99AD16005351F6 /* iOS.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; path = iOS.xcconfig; sourceTree = "<group>"; };
                FF945EC9161F7F3600971BC8 /* PseudoElement.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = PseudoElement.cpp; sourceTree = "<group>"; };
                FF945ECA161F7F3600971BC8 /* PseudoElement.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PseudoElement.h; sourceTree = "<group>"; };
                FFAC30FC184FB145008C4F1E /* TrailingObjects.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TrailingObjects.h; sourceTree = "<group>"; };
                        isa = PBXGroup;
                        children = (
                                CD0DBB3E142274E600280263 /* audio */,
+                               65998A650E5F5FD3004E097A /* images */,
                                46F9D5DA0B0D60170028EE36 /* aliasCursor.png */,
                                46D4F2460AF97E810035385A /* cellCursor.png */,
                                93153BDD141959F400FCF5BE /* deleteButton.png */,
                                1CDD45E60BA9C84600F90147 /* Base.xcconfig */,
                                1CDD45E40BA9C84600F90147 /* DebugRelease.xcconfig */,
                                449098B10F8F82520076A327 /* FeatureDefines.xcconfig */,
+                               FEE7D6610D99AD16005351F6 /* iOS.xcconfig */,
                                1C904DF90BA9D2C80081E9D0 /* Version.xcconfig */,
                                1CDD45E50BA9C84600F90147 /* WebCore.xcconfig */,
                                E1BA66F21742BDCC00C20251 /* WebCoreTestShim.xcconfig */,
                443292C10EBA6D7300E62016 /* ios */ = {
                        isa = PBXGroup;
                        children = (
+                               D0BD4F5A1408850F006839B6 /* DictationCommandIOS.cpp */,
+                               D0BD4F5B1408850F006839B6 /* DictationCommandIOS.h */,
                                FED13D390CEA934600D89466 /* EditorIOS.mm */,
                        );
                        path = ios;
                        path = mac;
                        sourceTree = "<group>";
                };
+               65998A650E5F5FD3004E097A /* images */ = {
+                       isa = PBXGroup;
+                       children = (
+                               D02B64B014089E56006EFA21 /* DictationPhraseWithAlternativesDot.png */,
+                               D02B64B114089E56006EFA21 /* DictationPhraseWithAlternativesDot@2x.png */,
+                               BE8C753010681324001E93F5 /* SpellingDot.png */,
+                               01E6C2E31194B2820050821C /* SpellingDot@2x.png */,
+                       );
+                       name = images;
+                       sourceTree = "<group>";
+               };
                65BF02180974806300C43196 /* page */ = {
                        isa = PBXGroup;
                        children = (
                971145FE14EF006E00674FD9 /* Modules */ = {
                        isa = PBXGroup;
                        children = (
+                               CE26169D187E6554007955F3 /* airplay */,
                                072AE1DE183C0513000A5988 /* plugins */,
                                CDA98DBD16014E0800FEA3B1 /* encryptedmedia */,
                                971145FF14EF007900674FD9 /* geolocation */,
                                8538F0840AD72CB6006A81D1 /* DOMRanges.h */,
                                BC1A37A7097C715F0019F3D8 /* DOMStylesheets.h */,
                                BC1A37A8097C715F0019F3D8 /* DOMTraversal.h */,
+                               FED13D260CEA91DF00D89466 /* DOMUIKitExtensions.h */,
+                               FED13D270CEA91DF00D89466 /* DOMUIKitExtensions.mm */,
                                BC1A37A9097C715F0019F3D8 /* DOMUtility.mm */,
                                BC1A37AA097C715F0019F3D8 /* DOMViews.h */,
                                1A1D137E0A5325520064BF5F /* DOMXPath.h */,
                BCCE58B41061E925008FB35A /* Constructors */ = {
                        isa = PBXGroup;
                        children = (
+                               CE261694187E6469007955F3 /* ios */,
                                BC6C49F10D7DBA0500FFA558 /* JSImageConstructor.cpp */,
                                BC6C49F20D7DBA0500FFA558 /* JSImageConstructor.h */,
                        );
                        path = mediasource;
                        sourceTree = "<group>";
                };
+               CE261694187E6469007955F3 /* ios */ = {
+                       isa = PBXGroup;
+                       children = (
+                               A1DE71301861322200734192 /* TouchConstructors.cpp */,
+                       );
+                       path = ios;
+                       sourceTree = "<group>";
+               };
+               CE26169D187E6554007955F3 /* airplay */ = {
+                       isa = PBXGroup;
+                       children = (
+                               A5DEBD9F16FB908700836FE0 /* WebKitPlaybackTargetAvailabilityEvent.cpp */,
+                               A5DEBDA016FB908700836FE0 /* WebKitPlaybackTargetAvailabilityEvent.h */,
+                               A5DEBDA116FB908700836FE0 /* WebKitPlaybackTargetAvailabilityEvent.idl */,
+                       );
+                       path = airplay;
+                       sourceTree = "<group>";
+               };
+               CE2616A4187E65C1007955F3 /* ios */ = {
+                       isa = PBXGroup;
+                       children = (
+                               A1DE712B18612AC100734192 /* TouchEvents.cpp */,
+                       );
+                       path = ios;
+                       sourceTree = "<group>";
+               };
                CE79D68617F220ED00815C00 /* ios */ = {
                        isa = PBXGroup;
                        children = (
                F523D32402DE4478018635CA /* dom */ = {
                        isa = PBXGroup;
                        children = (
+                               CE2616A4187E65C1007955F3 /* ios */,
                                E1C4DE6D0EA75C650023CCD6 /* ActiveDOMObject.cpp */,
                                E1C4DE680EA75C1E0023CCD6 /* ActiveDOMObject.h */,
                                A8C4A7FC09D563270003AC8D /* Attr.cpp */,
                                856C8AE40A912649005C687B /* DOMObject.h in Headers */,
                                0705851317FA7107005F2BCB /* JSMediaStreamCapabilities.h in Headers */,
                                BC53DA601143141A000D817E /* DOMObjectHashTableMap.h in Headers */,
+                               FED13D2A0CEA91DF00D89466 /* DOMUIKitExtensions.h in Headers */,
                                85C7F5D00AAFB8D9004014DD /* DOMOverflowEvent.h in Headers */,
                                85989DCF0ACC8BBD00A0BC51 /* DOMOverflowEventInternal.h in Headers */,
                                E1284BD61044A01E00EAEB52 /* DOMPageTransitionEvent.h in Headers */,
                                F55B3DD01251F12D003EF269 /* ResetInputType.h in Headers */,
                                514BC843161CF05C004D52F4 /* ResourceBuffer.h in Headers */,
                                7EE6846A12D26E3800E79415 /* ResourceError.h in Headers */,
+                               D0BD4F5D1408850F006839B6 /* DictationCommandIOS.h in Headers */,
                                934F713C0D5A6F1900018D69 /* ResourceErrorBase.h in Headers */,
                                514C76790CE923A1007EF3CD /* ResourceHandle.h in Headers */,
                                26FAE4CD1852E3A5004C8C46 /* ResourceHandleCFURLConnectionDelegate.h in Headers */,
                                F5A154281279534D00D0B0C0 /* ValidationMessage.h in Headers */,
                                F513A3EA15FF4841001526DB /* ValidationMessageClient.h in Headers */,
                                15C7708D100D3C6B005BA267 /* ValidityState.h in Headers */,
+                               A5DEBDA416FB908700836FE0 /* WebKitPlaybackTargetAvailabilityEvent.h in Headers */,
                                FD3160AF12B026F700C1A359 /* VectorMath.h in Headers */,
                                BCA257151293C010007A263D /* VerticalPositionCache.h in Headers */,
                                BE88E0DF1715D2A200658D98 /* VideoTrack.h in Headers */,
                        isa = PBXResourcesBuildPhase;
                        buildActionMask = 2147483647;
                        files = (
+                               D02B64B214089E56006EFA21 /* DictationPhraseWithAlternativesDot.png in Resources */,
                                46F9D5DD0B0D60170028EE36 /* aliasCursor.png in Resources */,
+                               D02B64B314089E56006EFA21 /* DictationPhraseWithAlternativesDot@2x.png in Resources */,
                                46D4F2490AF97E810035385A /* cellCursor.png in Resources */,
                                93153BDE141959F400FCF5BE /* deleteButton.png in Resources */,
+                               BE8C753110681324001E93F5 /* SpellingDot.png in Resources */,
                                93153BCD1417FBBF00FCF5BE /* deleteButton@2x.png in Resources */,
                                93153BE014195A2800FCF5BE /* deleteButtonPressed.png in Resources */,
                                93153BCF1417FBDB00FCF5BE /* deleteButtonPressed@2x.png in Resources */,
                                85136C990AED665900F90A3D /* eastResizeCursor.png in Resources */,
                                85136C9A0AED665900F90A3D /* eastWestResizeCursor.png in Resources */,
                                85136C9B0AED665900F90A3D /* helpCursor.png in Resources */,
+                               01E6C2E41194B2820050821C /* SpellingDot@2x.png in Resources */,
                                7CC7E3D717208C0F003C5277 /* IDNScriptWhiteList.txt in Resources */,
                                93153BE414195B2A00FCF5BE /* inputSpeech.png in Resources */,
                                2D9F0E1314FF1CBF00BA0FF7 /* linearSRGB.icc in Resources */,
                                BC64B4D70CB4298A005F2B62 /* CSSFontFaceSource.cpp in Sources */,
                                BC64B4D90CB4298A005F2B62 /* CSSFontFaceSrcValue.cpp in Sources */,
                                4A6E9FC313C17D1D0046A7F8 /* CSSFontFeatureValue.cpp in Sources */,
+                               A5DEBDA316FB908700836FE0 /* WebKitPlaybackTargetAvailabilityEvent.cpp in Sources */,
                                BC64B4DB0CB4298A005F2B62 /* CSSFontSelector.cpp in Sources */,
                                A80E6CF10A1989CA007FB8C5 /* CSSFontValue.cpp in Sources */,
                                BC02A6460E09AAE9004B6D2B /* CSSFunctionValue.cpp in Sources */,
                                97205AB51239291000B17380 /* ImageDocument.cpp in Sources */,
                                F55B3DC11251F12D003EF269 /* ImageInputType.cpp in Sources */,
                                51D719E6181106E00016DC51 /* IDBOpenDBRequest.cpp in Sources */,
+                               FED13D2B0CEA91DF00D89466 /* DOMUIKitExtensions.mm in Sources */,
                                089582550E857A7E00F82C83 /* ImageLoader.cpp in Sources */,
                                B275357B0B053814002CE64F /* ImageMac.mm in Sources */,
                                2D5A592F152525230036EE51 /* ImageOrientation.cpp in Sources */,
                                1A494EDE0A123F4C00FDAFC1 /* JSDocumentFragment.cpp in Sources */,
                                65DF31F509D1CC60000BE325 /* JSDocumentType.cpp in Sources */,
                                1AC2260C0DB69F190089B669 /* JSDOMApplicationCache.cpp in Sources */,
+                               A1DE712D18612AC100734192 /* TouchEvents.cpp in Sources */,
                                93B70D6309EB0C7C009D8468 /* JSDOMBinding.cpp in Sources */,
                                BC60D7C00D29A46300B9918F /* JSDOMCoreException.cpp in Sources */,
                                40ECAE8116B8B68A00C36103 /* JSDOMError.cpp in Sources */,
                                BC06ED060BFD5BAE00856E9D /* JSHTMLTableSectionElement.cpp in Sources */,
                                D6489D25166FFCF1007C031B /* JSHTMLTemplateElement.cpp in Sources */,
                                D6F7960D166FFECE0076DD18 /* JSHTMLTemplateElementCustom.cpp in Sources */,
+                               A1DE71321861322200734192 /* TouchConstructors.cpp in Sources */,
                                A80E7E9E0A1A83E3007FB8C5 /* JSHTMLTextAreaElement.cpp in Sources */,
                                A80E7B130A19D606007FB8C5 /* JSHTMLTitleElement.cpp in Sources */,
                                070756D314239A4E00414161 /* JSHTMLTrackElement.cpp in Sources */,
                                1AB7FC780A8B92EC00D9D37B /* XPathParser.cpp in Sources */,
                                4476531B133170990006B789 /* SSLKeyGeneratorIOS.cpp in Sources */,
                                1AB7FC7A0A8B92EC00D9D37B /* XPathPath.cpp in Sources */,
+                               D0BD4F5C1408850F006839B6 /* DictationCommandIOS.cpp in Sources */,
                                1AB7FC7C0A8B92EC00D9D37B /* XPathPredicate.cpp in Sources */,
                                1AB7FC7E0A8B92EC00D9D37B /* XPathResult.cpp in Sources */,
                                1AB7FC810A8B92EC00D9D37B /* XPathStep.cpp in Sources */,
index aabfb01..f910db6 100644 (file)
@@ -81,6 +81,12 @@ void GCController::gcTimerFired(Timer<GCController>*)
 void GCController::garbageCollectNow()
 {
     JSLockHolder lock(JSDOMWindow::commonVM());
+#if PLATFORM(IOS)
+    // If JavaScript was never run in this process, there's no need to call GC which will
+    // end up creating a VM unnecessarily.
+    if (!JSDOMWindow::commonVMExists())
+        return;
+#endif
     if (!JSDOMWindow::commonVM()->heap.isBusy())
         JSDOMWindow::commonVM()->heap.collectAllGarbage();
 }
@@ -97,6 +103,26 @@ void GCController::garbageCollectOnAlternateThreadForDebugging(bool waitUntilDon
     detachThread(threadID);
 }
 
+#if PLATFORM(IOS)
+void GCController::releaseExecutableMemory()
+{
+    JSLockHolder lock(JSDOMWindow::commonVM());
+
+    if (!JSDOMWindow::commonVMExists())
+        return;
+
+    // We shouldn't have any javascript running on our stack when this function is called. The
+    // following line asserts that.
+    ASSERT(!JSDOMWindow::commonVM()->dynamicGlobalObject);
+
+    // But be safe in release builds just in case...
+    if (JSDOMWindow::commonVM()->dynamicGlobalObject)
+        return;
+
+    JSDOMWindow::commonVM()->releaseExecutableMemory();
+}
+#endif
+
 void GCController::setJavaScriptGarbageCollectorTimerEnabled(bool enable)
 {
     JSDOMWindow::commonVM()->heap.setGarbageCollectionTimerEnabled(enable);
index 8a24cb0..fd232b0 100644 (file)
@@ -44,6 +44,9 @@ namespace WebCore {
         void garbageCollectNow(); // It's better to call garbageCollectSoon, unless you have a specific reason not to.
 
         void garbageCollectOnAlternateThreadForDebugging(bool waitUntilDone); // Used for stress testing.
+#if PLATFORM(IOS)
+        void releaseExecutableMemory();
+#endif
         void setJavaScriptGarbageCollectorTimerEnabled(bool);
         void discardAllCompiledCode();
 
index d321c57..ff76a9e 100644 (file)
@@ -58,7 +58,9 @@ public:
     
     ~JSCallbackData()
     {
+#if !PLATFORM(IOS)
         ASSERT(m_thread == currentThread());
+#endif
     }
 
     JSC::JSObject* callback() { return m_callback.get(); }
index 5004a19..2b8dd43 100644 (file)
 #include <runtime/Microtask.h>
 #include <wtf/MainThread.h>
 
+#if PLATFORM(IOS)
+#include "ChromeClient.h"
+#include "WebSafeGCActivityCallbackIOS.h"
+#include "WebSafeIncrementalSweeperIOS.h"
+#endif
+
 using namespace JSC;
 
 namespace WebCore {
@@ -110,7 +116,11 @@ bool JSDOMWindowBase::supportsProfiling(const JSGlobalObject* object)
     if (!page)
         return false;
 
+#if ENABLE(INSPECTOR)
     return page->inspectorController()->profilerEnabled();
+#else
+    return false;
+#endif // ENABLE(INSPECTOR)
 #endif
 }
 
@@ -166,7 +176,7 @@ bool JSDOMWindowBase::shouldInterruptScriptBeforeTimeout(const JSGlobalObject* o
         return true;
 
 #if PLATFORM(IOS)
-    if (page->chrome().client()->isStopping())
+    if (page->chrome().client().isStopping())
         return true;
 #endif
 
@@ -202,17 +212,44 @@ VM* JSDOMWindowBase::commonVM()
 {
     ASSERT(isMainThread());
 
+#if !PLATFORM(IOS)
     static VM* vm = 0;
+#else
+    VM*& vm = commonVMInternal();
+#endif
     if (!vm) {
         ScriptController::initializeThreading();
         vm = VM::createLeaked(LargeHeap).leakRef();
+#if PLATFORM(IOS)
+        PassOwnPtr<WebSafeGCActivityCallback> activityCallback = WebSafeGCActivityCallback::create(&vm->heap);
+        vm->heap.setActivityCallback(activityCallback);
+        PassOwnPtr<WebSafeIncrementalSweeper> incrementalSweeper = WebSafeIncrementalSweeper::create(&vm->heap);
+        vm->heap.setIncrementalSweeper(incrementalSweeper);
+        vm->makeUsableFromMultipleThreads();
+        vm->heap.machineThreads().addCurrentThread();
+#else
         vm->exclusiveThread = currentThread();
+#endif // !PLATFORM(IOS)
         initNormalWorldClientData(vm);
     }
 
     return vm;
 }
 
+#if PLATFORM(IOS)
+bool JSDOMWindowBase::commonVMExists()
+{
+    return commonVMInternal();
+}
+
+VM*& JSDOMWindowBase::commonVMInternal()
+{
+    ASSERT(isMainThread());
+    static VM* commonVM;
+    return commonVM;
+}
+#endif
+
 // JSDOMGlobalObject* is ignored, accessing a window in any context will
 // use that DOMWindow's prototype chain.
 JSValue toJS(ExecState* exec, JSDOMGlobalObject*, DOMWindow* domWindow)
index 31a3bd2..f9118f3 100644 (file)
 #include "JSSharedWorker.h"
 #endif
 
+#if ENABLE(IOS_TOUCH_EVENTS)
+#include "JSTouchConstructor.h"
+#include "JSTouchListConstructor.h"
+#endif
+
 #if ENABLE(WEB_AUDIO)
 #include "JSAudioContext.h"
 #endif
@@ -452,6 +457,18 @@ JSValue JSDOMWindow::image(ExecState* exec) const
     return getDOMConstructor<JSImageConstructor>(exec->vm(), this);
 }
 
+#if ENABLE(IOS_TOUCH_EVENTS)
+JSValue JSDOMWindow::touch(ExecState* exec) const
+{
+    return getDOMConstructor<JSTouchConstructor>(exec->vm(), this);
+}
+
+JSValue JSDOMWindow::touchList(ExecState* exec) const
+{
+    return getDOMConstructor<JSTouchListConstructor>(exec->vm(), this);
+}
+#endif
+
 // Custom functions
 
 JSValue JSDOMWindow::open(ExecState* exec)
index 65eccb3..86ddc96 100644 (file)
@@ -60,6 +60,25 @@ JSValue JSDeviceOrientationEvent::gamma(ExecState*) const
     return jsNumber(imp.orientation()->gamma());
 }
 
+#if PLATFORM(IOS)
+JSValue JSDeviceOrientationEvent::webkitCompassHeading(ExecState*) const
+{
+    DeviceOrientationEvent& imp = impl();
+    if (!imp.orientation()->canProvideCompassHeading())
+        return jsNull();
+    return jsNumber(imp.orientation()->compassHeading());
+}
+
+JSValue JSDeviceOrientationEvent::webkitCompassAccuracy(ExecState*) const
+{
+    DeviceOrientationEvent& imp = impl();
+    if (!imp.orientation()->canProvideCompassAccuracy())
+        return jsNull();
+    return jsNumber(imp.orientation()->compassAccuracy());
+}
+#endif
+
+#if !PLATFORM(IOS)
 JSValue JSDeviceOrientationEvent::absolute(ExecState*) const
 {
     DeviceOrientationEvent& imp = impl();
@@ -67,6 +86,7 @@ JSValue JSDeviceOrientationEvent::absolute(ExecState*) const
         return jsNull();
     return jsBoolean(imp.orientation()->absolute());
 }
+#endif
 
 JSValue JSDeviceOrientationEvent::initDeviceOrientationEvent(ExecState* exec)
 {
@@ -81,9 +101,17 @@ JSValue JSDeviceOrientationEvent::initDeviceOrientationEvent(ExecState* exec)
     double beta = exec->argument(4).toNumber(exec);
     bool gammaProvided = !exec->argument(5).isUndefinedOrNull();
     double gamma = exec->argument(5).toNumber(exec);
+#if PLATFORM(IOS)
+    bool compassHeadingProvided = !exec->argument(6).isUndefinedOrNull();
+    double compassHeading = exec->argument(6).toNumber(exec);
+    bool compassAccuracyProvided = !exec->argument(7).isUndefinedOrNull();
+    double compassAccuracy = exec->argument(7).toNumber(exec);
+    RefPtr<DeviceOrientationData> orientation = DeviceOrientationData::create(alphaProvided, alpha, betaProvided, beta, gammaProvided, gamma, compassHeadingProvided, compassHeading, compassAccuracyProvided, compassAccuracy);
+#else
     bool absoluteProvided = !exec->argument(6).isUndefinedOrNull();
     bool absolute = exec->argument(6).toBoolean(exec);
     RefPtr<DeviceOrientationData> orientation = DeviceOrientationData::create(alphaProvided, alpha, betaProvided, beta, gammaProvided, gamma, absoluteProvided, absolute);
+#endif
     impl().initDeviceOrientationEvent(type, bubbles, cancelable, orientation.get());
     return jsUndefined();
 }
index 99602f6..ed023db 100644 (file)
 #include <runtime/Completion.h>
 #include <wtf/MainThread.h>
 
+#if PLATFORM(IOS)
+#include "WebCoreThread.h"
+#endif
+
 namespace WebCore {
 
 class InspectorInstrumentationCookie;
index 80e21f6..d9434c0 100644 (file)
@@ -25,6 +25,7 @@
 
 #include "config.h"
 
+#if !PLATFORM(IOS)
 #if ENABLE(TOUCH_EVENTS)
 
 #include "JSTouch.h"
@@ -46,3 +47,4 @@ JSValue toJSNewlyCreated(ExecState* exec, JSDOMGlobalObject* globalObject, Touch
 } // namespace WebCore
 
 #endif // ENABLE(TOUCH_EVENTS)
+#endif // !PLATFORM(IOS)
index b60efdb..11318c0 100644 (file)
@@ -25,6 +25,7 @@
 
 #include "config.h"
 
+#if !PLATFORM(IOS)
 #if ENABLE(TOUCH_EVENTS)
 
 #include "JSTouchList.h"
@@ -46,3 +47,4 @@ JSValue toJSNewlyCreated(ExecState* exec, JSDOMGlobalObject* globalObject, Touch
 } // namespace WebCore
 
 #endif // ENABLE(TOUCH_EVENTS)
+#endif // !PLATFORM(IOS)
index 215577d..c3fb7dd 100644 (file)
@@ -148,6 +148,11 @@ void PageScriptDebugServer::didContinue(JSC::JSGlobalObject* globalObject)
 {
     // Page can be null if we are continuing because the Page closed.
     Page* page = toPage(globalObject);
+#if PLATFORM(IOS)
+    // FIXME: Can this happen in open source too, or is this iOS (multi-threaded) only?
+    if (!page)
+        return;
+#endif
     ASSERT(!page || page == m_pausedPage);
 
     m_pausedPage = 0;
index 007b032..718f888 100644 (file)
@@ -61,8 +61,10 @@ namespace WebCore {
 
 void ScriptController::initializeThreading()
 {
+#if !PLATFORM(IOS)
     JSC::initializeThreading();
     WTF::initializeMainThread();
+#endif
 }
 
 ScriptController::ScriptController(Frame& frame)
index 42aa59e..71c6a31 100644 (file)
@@ -34,6 +34,7 @@
 #include "ScriptDebugServer.h"
 
 #include "ContentSearchUtils.h"
+#include "EventLoop.h"
 #include "Frame.h"
 #include "JSDOMWindowCustom.h"
 #include "JSJavaScriptCallFrame.h"
 #include <wtf/MainThread.h>
 #include <wtf/text/WTFString.h>
 
+#if PLATFORM(IOS)
+#include "JSDOMWindowBase.h"
+#include "WebCoreThreadInternal.h"
+#endif
+
 using namespace JSC;
 
 namespace WebCore {
@@ -295,11 +301,27 @@ void ScriptDebugServer::handlePause(Debugger::ReasonForPause, JSGlobalObject* vm
 
     TimerBase::fireTimersInNestedEventLoop();
 
+#if PLATFORM(IOS)
+    // On iOS, running an EventLoop causes us to run a nested WebRunLoop.
+    // Since the WebThread is autoreleased at the end of run loop iterations
+    // we need to gracefully handle releasing and reacquiring the lock.
+    ASSERT(WebThreadIsLockedOrDisabled());
+    {
+        if (WebThreadIsEnabled())
+            JSC::JSLock::DropAllLocks dropAllLocks(WebCore::JSDOMWindowBase::commonVM(), JSC::JSLock::DropAllLocks::AlwaysDropLocks);
+        WebRunLoopEnableNested();
+#endif
+
     m_runningNestedMessageLoop = true;
     m_doneProcessingDebuggerEvents = false;
     runEventLoopWhilePaused();
     m_runningNestedMessageLoop = false;
 
+#if PLATFORM(IOS)
+        WebRunLoopDisableNested();
+    }
+    ASSERT(WebThreadIsLockedOrDisabled());
+#endif
     didContinue(vmEntryGlobalObject);
     dispatchFunctionToListeners(&ScriptDebugServer::dispatchDidContinue, vmEntryGlobalObject);
 }
diff --git a/Source/WebCore/bindings/js/ios/TouchConstructors.cpp b/Source/WebCore/bindings/js/ios/TouchConstructors.cpp
new file mode 100644 (file)
index 0000000..767b178
--- /dev/null
@@ -0,0 +1,33 @@
+/*
+ * Copyright (C) 2013 Apple Inc. All rights reserved.
+ *
+ * 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 INC. AND ITS CONTRIBUTORS ``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 INC. OR ITS 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.
+ */
+
+#include "config.h"
+
+#if PLATFORM(IOS) && ENABLE(TOUCH_EVENTS)
+
+#include <WebKitAdditions/JSTouchConstructor.cpp>
+#include <WebKitAdditions/JSTouchListConstructor.cpp>
+
+#endif
index 12864b9..22bd9d3 100644 (file)
 #import <JavaScriptCore/APICast.h>
 #import <wtf/HashMap.h>
 
+#if PLATFORM(IOS)
+#import "FocusController.h"
+#import "HTMLLinkElement.h"
+#import "KeyboardEvent.h"
+#import "URL.h"
+#import "MediaList.h"
+#import "MediaQueryEvaluator.h"
+#import "NodeRenderStyle.h"
+#import "Page.h"
+#import "RenderView.h"
+#import "Touch.h"
+#import "WAKAppKitStubs.h"
+#import "WAKWindow.h"
+#import "WebCoreThreadMessage.h"
+#endif
+
 using namespace JSC;
 using namespace WebCore;
 
@@ -176,8 +192,80 @@ static NSArray *kit(const Vector<IntRect>& rects)
     return array;
 }
 
+#if PLATFORM(IOS)
+static WKQuad wkQuadFromFloatQuad(const FloatQuad& inQuad)
+{
+    WKQuad  theQuad;
+    theQuad.p1 = inQuad.p1();
+    theQuad.p2 = inQuad.p2();
+    theQuad.p3 = inQuad.p3();
+    theQuad.p4 = inQuad.p4();
+    
+    return theQuad;
+}
+
+static NSArray *kit(const Vector<FloatQuad>& quads)
+{
+    size_t size = quads.size();
+    NSMutableArray *array = [NSMutableArray arrayWithCapacity:size];
+    for (size_t i = 0; i < size; ++i) {
+        WKQuadObject* quadObject = [[WKQuadObject alloc] initWithQuad:wkQuadFromFloatQuad(quads[i])];
+        [array addObject:quadObject];
+        [quadObject release];
+    }
+    return array;
+}
+
+static inline float min4(float a, float b, float c, float d)
+{
+    return std::min(std::min(a, b), std::min(c, d));
+}
+
+static inline float max4(float a, float b, float c, float d)
+{
+    return std::max(std::max(a, b), std::max(c, d));
+}
+
+static inline WKQuad emptyQuad()
+{
+    WKQuad zeroQuad = { CGPointZero, CGPointZero, CGPointZero, CGPointZero };
+    return zeroQuad;
+}
+#endif
+
 } // namespace WebCore
 
+#if PLATFORM(IOS)
+@implementation WKQuadObject
+
+- (id)initWithQuad:(WKQuad)quad
+{
+    if ((self = [super init]))
+    {
+        _quad = quad;
+    }
+    return self;
+}
+
+- (WKQuad)quad
+{
+    return _quad;
+}
+
+- (CGRect)boundingBox
+{
+    float left      = WebCore::min4(_quad.p1.x, _quad.p2.x, _quad.p3.x, _quad.p4.x);
+    float top       = WebCore::min4(_quad.p1.y, _quad.p2.y, _quad.p3.y, _quad.p4.y);
+    
+    float right     = WebCore::max4(_quad.p1.x, _quad.p2.x, _quad.p3.x, _quad.p4.x);
+    float bottom    = WebCore::max4(_quad.p1.y, _quad.p2.y, _quad.p3.y, _quad.p4.y);
+    
+    return CGRectMake(left, top, right - left, bottom - top);
+}
+
+@end
+#endif
+
 @implementation DOMNode (WebCoreInternal)
 
 #pragma clang diagnostic push
@@ -263,13 +351,21 @@ id <DOMEventTarget> kit(WebCore::EventTarget* eventTarget)
 
 @implementation DOMNode (DOMNodeExtensions)
 
+#if PLATFORM(IOS)
+- (CGRect)boundingBox
+#else
 - (NSRect)boundingBox
+#endif
 {
     // FIXME: Could we move this function to WebCore::Node and autogenerate?
     core(self)->document().updateLayoutIgnorePendingStylesheets();
     WebCore::RenderObject* renderer = core(self)->renderer();
     if (!renderer)
+#if PLATFORM(IOS)
+        return CGRectZero;
+#else
         return NSZeroRect;
+#endif
     return renderer->absoluteBoundingBoxRect();
 }
 
@@ -278,10 +374,180 @@ id <DOMEventTarget> kit(WebCore::EventTarget* eventTarget)
     return [self textRects];
 }
 
+#if PLATFORM(IOS)
+// quad in page coordinates, taking transforms into account. c.f. - (NSRect)boundingBox;
+- (WKQuad)absoluteQuad
+{
+    return [self absoluteQuadAndInsideFixedPosition:0];
+}
+
+- (WKQuad)absoluteQuadAndInsideFixedPosition:(BOOL *)insideFixed
+{
+    core(self)->document().updateLayoutIgnorePendingStylesheets();
+    WebCore::RenderObject *renderer = core(self)->renderer();
+    if (renderer) {
+        Vector<FloatQuad> quads;
+        bool wasFixed = false;
+        renderer->absoluteQuads(quads, &wasFixed);
+        if (insideFixed)
+            *insideFixed = wasFixed;
+
+        if (quads.size() == 0)
+            return WebCore::emptyQuad();
+        
+        if (quads.size() == 1)
+            return wkQuadFromFloatQuad(quads[0]);
+
+        FloatRect boundingRect = quads[0].boundingBox();
+        for (size_t i = 1; i < quads.size(); ++i)
+            boundingRect.unite(quads[i].boundingBox());
+
+        return wkQuadFromFloatQuad(boundingRect);
+    }
+
+    return WebCore::emptyQuad();
+}
+
+// this method is like - (CGRect)boundingBox, but it accounts for for transforms
+- (CGRect)boundingBoxUsingTransforms
+{
+    core(self)->document().updateLayoutIgnorePendingStylesheets();
+    WebCore::RenderObject* renderer = core(self)->renderer();
+    if (!renderer)
+        return CGRectZero;
+    return renderer->absoluteBoundingBoxRect(true);
+}
+
+// returns array of WKQuadObject
+- (NSArray *)lineBoxQuads
+{
+    core(self)->document().updateLayoutIgnorePendingStylesheets();
+    WebCore::RenderObject *renderer = core(self)->renderer();
+    if (renderer) {
+        Vector<WebCore::FloatQuad> quads;
+        renderer->absoluteQuads(quads);
+        return kit(quads);
+    }
+    return nil;
+}
+
+- (Element *)_linkElement
+{
+    WebCore::Node* node = core(self);
+    
+    while (node) {
+        if (node->isLink())
+            return static_cast<WebCore::Element*>(node);
+        node = node->parentNode();
+    }
+    
+    return 0;
+}
+
+- (NSURL *)hrefURL
+{
+    Element *link= [self _linkElement];
+    if (link)
+        return link->document().completeURL(stripLeadingAndTrailingHTMLSpaces(link->getAttribute(HTMLNames::hrefAttr)));
+    
+    return nil;
+}
+
+- (NSString *)hrefTarget
+{
+    Element *target = [self _linkElement];
+    
+    if(target) return target->getAttribute(HTMLNames::targetAttr);
+    
+    return nil;
+}
+
+- (CGRect)hrefFrame
+{
+    RenderObject *renderer = [self _linkElement]->renderer();
+    
+    if(renderer) return renderer->absoluteBoundingBoxRect();
+    
+    return NSZeroRect;
+}
+
+- (NSString *)hrefLabel
+{
+    Element *link= [self _linkElement];
+    
+    if (!link) return nil;
+    
+    return link->textContent();
+}
+
+- (NSString *)hrefTitle
+{
+    Element *link= [self _linkElement];
+    
+    if (!link) return nil;
+    
+    return link->document().displayStringModifiedByEncoding(static_cast<HTMLElement *>(link)->title());
+}
+
+- (CGRect)boundingFrame
+{
+    return [self boundingBox];
+}
+
+- (WKQuad)innerFrameQuad       // takes transforms into account
+{
+    core(self)->document().updateLayoutIgnorePendingStylesheets();
+    RenderObject* renderer = core(self)->renderer();
+    if (!renderer)
+        return emptyQuad();
+
+    RenderStyle& style = renderer->style();
+    IntRect boundingBox = renderer->absoluteBoundingBoxRect(true /* use transforms*/);
+
+    boundingBox.move(style.borderLeftWidth(), style.borderTopWidth());
+    boundingBox.setWidth(boundingBox.width() - style.borderLeftWidth() - style.borderRightWidth());
+    boundingBox.setHeight(boundingBox.height() - style.borderBottomWidth() - style.borderTopWidth());
+
+    // FIXME: This function advertises returning a quad, but it actually returns a bounding box (so there is no rotation, for instance).
+    return wkQuadFromFloatQuad(FloatQuad(boundingBox));
+}
+
+- (float)computedFontSize
+{
+    WebCore::Node *node = core(self);
+    RenderStyle *style = node->renderStyle();
+    if (!style)
+        return 0.0f;
+    return style->fontDescription().computedSize();
+}
+
+- (DOMNode *)nextFocusNode
+{
+    Page *page = core(self)->document().page();
+    if (!page)
+        return nil;
+
+    RefPtr<KeyboardEvent> key = KeyboardEvent::create();
+    return kit(page->focusController().nextFocusableElement(FocusNavigationScope::focusNavigationScopeOf(&core(self)->document()), core(self), key.get()));
+}
+
+- (DOMNode *)previousFocusNode
+{
+    Page *page = core(self)->document().page();
+    if (!page)
+        return nil;
+
+    RefPtr<KeyboardEvent> key = KeyboardEvent::create();
+    return kit(page->focusController().previousFocusableElement(FocusNavigationScope::focusNavigationScopeOf(&core(self)->document()), core(self), key.get()));
+}
+
+#endif // PLATFORM(IOS)
+
 @end
 
 @implementation DOMNode (DOMNodeExtensionsPendingPublic)
 
+#if !PLATFORM(IOS)
 - (NSImage *)renderedImage
 {
     // FIXME: Could we move this function to WebCore::Node and autogenerate?
@@ -291,6 +557,7 @@ id <DOMEventTarget> kit(WebCore::EventTarget* eventTarget)
         return nil;
     return [createDragImageForNode(*frame, *node).leakRef() autorelease];
 }
+#endif
 
 - (NSArray *)textRects
 {
@@ -321,14 +588,22 @@ id <DOMEventTarget> kit(WebCore::EventTarget* eventTarget)
 
 @implementation DOMRange (DOMRangeExtensions)
 
+#if PLATFORM(IOS)
+- (CGRect)boundingBox
+#else
 - (NSRect)boundingBox
+#endif
 {
     // FIXME: The call to updateLayoutIgnorePendingStylesheets should be moved into WebCore::Range.
     core(self)->ownerDocument().updateLayoutIgnorePendingStylesheets();
     return core(self)->boundingBox();
 }
 
+#if !PLATFORM(IOS)
 - (NSImage *)renderedImageForcingBlackText:(BOOL)forceBlackText
+#else
+- (CGImageRef)renderedImageForcingBlackText:(BOOL)forceBlackText
+#endif
 {
     WebCore::Range* range = core(self);
     WebCore::Frame* frame = range->ownerDocument().frame();
@@ -360,6 +635,7 @@ id <DOMEventTarget> kit(WebCore::EventTarget* eventTarget)
 
 @implementation DOMElement (DOMElementAppKitExtensions)
 
+#if !PLATFORM(IOS)
 - (NSImage*)image
 {
     // FIXME: Could we move this function to WebCore::Node and autogenerate?
@@ -371,11 +647,13 @@ id <DOMEventTarget> kit(WebCore::EventTarget* eventTarget)
         return nil;
     return cachedImage->imageForRenderer(toRenderImage(renderer))->getNSImage();
 }
+#endif
 
 @end
 
 @implementation DOMElement (WebPrivate)
 
+#if !PLATFORM(IOS)
 - (NSFont *)_font
 {
     // FIXME: Could we move this function to WebCore::Element and autogenerate?
@@ -384,7 +662,17 @@ id <DOMEventTarget> kit(WebCore::EventTarget* eventTarget)
         return nil;
     return renderer->style().font().primaryFont()->getNSFont();
 }
+#else
+- (CTFontRef)_font
+{
+    RenderObject* renderer = core(self)->renderer();
+    if (!renderer)
+        return nil;
+    return renderer->style().font().primaryFont()->getCTFont();
+}
+#endif
 
+#if !PLATFORM(IOS)
 - (NSData *)_imageTIFFRepresentation
 {
     // FIXME: Could we move this function to WebCore::Element and autogenerate?
@@ -396,6 +684,7 @@ id <DOMEventTarget> kit(WebCore::EventTarget* eventTarget)
         return nil;
     return (NSData *)cachedImage->imageForRenderer(renderer)->getTIFFRepresentation();
 }
+#endif
 
 - (NSURL *)_getURLAttribute:(NSString *)name
 {
@@ -415,6 +704,49 @@ id <DOMEventTarget> kit(WebCore::EventTarget* eventTarget)
 
 @end
 
+#if PLATFORM(IOS)
+@implementation DOMHTMLLinkElement (WebPrivate)
+- (BOOL)_mediaQueryMatchesForOrientation:(int)orientation
+{
+    Document& document = static_cast<HTMLLinkElement*>(core(self))->document();
+    FrameView* frameView = document.frame() ? document.frame()->view() : 0;
+    if (!frameView)
+        return false;
+    int layoutWidth = frameView->layoutWidth();
+    int layoutHeight = frameView->layoutHeight();
+    IntSize savedFixedLayoutSize = frameView->fixedLayoutSize();
+    bool savedUseFixedLayout = frameView->useFixedLayout();
+    if ((orientation == WebMediaQueryOrientationPortrait && layoutWidth > layoutHeight) ||
+        (orientation == WebMediaQueryOrientationLandscape && layoutWidth < layoutHeight)) {
+        // temporarily swap the orientation for the evaluation
+        frameView->setFixedLayoutSize(IntSize(layoutHeight, layoutWidth));
+        frameView->setUseFixedLayout(true);
+    }
+        
+    bool result = [self _mediaQueryMatches];
+
+    frameView->setFixedLayoutSize(savedFixedLayoutSize);
+    frameView->setUseFixedLayout(savedUseFixedLayout);
+
+    return result;
+}
+
+- (BOOL)_mediaQueryMatches
+{
+    HTMLLinkElement* link = static_cast<HTMLLinkElement*>(core(self));
+    String media = link->getAttribute(HTMLNames::mediaAttr);
+    if (media.isEmpty())
+        return true;
+    Document& document = link->document();
+
+    RefPtr<MediaQuerySet> mediaQuerySet = MediaQuerySet::createAllowingDescriptionSyntax(media);
+    MediaQueryEvaluator screenEval("screen", document.frame(), document.renderView() ? &document.renderView()->style() : 0);
+
+    return screenEval.eval(mediaQuerySet.get());
+}
+@end
+#endif
+
 //------------------------------------------------------------------------------------------
 // DOMRange
 
@@ -442,12 +774,14 @@ id <DOMEventTarget> kit(WebCore::EventTarget* eventTarget)
 
 @implementation DOMRGBColor (WebPrivate)
 
+#if !PLATFORM(IOS)
 // FIXME: This should be removed as soon as all internal Apple uses of it have been replaced with
 // calls to the public method - (NSColor *)color.
 - (NSColor *)_color
 {
     return [self color];
 }
+#endif
 
 @end
 
index 4e2d825..7ecddfb 100644 (file)
 #import <WebCore/DOMProgressEvent.h>
 #import <WebCore/DOMUIEvent.h>
 #import <WebCore/DOMWheelEvent.h>
+
+#if defined(ENABLE_IOS_TOUCH_EVENTS) && ENABLE_IOS_TOUCH_EVENTS
+#import <WebCore/DOMTouchEvent.h>
+#endif
+
+#if defined(ENABLE_IOS_GESTURE_EVENTS) && ENABLE_IOS_GESTURE_EVENTS
+#import <WebCore/DOMGestureEvent.h>
+#endif
index bdd17c6..4e9fb8b 100644 (file)
 #import "Event.h"
 #import "EventNames.h"
 
+#if ENABLE(TOUCH_EVENTS)
+#import "DOMTouchEvent.h"
+#endif
+
+#if ENABLE(IOS_GESTURE_EVENTS)
+#import "DOMGestureEvent.h"
+#endif
+
 using WebCore::eventNames;
 
 Class kitClass(WebCore::Event* impl)
@@ -54,7 +62,15 @@ Class kitClass(WebCore::Event* impl)
         if (desiredInterface == WebCore::TextEventInterfaceType)
             return [DOMTextEvent class];
         if (desiredInterface == WebCore::WheelEventInterfaceType)
-            return [DOMWheelEvent class];
+            return [DOMWheelEvent class];        
+#if PLATFORM(IOS) && ENABLE(TOUCH_EVENTS)
+        if (desiredInterface == WebCore::TouchEventInterfaceType) 
+            return [DOMTouchEvent class];
+#endif
+#if ENABLE(IOS_GESTURE_EVENTS)
+        if (desiredInterface == WebCore::GestureEventInterfaceType)
+            return [DOMGestureEvent class];
+#endif
         return [DOMUIEvent class];
     }
 
index cec3560..ca7d872 100644 (file)
 #import <WebCore/DOMRGBColor.h>
 #import <WebCore/DOMRange.h>
 
+#if defined(TARGET_OS_EMBEDDED) && TARGET_OS_EMBEDDED
+#import <CoreGraphics/CoreGraphics.h>
+#endif
+
 @class NSArray;
 @class NSImage;
 @class NSURL;
 
+
+#if defined(TARGET_OS_EMBEDDED) && TARGET_OS_EMBEDDED
+@interface DOMHTMLElement (DOMHTMLElementExtensions)
+- (int)scrollXOffset;
+- (int)scrollYOffset;
+- (void)setScrollXOffset:(int)x scrollYOffset:(int)y;
+- (void)setScrollXOffset:(int)x scrollYOffset:(int)y adjustForIOSCaret:(BOOL)adjustForIOSCaret;
+- (void)absolutePosition:(int *)x :(int *)y :(int *)w :(int *)h;
+@end
+#endif
+
+#if defined(TARGET_OS_EMBEDDED) && TARGET_OS_EMBEDDED
+typedef struct _WKQuad {
+    CGPoint p1;
+    CGPoint p2;
+    CGPoint p3;
+    CGPoint p4;
+} WKQuad;
+
+@interface WKQuadObject : NSObject
+{
+    WKQuad  _quad;
+}
+
+- (id)initWithQuad:(WKQuad)quad;
+- (WKQuad)quad;
+- (CGRect)boundingBox;
+@end
+#endif
+
 @interface DOMNode (DOMNodeExtensions)
+#if defined(TARGET_OS_EMBEDDED) && TARGET_OS_EMBEDDED
+- (CGRect)boundingBox;
+#else
 - (NSRect)boundingBox WEBKIT_AVAILABLE_MAC(10_5);
+#endif
 - (NSArray *)lineBoxRects WEBKIT_AVAILABLE_MAC(10_5);
+
+#if defined(TARGET_OS_EMBEDDED) && TARGET_OS_EMBEDDED
+- (CGRect)boundingBoxUsingTransforms; // takes transforms into account
+
+- (WKQuad)absoluteQuad;
+- (WKQuad)absoluteQuadAndInsideFixedPosition:(BOOL *)insideFixed;
+- (NSArray *)lineBoxQuads;      // returns array of WKQuadObject
+
+- (NSURL *)hrefURL;
+- (CGRect)hrefFrame;
+- (NSString *)hrefTarget;
+- (NSString *)hrefLabel;
+- (NSString *)hrefTitle;
+- (CGRect)boundingFrame;
+- (WKQuad)innerFrameQuad;       // takes transforms into account
+- (float)computedFontSize;
+- (DOMNode *)nextFocusNode;
+- (DOMNode *)previousFocusNode;
+#endif
 @end
 
 @interface DOMElement (DOMElementAppKitExtensions)
+#if !defined(TARGET_OS_EMBEDDED) || !TARGET_OS_EMBEDDED
 - (NSImage *)image WEBKIT_AVAILABLE_MAC(10_5);
+#endif
 @end
 
 @interface DOMHTMLDocument (DOMHTMLDocumentExtensions)
 - (DOMDocumentFragment *)createDocumentFragmentWithMarkupString:(NSString *)markupString baseURL:(NSURL *)baseURL WEBKIT_AVAILABLE_MAC(10_5);
 - (DOMDocumentFragment *)createDocumentFragmentWithText:(NSString *)text WEBKIT_AVAILABLE_MAC(10_5);
 @end
+
+#if defined(TARGET_OS_EMBEDDED) && TARGET_OS_EMBEDDED
+@interface DOMHTMLAreaElement (DOMHTMLAreaElementExtensions)
+- (CGRect)boundingFrameForOwner:(DOMNode *)anOwner;
+@end
+
+@interface DOMHTMLSelectElement (DOMHTMLSelectElementExtensions)
+- (DOMNode *)listItemAtIndex:(int)anIndex;
+@end
+#endif
index c333514..ba41122 100644 (file)
 #import "Settings.h"
 #import "markup.h"
 
+#if PLATFORM(IOS)
+#import "Autocapitalize.h"
+#import "DOMHTMLElementInternal.h"
+#import "HTMLTextFormControlElement.h"
+#import "JSMainThreadExecState.h"
+#import "RenderLayer.h"
+#import "WAKWindow.h"
+#import "WebCoreThreadMessage.h"
+#endif
+
+#if PLATFORM(IOS)
+
+using namespace WebCore;
+
+@implementation DOMHTMLElement (DOMHTMLElementExtensions)
+
+- (int)scrollXOffset
+{
+    RenderObject *renderer = core(self)->renderer();
+    if (!renderer)
+        return 0;
+
+    if (!renderer->isRenderBlockFlow())
+        renderer = renderer->containingBlock();
+
+    if (!renderer->isBox() || !renderer->hasOverflowClip())
+        return 0;
+
+    RenderBox *renderBox = toRenderBox(renderer);
+    return renderBox->layer()->scrollXOffset();
+}
+
+- (int)scrollYOffset
+{
+    RenderObject *renderer = core(self)->renderer();
+    if (!renderer)
+        return 0;
+
+    if (!renderer->isRenderBlockFlow())
+        renderer = renderer->containingBlock();
+    if (!renderer->isBox() || !renderer->hasOverflowClip())
+        return 0;
+
+    RenderBox *renderBox = toRenderBox(renderer);
+    return renderBox->layer()->scrollYOffset();
+}
+
+- (void)setScrollXOffset:(int)x scrollYOffset:(int)y
+{
+    [self setScrollXOffset:x scrollYOffset:y adjustForIOSCaret:NO];
+}
+
+- (void)setScrollXOffset:(int)x scrollYOffset:(int)y adjustForIOSCaret:(BOOL)adjustForIOSCaret
+{
+    RenderObject *renderer = core(self)->renderer();
+    if (!renderer)
+        return;
+
+    if (!renderer->isRenderBlockFlow())
+        renderer = renderer->containingBlock();
+    if (!renderer->hasOverflowClip() || !renderer->isBox())
+        return;
+
+    RenderBox *renderBox = toRenderBox(renderer);
+    RenderLayer *layer = renderBox->layer();
+    if (adjustForIOSCaret)
+        layer->setAdjustForIOSCaretWhenScrolling(true);
+    layer->scrollToOffset(IntSize(x, y));
+    if (adjustForIOSCaret)
+        layer->setAdjustForIOSCaretWhenScrolling(false);
+}
+
+- (void)absolutePosition:(int *)x :(int *)y :(int *)w :(int *)h {
+    RenderBox *renderer = core(self)->renderBox();
+    if (renderer) {
+        if (w)
+            *w = renderer->width();
+        if (h)
+            *h = renderer->width();
+        if (x && y) {
+            FloatPoint floatPoint(*x, *y);
+            renderer->localToAbsolute(floatPoint);
+            IntPoint point = roundedIntPoint(floatPoint);
+            *x = point.x();
+            *y = point.y();
+        }
+    }
+}
+
+@end
+
+#endif // PLATFORM(IOS)
+
 //------------------------------------------------------------------------------------------
 // DOMHTMLDocument
 
     return core(self)->isTextField();
 }
 
+#if !PLATFORM(IOS)
 - (NSRect)_rectOnScreen
 {
     // Returns bounding rect of text field, in screen coordinates.
 #pragma clang diagnostic pop
     return result;
 }
+#endif
 
 - (void)_replaceCharactersInRange:(NSRange)targetRange withString:(NSString *)replacementString selectingFromIndex:(int)index
 {
 
 @end
 
+#if PLATFORM(IOS)
+@implementation DOMHTMLInputElement (AutocapitalizeAdditions)
+
+- (WebAutocapitalizeType)_autocapitalizeType
+{
+    WebCore::HTMLInputElement* inputElement = core(self);
+    return static_cast<WebAutocapitalizeType>(inputElement->autocapitalizeType());
+}
+
+@end
+
+@implementation DOMHTMLTextAreaElement (AutocapitalizeAdditions)
+
+- (WebAutocapitalizeType)_autocapitalizeType
+{
+    WebCore::HTMLTextAreaElement* textareaElement = core(self);
+    return static_cast<WebAutocapitalizeType>(textareaElement->autocapitalizeType());
+}
+
+@end
+
+@implementation DOMHTMLInputElement (WebInputChangeEventAdditions)
+
+- (void)setValueWithChangeEvent:(NSString *)newValue
+{
+    WebCore::JSMainThreadNullState state;
+    core(self)->setValue(newValue, DispatchInputAndChangeEvent);
+}
+
+- (void)setValueAsNumberWithChangeEvent:(double)newValueAsNumber
+{
+    WebCore::JSMainThreadNullState state;
+    WebCore::ExceptionCode ec = 0;
+    core(self)->setValueAsNumber(newValueAsNumber, ec, DispatchInputAndChangeEvent);
+}
+
+@end
+#endif
+
 Class kitClass(WebCore::HTMLCollection* collection)
 {
     if (collection->type() == WebCore::SelectOptions)
index d22b318..10c48e1 100644 (file)
@@ -45,6 +45,9 @@ namespace JSC {
 namespace WebCore {
     class NodeFilter;
     class XPathNSResolver;
+#if ENABLE(TOUCH_EVENTS)
+    class Touch;
+#endif
 }
 
 @interface DOMNodeFilter : DOMObject <DOMNodeFilter>
index 34104b9..8132698 100644 (file)
 #import "WebScriptObjectPrivate.h"
 #import "runtime_root.h"
 
+#if PLATFORM(IOS)
+#define NEEDS_WRAPPER_CACHE_LOCK 1
+#endif
+
 //------------------------------------------------------------------------------------------
 // Wrapping WebCore implementation objects
 
 static NSMapTable* DOMWrapperCache;
+    
+#ifdef NEEDS_WRAPPER_CACHE_LOCK
+static Mutex& wrapperCacheLock()
+{
+    DEFINE_STATIC_LOCAL(Mutex, wrapperCacheMutex, ());
+    return wrapperCacheMutex;
+}
+#endif
 
 #if COMPILER(CLANG)
 #pragma clang diagnostic push
@@ -57,6 +69,9 @@ NSMapTable* createWrapperCache()
 
 NSObject* getDOMWrapper(DOMObjectInternal* impl)
 {
+#ifdef NEEDS_WRAPPER_CACHE_LOCK
+    MutexLocker locker(wrapperCacheLock());
+#endif
     if (!DOMWrapperCache)
         return nil;
     return static_cast<NSObject*>(NSMapGet(DOMWrapperCache, impl));
@@ -64,6 +79,9 @@ NSObject* getDOMWrapper(DOMObjectInternal* impl)
 
 void addDOMWrapper(NSObject* wrapper, DOMObjectInternal* impl)
 {
+#ifdef NEEDS_WRAPPER_CACHE_LOCK
+    MutexLocker locker(wrapperCacheLock());
+#endif
     if (!DOMWrapperCache)
         DOMWrapperCache = createWrapperCache();
     NSMapInsert(DOMWrapperCache, impl, wrapper);
@@ -71,6 +89,9 @@ void addDOMWrapper(NSObject* wrapper, DOMObjectInternal* impl)
 
 void removeDOMWrapper(DOMObjectInternal* impl)
 {
+#ifdef NEEDS_WRAPPER_CACHE_LOCK
+    MutexLocker locker(wrapperCacheLock());
+#endif
     if (!DOMWrapperCache)
         return;
     NSMapRemove(DOMWrapperCache, impl);
index 44a8bd6..ff4312c 100644 (file)
 
 #import <WebCore/DOM.h>
 
+#if defined(TARGET_OS_EMBEDDED) && TARGET_OS_EMBEDDED
+#import <WebCore/WebAutocapitalize.h>
+#import <CoreText/CoreText.h>
+#endif
+
 @interface DOMNode (DOMNodeExtensionsPendingPublic)
+#if !defined(TARGET_OS_EMBEDDED) || !TARGET_OS_EMBEDDED
 - (NSImage *)renderedImage;
+#endif
 - (NSArray *)textRects;
 @end
 
@@ -38,7 +45,9 @@
 // FIXME: this should be removed as soon as all internal Apple uses of it have been replaced with
 // calls to the public method - (NSColor *)color.
 @interface DOMRGBColor (WebPrivate)
+#if !defined(TARGET_OS_EMBEDDED) || !TARGET_OS_EMBEDDED
 - (NSColor *)_color;
+#endif
 @end
 
 // FIXME: this should be removed as soon as all internal Apple uses of it have been replaced with
 @end
 
 @interface DOMRange (DOMRangeExtensions)
+#if defined(TARGET_OS_EMBEDDED) && TARGET_OS_EMBEDDED
+- (CGRect)boundingBox;
+#else
 - (NSRect)boundingBox;
+#endif
+#if !defined(TARGET_OS_EMBEDDED) || !TARGET_OS_EMBEDDED
 - (NSImage *)renderedImageForcingBlackText:(BOOL)forceBlackText;
+#else
+- (CGImageRef)renderedImageForcingBlackText:(BOOL)forceBlackText;
+#endif
 - (NSArray *)lineBoxRects; // Deprecated. Use textRects instead.
 - (NSArray *)textRects;
 @end
 
 @interface DOMElement (WebPrivate)
+#if !defined(TARGET_OS_EMBEDDED) || !TARGET_OS_EMBEDDED
 - (NSFont *)_font;
 - (NSData *)_imageTIFFRepresentation;
+#else
+- (CTFontRef)_font;
+#endif
 - (NSURL *)_getURLAttribute:(NSString *)name;
 - (BOOL)isFocused;
 @end
 @interface DOMHTMLInputElement (FormAutoFillTransition)
 - (BOOL)_isAutofilled;
 - (BOOL)_isTextField;
+#if !defined(TARGET_OS_EMBEDDED) || !TARGET_OS_EMBEDDED
 - (NSRect)_rectOnScreen; // bounding box of the text field, in screen coordinates
+#endif
 - (void)_replaceCharactersInRange:(NSRange)targetRange withString:(NSString *)replacementString selectingFromIndex:(int)index;
 - (NSRange)_selectedRange;
 - (void)_setAutofilled:(BOOL)filled;
 - (void)_activateItemAtIndex:(int)index;
 - (void)_activateItemAtIndex:(int)index allowMultipleSelection:(BOOL)allowMultipleSelection;
 @end
+
+#if defined(TARGET_OS_EMBEDDED) && TARGET_OS_EMBEDDED
+enum { WebMediaQueryOrientationCurrent, WebMediaQueryOrientationPortrait, WebMediaQueryOrientationLandscape };
+@interface DOMHTMLLinkElement (WebPrivate)
+- (BOOL)_mediaQueryMatchesForOrientation:(int)orientation;
+- (BOOL)_mediaQueryMatches;
+@end
+
+// These changes are useful to get the AutocapitalizeType on particular form controls.
+@interface DOMHTMLInputElement (AutocapitalizeAdditions)
+- (WebAutocapitalizeType)_autocapitalizeType;
+@end
+
+@interface DOMHTMLTextAreaElement (AutocapitalizeAdditions)
+- (WebAutocapitalizeType)_autocapitalizeType;
+@end
+
+// These are used by Date and Time input types because the generated ObjC methods default to not dispatching events.
+@interface DOMHTMLInputElement (WebInputChangeEventAdditions)
+- (void)setValueWithChangeEvent:(NSString *)newValue;
+- (void)setValueAsNumberWithChangeEvent:(double)newValueAsNumber;
+@end
+#endif // defined(TARGET_OS_EMBEDDED) && TARGET_OS_EMBEDDED
diff --git a/Source/WebCore/bindings/objc/DOMUIKitExtensions.h b/Source/WebCore/bindings/objc/DOMUIKitExtensions.h
new file mode 100644 (file)
index 0000000..a399eed
--- /dev/null
@@ -0,0 +1,89 @@
+/*
+ * Copyright (C) 2007, 2008 Apple Inc. All Rights Reserved.
+ *
+ * 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, 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. 
+ *
+ */
+
+#if defined(TARGET_OS_EMBEDDED) && TARGET_OS_EMBEDDED
+
+#import <WebCore/DOMElement.h>
+#import <WebCore/DOMExtensions.h>
+#import <WebCore/DOMHTMLAreaElement.h>
+#import <WebCore/DOMHTMLImageElement.h>
+#import <WebCore/DOMHTMLSelectElement.h>
+#import <WebCore/DOMNode.h>
+#import <WebCore/DOMRange.h>
+
+typedef enum { 
+    // The first four match SelectionDirection.  The last two don't have WebKit counterparts because
+    // they aren't necessary until there is support vertical layout.
+    WebTextAdjustmentForward,
+    WebTextAdjustmentBackward,
+    WebTextAdjustmentRight,
+    WebTextAdjustmentLeft,
+    WebTextAdjustmentUp,
+    WebTextAdjustmentDown
+} WebTextAdjustmentDirection; 
+
+@interface DOMRange (UIKitExtensions)
+
+- (void)move:(UInt32)amount inDirection:(WebTextAdjustmentDirection)direction;
+- (void)extend:(UInt32)amount inDirection:(WebTextAdjustmentDirection)direction;
+- (DOMNode *)firstNode;
+
+@end
+
+@interface DOMNode (UIKitExtensions)
+- (NSArray *)borderRadii;
+- (NSArray *)boundingBoxes;
+- (NSArray *)absoluteQuads;     // return array of WKQuadObjects. takes transforms into account
+
+- (BOOL)containsOnlyInlineObjects;
+- (BOOL)isSelectableBlock;
+- (DOMRange *)rangeOfContainingParagraph;
+- (CGFloat)textHeight;
+- (DOMNode *)findExplodedTextNodeAtPoint:(CGPoint)point;  // A second-chance pass to look for text nodes missed by the hit test.
+@end
+
+@interface DOMHTMLAreaElement (UIKitExtensions)
+- (CGRect)boundingBoxWithOwner:(DOMNode *)anOwner;
+- (WKQuad)absoluteQuadWithOwner:(DOMNode *)anOwner;     // takes transforms into account
+- (NSArray *)boundingBoxesWithOwner:(DOMNode *)anOwner;
+- (NSArray *)absoluteQuadsWithOwner:(DOMNode *)anOwner; // return array of WKQuadObjects. takes transforms into account
+@end
+
+@interface DOMHTMLSelectElement (UIKitExtensions)
+- (unsigned)completeLength;
+- (DOMNode *)listItemAtIndex:(int)anIndex;
+@end
+
+@interface DOMHTMLImageElement (WebDOMHTMLImageElementOperationsPrivate)
+- (NSData *)dataRepresentation:(BOOL)rawImageData;
+- (NSString *)mimeType;
+@end
+
+@interface DOMElement (DOMUIKitComplexityExtensions) 
+- (int)structuralComplexityContribution; // Does not include children.
+@end
+
+#endif // defined(TARGET_OS_EMBEDDED) && TARGET_OS_EMBEDDED
diff --git a/Source/WebCore/bindings/objc/DOMUIKitExtensions.mm b/Source/WebCore/bindings/objc/DOMUIKitExtensions.mm
new file mode 100644 (file)
index 0000000..3ad9575
--- /dev/null
@@ -0,0 +1,507 @@
+/*
+ * Copyright (C) 2007, 2008, 2009, 2013 Apple Inc. All Rights Reserved.
+ *
+ * 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, 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. 
+ *
+ */
+
+#if PLATFORM(IOS)
+
+#import "config.h"
+#import "htmlediting.h"
+
+#import "CachedImage.h"
+#import "DOM.h"
+#import "DOMCore.h"
+#import "DOMExtensions.h"
+#import "DOMHTML.h"
+#import "DOMHTMLAreaElementInternal.h"
+#import "DOMHTMLElementInternal.h"
+#import "DOMHTMLImageElementInternal.h"
+#import "DOMHTMLSelectElementInternal.h"
+#import "DOMInternal.h"
+#import "DOMNodeInternal.h"
+#import "DOMRangeInternal.h"
+#import "DOMUIKitExtensions.h"
+#import "FloatPoint.h"
+#import "Font.h"
+#import "FrameSelection.h"
+#import "HTMLAreaElement.h"
+#import "HTMLImageElement.h"
+#import "HTMLInputElement.h"
+#import "HTMLSelectElement.h"
+#import "HTMLTextAreaElement.h"
+#import "Image.h"
+#import "InlineBox.h"
+#import "Node.h"
+#import "Range.h"
+#import "RenderBlock.h"
+#import "RenderBlockFlow.h"
+#import "RenderBox.h"
+#import "RoundedRect.h"
+#import "RenderObject.h"
+#import "RenderStyleConstants.h"
+#import "RenderText.h"
+#import "ResourceBuffer.h"
+#import "SharedBuffer.h"
+#import "TextIterator.h"
+#import "VisiblePosition.h"
+#import "VisibleUnits.h"
+
+#import "WAKAppKitStubs.h"
+
+using namespace WebCore;
+
+using WebCore::FloatPoint;
+using WebCore::Font;
+using WebCore::HTMLAreaElement;
+using WebCore::HTMLImageElement;
+using WebCore::HTMLSelectElement;
+using WebCore::InlineBox;
+using WebCore::IntRect;
+using WebCore::Node;
+using WebCore::Position;
+using WebCore::Range;
+using WebCore::RenderBlock;
+using WebCore::RenderBox;
+using WebCore::RenderObject;
+using WebCore::RenderStyle;
+using WebCore::RenderText;
+using WebCore::RootInlineBox;
+using WebCore::TextIterator;
+using WebCore::VisiblePosition;
+
+@implementation DOMRange (UIKitExtensions)
+
+- (void)move:(UInt32)amount inDirection:(WebTextAdjustmentDirection)direction
+{
+    Range *range = core(self);
+    FrameSelection frameSelection;
+    frameSelection.moveTo(range, DOWNSTREAM);
+    
+    TextGranularity granularity = CharacterGranularity;
+    // Until WebKit supports vertical layout, "down" is equivalent to "forward by a line" and
+    // "up" is equivalent to "backward by a line".
+    if (direction == WebTextAdjustmentDown) {
+        direction = WebTextAdjustmentForward;
+        granularity = LineGranularity;
+    } else if (direction == WebTextAdjustmentUp) {
+        direction = WebTextAdjustmentBackward;
+        granularity = LineGranularity;
+    }
+    
+    for (UInt32 i = 0; i < amount; i++)
+        frameSelection.modify(FrameSelection::AlterationMove, (SelectionDirection)direction, granularity);
+    
+    ExceptionCode ignored;
+    range->setStart(frameSelection.start().anchorNode(), frameSelection.start().deprecatedEditingOffset(), ignored);
+    range->setEnd(frameSelection.end().anchorNode(), frameSelection.end().deprecatedEditingOffset(), ignored);
+}
+
+- (void)extend:(UInt32)amount inDirection:(WebTextAdjustmentDirection)direction
+{
+    Range *range = core(self);
+    FrameSelection frameSelection;
+    frameSelection.moveTo(range, DOWNSTREAM);
+    
+    for (UInt32 i = 0; i < amount; i++)
+        frameSelection.modify(FrameSelection::AlterationExtend, (SelectionDirection)direction, CharacterGranularity);    
+    
+    ExceptionCode ignored;
+    range->setStart(frameSelection.start().anchorNode(), frameSelection.start().deprecatedEditingOffset(), ignored);
+    range->setEnd(frameSelection.end().anchorNode(), frameSelection.end().deprecatedEditingOffset(), ignored);    
+}
+
+- (DOMNode *)firstNode
+{
+    return kit(core(self)->firstNode());
+}
+
+@end
+
+//-------------------
+
+@implementation DOMNode (UIKitExtensions)
+
+// NOTE: Code blatantly copied from [WebInspector _hightNode:] in WebKit/WebInspector/WebInspector.m@19861
+- (NSArray *)boundingBoxes
+{
+    NSArray *rects = nil;
+    NSRect bounds = [self boundingBox];
+    if (!NSIsEmptyRect(bounds)) {
+        if ([self isKindOfClass:[DOMElement class]]) {
+            DOMDocument *document = [self ownerDocument];
+            DOMCSSStyleDeclaration *style = [document getComputedStyle:(DOMElement *)self pseudoElement:@""];
+            if ([[style getPropertyValue:@"display"] isEqualToString:@"inline"])
+                rects = [self lineBoxRects];
+        } else if ([self isKindOfClass:[DOMText class]]
+#if ENABLE(SVG_DOM_OBJC_BINDINGS)
+                   && ![[self parentNode] isKindOfClass:NSClassFromString(@"DOMSVGElement")]
+#endif
+                  )
+            rects = [self lineBoxRects];
+    }
+
+    if (![rects count])
+        rects = [NSArray arrayWithObject:[NSValue valueWithRect:bounds]];
+
+    return rects;
+}
+
+- (NSArray *)absoluteQuads
+{
+    NSArray *quads = nil;
+    NSRect bounds = [self boundingBox];
+    if (!NSIsEmptyRect(bounds)) {
+        if ([self isKindOfClass:[DOMElement class]]) {
+            DOMDocument *document = [self ownerDocument];
+            DOMCSSStyleDeclaration *style = [document getComputedStyle:(DOMElement *)self pseudoElement:@""];
+            if ([[style getPropertyValue:@"display"] isEqualToString:@"inline"])
+                quads = [self lineBoxQuads];
+        } else if ([self isKindOfClass:[DOMText class]]
+#if ENABLE(SVG_DOM_OBJC_BINDINGS)
+                   && ![[self parentNode] isKindOfClass:NSClassFromString(@"DOMSVGElement")]
+#endif
+                   )
+            quads = [self lineBoxQuads];
+    }
+
+    if (![quads count]) {
+        WKQuadObject* quadObject = [[WKQuadObject alloc] initWithQuad:[self absoluteQuad]];
+        quads = [NSArray arrayWithObject:quadObject];
+        [quadObject release];
+    }
+
+    return quads;
+}
+
+- (NSArray *)borderRadii
+{
+    RenderObject* renderer = core(self)->renderer();
+    
+
+    if (renderer && renderer->isBox()) {
+        RoundedRect::Radii radii = toRenderBox(renderer)->borderRadii();
+        return @[[NSValue valueWithSize:(CGSize)radii.topLeft()],
+                 [NSValue valueWithSize:(CGSize)radii.topRight()],
+                 [NSValue valueWithSize:(CGSize)radii.bottomLeft()],
+                 [NSValue valueWithSize:(CGSize)radii.bottomRight()]];
+    }
+    NSValue *emptyValue = [NSValue valueWithSize:CGSizeZero];
+    return @[emptyValue, emptyValue, emptyValue, emptyValue];
+}
+
+- (BOOL)containsOnlyInlineObjects
+{
+    RenderObject * renderer = core(self)->renderer();
+    return  (renderer &&
+             renderer->childrenInline() &&
+             (renderer->isRenderBlock() && toRenderBlock(renderer)->inlineElementContinuation() == nil) &&
+             !renderer->isTable());
+}
+
+- (BOOL)isSelectableBlock
+{
+    RenderObject * renderer = core(self)->renderer();
+    return (renderer && (renderer->isRenderBlockFlow() || (renderer->isRenderBlock() && toRenderBlock(renderer)->inlineElementContinuation() != nil)));
+}
+
+- (DOMRange *)rangeOfContainingParagraph
+{
+    DOMRange *result = nil;
+    
+    Node *node = core(self);    
+    VisiblePosition visiblePosition(createLegacyEditingPosition(node, 0), WebCore::DOWNSTREAM);
+    VisiblePosition visibleParagraphStart = startOfParagraph(visiblePosition);
+    VisiblePosition visibleParagraphEnd = endOfParagraph(visiblePosition);
+    
+    Position paragraphStart = visibleParagraphStart.deepEquivalent().parentAnchoredEquivalent();
+    Position paragraphEnd = visibleParagraphEnd.deepEquivalent().parentAnchoredEquivalent();    
+    
+    if (paragraphStart.isNotNull() && paragraphEnd.isNotNull()) {
+        PassRefPtr<Range> range = Range::create(*node->ownerDocument(), paragraphStart, paragraphEnd);
+        result = kit(range.get());
+    }
+    
+    return result;
+}
+
+- (CGFloat)textHeight
+{  
+    RenderObject *o = core(self)->renderer();
+    if (o && o->isText()) {
+        RenderText *t = toRenderText(o);
+        return t->style().computedLineHeight();;
+    }
+    
+    return CGFLOAT_MAX;
+}
+
+- (DOMNode *)findExplodedTextNodeAtPoint:(CGPoint)point
+{
+    // A light, non-recursive version of RenderBlock::positionForCoordinates that looks at
+    // whether a point lies within the gaps between its root line boxes, to be called against
+    // a node returned from elementAtPoint.  We make the assumption that either the node or one
+    // of its immediate children contains the root line boxes in question.
+    // See <rdar://problem/6824650> for context.
+    RenderObject *renderer = core(self)->renderer();
+    if (!renderer || !renderer->isRenderBlockFlow())
+        return nil;
+
+    RenderBlock *block = static_cast<RenderBlock *>(renderer);
+    
+    FloatPoint absPoint(point);
+    FloatPoint localPoint = block->absoluteToLocal(absPoint);
+
+    if (!block->childrenInline()) {
+        // Look among our immediate children for an alternate box that contains the point.
+        for (RenderBox* child = block->firstChildBox(); child; child = child->nextSiblingBox()) {
+            if (child->height() == 0 || child->style().visibility() != WebCore::VISIBLE || child->isFloatingOrOutOfFlowPositioned())
+                continue;
+            float top = child->y();
+            
+            RenderBox* nextChild = child->nextSiblingBox();
+            while (nextChild && nextChild->isFloatingOrOutOfFlowPositioned())
+                nextChild = nextChild->nextSiblingBox();
+            if (!nextChild) {
+                if (localPoint.y() >= top) {
+                    block = static_cast<RenderBlock *>(child);
+                    break;
+                }
+                continue;
+            }
+            
+            float bottom = nextChild->y();
+            
+            if (localPoint.y() >= top && localPoint.y() < bottom && child->isRenderBlock()) {
+                block = static_cast<RenderBlock *>(child);
+                break;
+            }                
+        }
+        
+        if (!block->childrenInline())
+            return nil;
+        
+        localPoint = block->absoluteToLocal(absPoint);
+    }
+
+    RenderBlockFlow *blockFlow = toRenderBlockFlow(block);
+    
+    // Only check the gaps between the root line boxes.  We deliberately ignore overflow because
+    // experience has shown that hit tests on an exploded text node can fail when within the
+    // overflow region.
+    for (RootInlineBox *cur = blockFlow->firstRootBox(); cur && cur != blockFlow->lastRootBox(); cur = cur->nextRootBox()) {
+        float currentBottom = cur->y() + cur->logicalHeight();        
+        if (localPoint.y() < currentBottom)
+            return nil;
+
+        RootInlineBox *next = cur->nextRootBox();
+        float nextTop = next->y();
+        if (localPoint.y() < nextTop) {
+            InlineBox *inlineBox = cur->closestLeafChildForLogicalLeftPosition(localPoint.x());
+            if (inlineBox && inlineBox->behavesLikeText() && inlineBox->renderer().isText()) {
+                RenderText *t = toRenderText(&inlineBox->renderer());
+                if (t->textNode()) {
+                    return kit(t->textNode());
+                }
+            }
+        }
+
+    }
+    return nil;    
+}
+
+@end
+
+//-----------------
+
+@implementation DOMElement (DOMUIKitComplexityExtensions) 
+
+- (int)structuralComplexityContribution { return 0; }
+
+@end
+
+@implementation DOMHTMLElement (DOMUIKitComplexityExtensions) 
+
+- (int)structuralComplexityContribution
+{
+    int result = 0;
+    RenderObject * renderer = core(self)->renderer();
+    if (renderer) {
+        if (renderer->isFloatingOrOutOfFlowPositioned() ||
+            renderer->isWidget()) {
+            result = INT_MAX;
+        } else if (renderer->isEmpty()) {
+            result = 0;
+        } else if (renderer->isRenderBlockFlow() || (renderer->isRenderBlock() && toRenderBlock(renderer)->inlineElementContinuation() != 0)) {
+            BOOL noCost = NO;
+            if (renderer->isBox()) {
+                RenderBox *asBox = renderer->enclosingBox();
+                RenderObject *parent = asBox->parent();
+                RenderBox *parentRenderBox = (parent && parent->isBox()) ? toRenderBox(parent) : 0;
+                if (parentRenderBox && asBox && asBox->width() == parentRenderBox->width()) {
+                    noCost = YES;
+                }
+            }
+            result = (noCost ? 0 : 1);
+        } else if (renderer->hasTransform()) {
+            result = INT_MAX;
+        }
+    }
+    return result;
+}
+
+@end
+
+@implementation DOMHTMLBodyElement (DOMUIKitComplexityExtensions)
+- (int)structuralComplexityContribution { return 0; }
+@end
+
+
+// Maximally complex elements
+
+@implementation DOMHTMLFormElement (DOMUIKitComplexityExtensions)
+- (int)structuralComplexityContribution { return INT_MAX; }
+@end
+
+@implementation DOMHTMLTableElement (DOMUIKitComplexityExtensions)
+- (int)structuralComplexityContribution { return INT_MAX; }
+@end
+
+@implementation DOMHTMLFrameElement (DOMUIKitComplexityExtensions)
+- (int)structuralComplexityContribution { return INT_MAX; }
+@end
+
+@implementation DOMHTMLIFrameElement (DOMUIKitComplexityExtensions)
+- (int)structuralComplexityContribution { return INT_MAX; }
+@end
+
+@implementation DOMHTMLButtonElement (DOMUIKitComplexityExtensions)
+- (int)structuralComplexityContribution { return INT_MAX; }
+@end
+
+@implementation DOMHTMLTextAreaElement (DOMUIKitComplexityExtensions)
+- (int)structuralComplexityContribution { return INT_MAX; }
+@end
+
+@implementation DOMHTMLInputElement (DOMUIKitComplexityExtensions)
+- (int)structuralComplexityContribution { return INT_MAX; }
+@end
+
+@implementation DOMHTMLSelectElement (DOMUIKitComplexityExtensions)
+- (int)structuralComplexityContribution { return INT_MAX; }
+@end
+
+
+//-----------------
+        
+@implementation DOMHTMLAreaElement (DOMUIKitExtensions)
+
+- (CGRect)boundingBoxWithOwner:(DOMNode *)anOwner
+{
+    // ignores transforms
+    return anOwner ? pixelSnappedIntRect(core(self)->computeRect(core(anOwner)->renderer())) : CGRectZero;
+}
+
+- (WKQuad)absoluteQuadWithOwner:(DOMNode *)anOwner
+{
+    if (anOwner) {
+        // FIXME: ECLAIR
+        //WebCore::FloatQuad theQuad = core(self)->getAbsoluteQuad(core(anOwner)->renderer());
+        WebCore::IntRect rect = pixelSnappedIntRect(core(self)->computeRect(core(anOwner)->renderer()));
+        WKQuad quad;
+        quad.p1 = CGPointMake(rect.x(), rect.y());
+        quad.p2 = CGPointMake(rect.maxX(), rect.y());
+        quad.p3 = CGPointMake(rect.maxX(), rect.maxY());
+        quad.p4 = CGPointMake(rect.x(), rect.maxY());
+        return quad;
+    }
+
+    WKQuad zeroQuad = { CGPointZero, CGPointZero, CGPointZero, CGPointZero };
+    return zeroQuad;
+}
+
+- (NSArray *)boundingBoxesWithOwner:(DOMNode *)anOwner
+{
+    return [NSArray arrayWithObject:[NSValue valueWithRect:[self boundingBoxWithOwner:anOwner]]];
+}
+
+- (NSArray *)absoluteQuadsWithOwner:(DOMNode *)anOwner
+{
+    WKQuadObject* quadObject = [[WKQuadObject alloc] initWithQuad:[self absoluteQuadWithOwner:anOwner]];
+    NSArray*    quadArray = [NSArray arrayWithObject:quadObject];
+    [quadObject release];
+    return quadArray;
+}
+
+@end
+
+@implementation DOMHTMLSelectElement (DOMUIKitExtensions)
+
+- (unsigned)completeLength
+{
+    return core(self)->listItems().size();
+}
+
+- (DOMNode *)listItemAtIndex:(int)anIndex
+{
+    return kit(core(self)->listItems()[anIndex]);
+}
+
+@end
+
+@implementation DOMHTMLImageElement (WebDOMHTMLImageElementOperationsPrivate)
+
+- (NSData *)dataRepresentation:(BOOL)rawImageData
+{
+    WebCore::CachedImage *cachedImage = core(self)->cachedImage();
+    if (!cachedImage)
+        return nil;
+    WebCore::Image *image = cachedImage->image();
+    if (!image)
+        return nil;
+    WebCore::SharedBuffer *data = nil;
+    if (rawImageData) {
+        ResourceBuffer *resourceBuffer = cachedImage->resourceBuffer();
+        if (resourceBuffer)
+            data = resourceBuffer->sharedBuffer();
+    } else {
+        data = image->data();
+    }
+    if (!data)
+        return nil;
+    
+    return [data->createNSData().leakRef() autorelease];
+}
+
+- (NSString *)mimeType
+{
+    WebCore::CachedImage *cachedImage = core(self)->cachedImage();
+    if (!cachedImage || !cachedImage->image())
+        return nil;
+    
+    return cachedImage->response().mimeType();
+}
+
+@end
+
+#endif
index caaab9a..a643f52 100644 (file)
@@ -26,6 +26,8 @@
 // All public DOM class interfaces, properties and methods need to be in this file.
 // Anything not in the file will be generated into the appropriate private header file.
 
+#include <wtf/Platform.h>
+
 #ifndef OBJC_CODE_GENERATION
 #error Do not include this header, instead include the appropriate DOM header.
 #endif
index dddabc9..8783e76 100644 (file)
@@ -49,6 +49,40 @@ my @depsContent = ();
 my $numCachedAttributes = 0;
 my $currentCachedAttribute = 0;
 
+my $beginAppleCopyrightForHeaderFiles = <<END;
+// ------- Begin Apple Copyright -------
+/*
+ * Copyright (C) 2008, Apple Inc. All rights reserved.
+ *
+ * Permission is granted by Apple to use this file to the extent
+ * necessary to relink with LGPL WebKit files.
+ *
+ * No license or rights are granted by Apple expressly or by
+ * implication, estoppel, or otherwise, to Apple patents and
+ * trademarks. For the sake of clarity, no license or rights are
+ * granted by Apple expressly or by implication, estoppel, or otherwise,
+ * under any Apple patents, copyrights and trademarks to underlying
+ * implementations of any application programming interfaces (APIs)
+ * or to any functionality that is invoked by calling any API.
+ */
+
+END
+my $beginAppleCopyrightForSourceFiles = <<END;
+// ------- Begin Apple Copyright -------
+/*
+ * Copyright (C) 2008, Apple Inc. All rights reserved.
+ *
+ * No license or rights are granted by Apple expressly or by implication,
+ * estoppel, or otherwise, to Apple copyrights, patents, trademarks, trade
+ * secrets or other rights.
+ */
+
+END
+my $endAppleCopyright   = <<END;
+// ------- End Apple Copyright   -------
+
+END
+
 # Default .h template
 my $headerTemplate = << "EOF";
 /*
@@ -448,7 +482,12 @@ sub GenerateHeaderContentHeader
     my $interface = shift;
     my $className = "JS" . $interface->name;
 
-    my @headerContentHeader = split("\r", $headerTemplate);
+    my @headerContentHeader;
+    if ($interface->extendedAttributes->{"AppleCopyright"}) {
+        @headerContentHeader = split("\r", $beginAppleCopyrightForHeaderFiles);
+    } else {
+        @headerContentHeader = split("\r", $headerTemplate);
+    }
 
     # - Add header protection
     push(@headerContentHeader, "\n#ifndef $className" . "_h");
@@ -464,7 +503,12 @@ sub GenerateImplementationContentHeader
     my $interface = shift;
     my $className = "JS" . $interface->name;
 
-    my @implContentHeader = split("\r", $headerTemplate);
+    my @implContentHeader;
+    if ($interface->extendedAttributes->{"AppleCopyright"}) {
+        @implContentHeader = split("\r", $beginAppleCopyrightForSourceFiles);
+    } else {
+        @implContentHeader = split("\r", $headerTemplate);
+    }
 
     push(@implContentHeader, "\n#include \"config.h\"\n");
     my $conditionalString = $codeGenerator->GenerateConditionalString($interface);
@@ -867,8 +911,21 @@ sub GenerateHeader
     }
 
     if ($numCustomFunctions > 0) {
+        my $inAppleCopyright = 0;
         push(@headerContent, "\n    // Custom functions\n");
         foreach my $function (@{$interface->functions}) {
+            # PLATFORM_IOS
+            my $needsAppleCopyright = $function->signature->extendedAttributes->{"AppleCopyright"};
+            if ($needsAppleCopyright) {
+                if (!$inAppleCopyright) {
+                    push(@headerContent, $beginAppleCopyrightForHeaderFiles);
+                    $inAppleCopyright = 1;
+                }
+            } elsif ($inAppleCopyright) {
+                push(@headerContent, $endAppleCopyright);
+                $inAppleCopyright = 0;
+            }
+            # end PLATFORM_IOS
             next unless HasCustomMethod($function->signature->extendedAttributes);
             next if $function->{overloads} && $function->{overloadIndex} != 1;
             my $conditionalString = $codeGenerator->GenerateConditionalString($function->signature);
@@ -877,6 +934,7 @@ sub GenerateHeader
             push(@headerContent, "    " . ($function->isStatic ? "static " : "") . "JSC::JSValue " . $functionImplementationName . "(JSC::ExecState*);\n");
             push(@headerContent, "#endif\n") if $conditionalString;
         }
+        push(@headerContent, $endAppleCopyright) if $inAppleCopyright;
     }
 
     if (!$hasParent) {
@@ -1043,15 +1101,29 @@ sub GenerateHeader
     }
 
     if ($numFunctions > 0) {
+        my $inAppleCopyright = 0;
         push(@headerContent,"// Functions\n\n");
         foreach my $function (@{$interface->functions}) {
             next if $function->{overloadIndex} && $function->{overloadIndex} > 1;
+            my $needsAppleCopyright = $function->signature->extendedAttributes->{"AppleCopyright"};
+            if ($needsAppleCopyright) {
+                if (!$inAppleCopyright) {
+                    push(@headerContent, $beginAppleCopyrightForHeaderFiles);
+                    $inAppleCopyright = 1;
+                }
+            } elsif ($inAppleCopyright) {
+                push(@headerContent, $endAppleCopyright);
+                $inAppleCopyright = 0;
+            }
+
             my $conditionalString = $codeGenerator->GenerateConditionalString($function->signature);
             push(@headerContent, "#if ${conditionalString}\n") if $conditionalString;
             my $functionName = GetFunctionName($className, $function);
             push(@headerContent, "JSC::EncodedJSValue JSC_HOST_CALL ${functionName}(JSC::ExecState*);\n");
             push(@headerContent, "#endif\n") if $conditionalString;
         }
+
+        push(@headerContent, $endAppleCopyright) if $inAppleCopyright;
     }
 
     if ($numAttributes > 0 || !$interface->extendedAttributes->{"NoInterfaceObject"}) {
@@ -1094,6 +1166,10 @@ sub GenerateHeader
     push(@headerContent, "\n} // namespace WebCore\n\n");
     push(@headerContent, "#endif // ${conditionalString}\n\n") if $conditionalString;
     push(@headerContent, "#endif\n");
+
+    if ($interface->extendedAttributes->{"AppleCopyright"}) {
+        push(@headerContent, split("\r", $endAppleCopyright));
+    }
 }
 
 sub GenerateAttributesHashTable($$)
@@ -2382,7 +2458,19 @@ sub GenerateImplementation
 
     # Functions
     if ($numFunctions > 0) {
+        my $inAppleCopyright = 0;
         foreach my $function (@{$interface->functions}) {
+            my $needsAppleCopyright = $function->signature->extendedAttributes->{"AppleCopyright"};
+            if ($needsAppleCopyright) {
+                if (!$inAppleCopyright) {
+                    push(@implContent, $beginAppleCopyrightForSourceFiles);
+                    $inAppleCopyright = 1;
+                }
+            } elsif ($inAppleCopyright) {
+                push(@implContent, $endAppleCopyright);
+                $inAppleCopyright = 0;
+            }
+
             my $isCustom = HasCustomMethod($function->signature->extendedAttributes);
             my $isOverloaded = $function->{overloads} && @{$function->{overloads}} > 1;
             my $raisesException = $function->signature->extendedAttributes->{"RaisesException"};
@@ -2497,6 +2585,9 @@ sub GenerateImplementation
             }
 
         }
+
+        push(@implContent, $endAppleCopyright) if $inAppleCopyright;
+
     }
 
     if ($needsMarkChildren && !$interface->extendedAttributes->{"JSCustomMarkFunction"}) {
@@ -3229,6 +3320,10 @@ sub GenerateCallbackImplementation
     push(@implContent, "\n}\n");
     my $conditionalString = $codeGenerator->GenerateConditionalString($interface);
     push(@implContent, "\n#endif // ${conditionalString}\n") if $conditionalString;
+
+    if ($interface->extendedAttributes->{"AppleCopyright"}) {
+        push(@implContent, split("\r", $endAppleCopyright));
+    }
 }
 
 sub GenerateImplementationFunctionCall()
index eb15329..5d8ebed 100644 (file)
@@ -48,11 +48,46 @@ my %privateHeaderForwardDeclarationsForProtocols = ();
 
 my @internalHeaderContent = ();
 
+my @implConditionalIncludes = ();
 my @implContentHeader = ();
 my @implContent = ();
 my %implIncludes = ();
 my @depsContent = ();
 
+my $beginAppleCopyrightForHeaderFiles = <<END;
+// ------- Begin Apple Copyright -------
+/*
+ * Copyright (C) 2008, Apple Inc. All rights reserved.
+ *
+ * Permission is granted by Apple to use this file to the extent
+ * necessary to relink with LGPL WebKit files.
+ *
+ * No license or rights are granted by Apple expressly or by
+ * implication, estoppel, or otherwise, to Apple patents and
+ * trademarks. For the sake of clarity, no license or rights are
+ * granted by Apple expressly or by implication, estoppel, or otherwise,
+ * under any Apple patents, copyrights and trademarks to underlying
+ * implementations of any application programming interfaces (APIs)
+ * or to any functionality that is invoked by calling any API.
+ */
+
+END
+my $beginAppleCopyrightForSourceFiles = <<END;
+// ------- Begin Apple Copyright -------
+/*
+ * Copyright (C) 2008, Apple Inc. All rights reserved.
+ *
+ * No license or rights are granted by Apple expressly or by implication,
+ * estoppel, or otherwise, to Apple copyrights, patents, trademarks, trade
+ * secrets or other rights.
+ */
+
+END
+my $endAppleCopyright   = <<END;
+// ------- End Apple Copyright   -------
+
+END
+
 # Hashes
 my %protocolTypeHash = ("XPathNSResolver" => 1, "EventListener" => 1, "EventTarget" => 1, "NodeFilter" => 1,
                         "SVGFilterPrimitiveStandardAttributes" => 1, 
@@ -76,6 +111,7 @@ my %baseTypeHash = ("Object" => 1, "Node" => 1, "NodeList" => 1, "NamedNodeMap"
                     "SVGStringList" => 1, "SVGTransform" => 1, "SVGTransformList" => 1, "SVGUnitTypes" => 1);
 
 # Constants
+my $buildingForIPhone = ($ENV{PLATFORM_NAME} eq "iphoneos" or $ENV{PLATFORM_NAME} eq "iphonesimulator");
 my $nullableInit = "bool isNull = false;";
 my $exceptionInit = "WebCore::ExceptionCode ec = 0;";
 my $jsContextSetter = "WebCore::JSMainThreadNullState state;";
@@ -214,6 +250,18 @@ sub ReadPublicInterfaces
     my $actualSuperClass;
     %publicInterfaces = ();
 
+    my @args = qw(-E -P -x objective-c);
+    # Set include path to find <wtf/Platform.h>.  We search BUILT_PRODUCTS_DIR
+    # first for local developer builds, then the installation path for B&I
+    # builds.
+    push(@args, "-I" . $ENV{BUILT_PRODUCTS_DIR} . "/usr/local/include") if $ENV{BUILT_PRODUCTS_DIR};
+    push(@args, "-I" . $ENV{BUILT_PRODUCTS_DIR} . $ENV{SDKROOT} . "/usr/local/include") if $ENV{BUILT_PRODUCTS_DIR};
+
+    # Xcode 3.1 is required for SDKROOT to be set.
+    if ($ENV{SDKROOT} && $ENV{SYSTEM_LIBRARY_DIR}) {
+        push(@args, "-I" . $ENV{BUILT_PRODUCTS_DIR} . $ENV{SDKROOT} . "/usr/local/include") if $ENV{BUILT_PRODUCTS_DIR};
+        push(@args, "-I" . $ENV{SDKROOT} . "/usr/local/include");
+    }
     my $fileName = "WebCore/bindings/objc/PublicDOMInterfaces.h";
     my $gccLocation = "";
     if ($ENV{CC}) {
@@ -225,7 +273,13 @@ sub ReadPublicInterfaces
     } else {
         $gccLocation = "/usr/bin/gcc";
     }
-    open FILE, "-|", $gccLocation, "-E", "-P", "-x", "objective-c",
+
+    if ($ENV{SDKROOT}) {
+        # PLATFORM(IOS)
+        push(@args, "-isysroot", $ENV{SDKROOT});
+    }
+
+    open FILE, "-|", $gccLocation, @args,
         (map { "-D$_" } split(/ +/, $defines)), "-DOBJC_CODE_GENERATION", $fileName or die "Could not open $fileName";
     my @documentContent = <FILE>;
     close FILE;
@@ -353,6 +407,7 @@ sub GetClassName
 
     # special cases
     return "NSString" if $codeGenerator->IsStringType($name) or $name eq "SerializedScriptValue";
+    return "CGColorRef" if $name eq "Color" and $buildingForIPhone;
     return "NS$name" if IsNativeObjCType($name);
     return "BOOL" if $name eq "boolean";
     return "unsigned char" if $name eq "octet";
@@ -483,6 +538,14 @@ sub IsNativeObjCType
     return 0;
 }
 
+sub IsCoreFoundationType
+{
+    my $type = shift;
+
+    return 1 if $type =~ /^(CF|CG)[A-Za-z]+Ref$/;
+    return 0;
+}
+
 sub SkipFunction
 {
     my $function = shift;
@@ -518,7 +581,6 @@ sub SkipAttribute
     return 0;
 }
 
-
 sub GetObjCType
 {
     my $type = shift;
@@ -527,6 +589,7 @@ sub GetObjCType
     return "id <$name>" if IsProtocolType($type);
     return $name if $codeGenerator->IsPrimitiveType($type) or $type eq "DOMTimeStamp";
     return "unsigned short" if $type eq "CompareHow";
+    return $name if IsCoreFoundationType($name);
     return "$name *";
 }
 
@@ -612,7 +675,11 @@ sub AddIncludesForType
 
     if (IsNativeObjCType($type)) {
         if ($type eq "Color") {
-            $implIncludes{"ColorMac.h"} = 1;
+            if ($buildingForIPhone) {
+                $implIncludes{"ColorSpace.h"} = 1;
+            } else {
+                $implIncludes{"ColorMac.h"} = 1;
+            }
         }
         return;
     }
@@ -752,7 +819,11 @@ sub GenerateHeader
     my $numFunctions = @{$interface->functions};
 
     # - Add default header template
-    @headerContentHeader = split("\r", $headerLicenseTemplate);
+    if ($interface->extendedAttributes->{"AppleCopyright"}) {
+        @headerContentHeader = split("\r", $beginAppleCopyrightForHeaderFiles);
+    } else {
+        @headerContentHeader = split("\r", $headerLicenseTemplate);
+    }
     push(@headerContentHeader, "\n");
 
     # - INCLUDES -
@@ -848,6 +919,11 @@ sub GenerateHeader
 
             my $publicInterfaceKey = $property . ";";
 
+            # FIXME: This only works for the getter, but not the setter.  Need to refactor this code.
+            if ($buildingForTigerOrEarlier && !$buildingForIPhone || IsCoreFoundationType($attributeType)) {
+                $publicInterfaceKey = "- (" . $attributeType . ")" . $attributeName . ";";
+            }
+
             my $availabilityMacro = "";
             if (defined $publicInterfaces{$publicInterfaceKey} and length $publicInterfaces{$publicInterfaceKey}) {
                 $availabilityMacro = $publicInterfaces{$publicInterfaceKey};
@@ -875,9 +951,34 @@ sub GenerateHeader
                 $fatalError = 1;
             }
 
-            $property .= $declarationSuffix;
-            push(@headerAttributes, $property) if $public;
-            push(@privateHeaderAttributes, $property) unless $public;
+            if (!IsCoreFoundationType($attributeType)) {
+                $property .= $declarationSuffix;
+                push(@headerAttributes, $property) if $public;
+                push(@privateHeaderAttributes, $property) unless $public;
+            } else {
+                my $attributeConditionalString = $codeGenerator->GenerateConditionalString($attribute->signature);
+                if ($attributeConditionalString) {
+                    push(@headerAttributes, "#if ${attributeConditionalString}\n") if $public;
+                    push(@privateHeaderAttributes, "#if ${attributeConditionalString}\n") unless $public;
+                }
+                # - GETTER
+                my $getter = "- (" . $attributeType . ")" . $attributeName . $declarationSuffix;
+                push(@headerAttributes, $getter) if $public;
+                push(@privateHeaderAttributes, $getter) unless $public;
+                # - SETTER
+                if (!$attribute->isReadOnly) {
+                    my $setter = "- (void)$setterName(" . $attributeType . ")new" . ucfirst($attributeName) . $declarationSuffix;
+                    push(@headerAttributes, $setter) if $public;
+                    push(@privateHeaderAttributes, $setter) unless $public;
+                }
+                if ($attributeConditionalString) {
+                    push(@headerAttributes, "#endif\n") if $public;
+                    push(@privateHeaderAttributes, "#endif\n") unless $public;
+                }
+            }
         }
 
         push(@headerContent, @headerAttributes) if @headerAttributes > 0;
@@ -889,6 +990,7 @@ sub GenerateHeader
 
     # - Add functions.
     if ($numFunctions > 0) {
+        my %inAppleCopyright = (public => 0, private => 0);
         foreach my $function (@{$interface->functions}) {
             next if SkipFunction($function);
             next if ($function->signature->name eq "set" and $interface->extendedAttributes->{"TypedArray"});
@@ -896,6 +998,7 @@ sub GenerateHeader
 
             my $returnType = GetObjCType($function->signature->type);
             my $needsDeprecatedVersion = (@{$function->parameters} > 1 and $function->signature->extendedAttributes->{"ObjCLegacyUnnamedParameters"});
+            my $needsAppleCopyright = $function->signature->extendedAttributes->{"AppleCopyright"};
             my $numberOfParameters = @{$function->parameters};
             my %typesToForwardDeclare = ($function->signature->type => 1);
 
@@ -950,6 +1053,18 @@ sub GenerateHeader
                 AddForwardDeclarationsForType($type, $public) unless $public and $needsDeprecatedVersion;
             }
 
+            if ($needsAppleCopyright) {
+                if (!$inAppleCopyright{$public ? "public" : "private"}) {
+                    push(@headerFunctions, $beginAppleCopyrightForHeaderFiles) if $public;
+                    push(@privateHeaderFunctions, $beginAppleCopyrightForHeaderFiles) unless $public;
+                    $inAppleCopyright{$public ? "public" : "private"} = 1;
+                }
+            } elsif ($inAppleCopyright{$public ? "public" : "private"}) {
+                push(@headerFunctions, $endAppleCopyright) if $public;
+                push(@privateHeaderFunctions, $endAppleCopyright) unless $public;
+                $inAppleCopyright{$public ? "public" : "private"} = 0;
+            }
+
             my $functionConditionalString = $codeGenerator->GenerateConditionalString($function->signature);
             if ($functionConditionalString) {
                 push(@headerFunctions, "#if ${functionConditionalString}\n") if $public;
@@ -991,6 +1106,9 @@ sub GenerateHeader
             }
         }
 
+        push(@headerFunctions, $endAppleCopyright) if $inAppleCopyright{"public"};
+        push(@privateHeaderFunctions, $endAppleCopyright) if $inAppleCopyright{"private"};
+
         if (@headerFunctions > 0) {
             push(@headerContent, "\n") if @headerAttributes > 0;
             push(@headerContent, @headerFunctions);
@@ -1011,11 +1129,19 @@ sub GenerateHeader
         push(@headerContent, "\@end\n");
     }
 
+    if ($interface->extendedAttributes->{"AppleCopyright"}) {
+        push(@headerContent, split("\r", $endAppleCopyright));
+    }
+
     my %alwaysGenerateForNoSVGBuild = map { $_ => 1 } qw(DOMHTMLEmbedElement DOMHTMLObjectElement);
 
     if (@privateHeaderAttributes > 0 or @privateHeaderFunctions > 0 or exists $alwaysGenerateForNoSVGBuild{$className}) {
         # - Private category @interface
-        @privateHeaderContentHeader = split("\r", $headerLicenseTemplate);
+        if ($interface->extendedAttributes->{"AppleCopyright"}) {
+            @privateHeaderContentHeader = split("\r", $beginAppleCopyrightForHeaderFiles);
+        } else {
+            @privateHeaderContentHeader = split("\r", $headerLicenseTemplate);
+        }
         push(@privateHeaderContentHeader, "\n");
 
         my $classHeaderName = GetClassHeaderName($className);
@@ -1027,6 +1153,10 @@ sub GenerateHeader
         push(@privateHeaderContent, "\n") if @privateHeaderAttributes > 0 and @privateHeaderFunctions > 0;
         push(@privateHeaderContent, @privateHeaderFunctions) if @privateHeaderFunctions > 0;
         push(@privateHeaderContent, "\@end\n");
+
+        if ($interface->extendedAttributes->{"AppleCopyright"}) {
+            push(@privateHeaderContent, split("\r", $endAppleCopyright));
+        }
     }
 
     unless ($isProtocol) {
@@ -1039,7 +1169,11 @@ sub GenerateHeader
         $implType = $svgNativeType if $svgNativeType;
 
         # Generate interface definitions. 
-        @internalHeaderContent = split("\r", $implementationLicenseTemplate);
+        if ($interface->extendedAttributes->{"AppleCopyright"}) {
+            @internalHeaderContent = split("\r", $beginAppleCopyrightForHeaderFiles);
+        } else {
+            @internalHeaderContent = split("\r", $implementationLicenseTemplate);
+        }
 
         push(@internalHeaderContent, "\n#import <WebCore/$className.h>\n\n");
         push(@internalHeaderContent, "#import <WebCore/SVGAnimatedPropertyTearOff.h>\n\n") if $svgPropertyType;
@@ -1108,7 +1242,11 @@ sub GenerateImplementation
     $implType = $svgNativeType if $svgNativeType;
 
     # - Add default header template.
-    @implContentHeader = split("\r", $implementationLicenseTemplate);
+    if ($interface->extendedAttributes->{"AppleCopyright"}) {
+        @implContentHeader = split("\r", $beginAppleCopyrightForSourceFiles);
+    } else {
+        @implContentHeader = split("\r", $implementationLicenseTemplate);
+    }
 
     # - INCLUDES -
     push(@implContentHeader, "\n#import \"config.h\"\n");
@@ -1335,8 +1473,13 @@ sub GenerateImplementation
                 $getterContentHead = "kit($getterContentHead";
                 $getterContentTail .= ")";
             } elsif ($idlType eq "Color") {
-                $getterContentHead = "WebCore::nsColor($getterContentHead";
-                $getterContentTail .= ")";
+                if ($buildingForIPhone) {
+                    $getterContentHead = "WebCore::cachedCGColor($getterContentHead";
+                    $getterContentTail .= ", WebCore::ColorSpaceDeviceRGB)";
+                } else {
+                    $getterContentHead = "WebCore::nsColor($getterContentHead";
+                    $getterContentTail .= ")";
+                }
             } elsif ($attribute->signature->type eq "SerializedScriptValue") {
                 $getterContentHead = "$getterContentHead";
                 $getterContentTail .= "->toString()";                
@@ -1507,6 +1650,7 @@ sub GenerateImplementation
 
     # - Functions
     if ($numFunctions > 0) {
+        my $inAppleCopyright = 0;
         foreach my $function (@{$interface->functions}) {
             next if SkipFunction($function);
             next if ($function->signature->name eq "set" and $interface->extendedAttributes->{"TypedArray"});
@@ -1514,6 +1658,7 @@ sub GenerateImplementation
 
             my $functionName = $function->signature->name;
             my $returnType = GetObjCType($function->signature->type);
+            my $needsAppleCopyright = $function->signature->extendedAttributes->{"AppleCopyright"};
             my $hasParameters = @{$function->parameters};
             my $raisesExceptions = $function->signature->extendedAttributes->{"RaisesException"};
 
@@ -1724,6 +1869,16 @@ sub GenerateImplementation
                 }
             }
 
+            if ($needsAppleCopyright) {
+                if (!$inAppleCopyright) {
+                    push(@implContent, $beginAppleCopyrightForSourceFiles);
+                    $inAppleCopyright = 1;
+                }
+            } elsif ($inAppleCopyright) {
+                push(@implContent, $endAppleCopyright);
+                $inAppleCopyright = 0;
+            }
+
             my $conditionalString = $codeGenerator->GenerateConditionalString($function->signature);
             push(@implContent, "\n#if ${conditionalString}\n") if $conditionalString;
 
@@ -1750,11 +1905,16 @@ sub GenerateImplementation
             # Clear the hash
             %needsCustom = ();
         }
+        push(@implContent, $endAppleCopyright) if $inAppleCopyright;
     }
 
     # END implementation
     push(@implContent, "\@end\n");
 
+    if ($interface->extendedAttributes->{"AppleCopyright"}) {
+        push(@implContent, split("\r", $endAppleCopyright));
+    }
+
     # Generate internal interfaces
     push(@implContent, "\n$implType* core($className *wrapper)\n");
     push(@implContent, "{\n");
@@ -1792,6 +1952,10 @@ sub GenerateImplementation
     # - End the ifdef conditional if necessary
     push(@implContent, "\n#endif // ${conditionalString}\n") if $conditionalString;
 
+    if ($interface->extendedAttributes->{"AppleCopyright"}) {
+        push(@implContent, split("\r", $endAppleCopyright));
+    }
+
     # - Generate dependencies.
     if ($writeDependencies && @ancestorInterfaceNames) {
         push(@depsContent, "$className.h : ", join(" ", map { "$_.idl" } @ancestorInterfaceNames), "\n");
@@ -1803,11 +1967,11 @@ sub GenerateImplementation
 sub WriteData
 {
     my $object = shift;
-    my $dataNode = shift;
+    my $interface = shift;
     my $outputDir = shift;
 
     # Open files for writing...
-    my $name = $dataNode->name;
+    my $name = $interface->name;
     my $prefix = FileNamePrefix;
     my $headerFileName = "$outputDir/$prefix$name.h";
     my $privateHeaderFileName = "$outputDir/$prefix${name}Private.h";
@@ -1817,7 +1981,7 @@ sub WriteData
 
     # Write public header.
     my $contents = join "", @headerContentHeader;
-    map { $contents .= "\@class $_;\n" } sort keys(%headerForwardDeclarations);
+    map { $contents .= (IsCoreFoundationType($_) ? "typedef struct " . substr($_, 0, -3) . "* $_;\n" : "\@class $_;\n") } sort keys(%headerForwardDeclarations);
     map { $contents .= "\@protocol $_;\n" } sort keys(%headerForwardDeclarationsForProtocols);
 
     my $hasForwardDeclarations = keys(%headerForwardDeclarations) + keys(%headerForwardDeclarationsForProtocols);
index e4c292b..85ead71 100644 (file)
@@ -107,3 +107,6 @@ TreatReturnedNullStringAs=Null|Undefined
 TreatUndefinedAs=NullString
 TypedArray=*
 URL
+
+# PLATFORM(IOS)
+AppleCopyright
index cb30f80..e84cd4a 100644 (file)
@@ -57,6 +57,9 @@ sub applyPreprocessor
         push(@args, qw(-E -P -x c++));
     }
 
+    push(@args, "-I" . $ENV{BUILT_PRODUCTS_DIR} . "/usr/local/include") if $ENV{BUILT_PRODUCTS_DIR};
+    push(@args, "-isysroot", $ENV{SDKROOT}) if $ENV{SDKROOT};
+
     # Remove double quotations from $defines and extract macros.
     # For example, if $defines is ' "A=1" "B=1" C=1 ""    D  ',
     # then it is converted into four macros -DA=1, -DB=1, -DC=1 and -DD.
index 5bacf7a..a8ef50e 100644 (file)
@@ -161,7 +161,11 @@ Field* ObjcClass::fieldNamed(PropertyName propertyName, Instance* instance) cons
     CString jsName = name.ascii();
     RetainPtr<CFStringRef> fieldName = adoptCF(CFStringCreateWithCString(NULL, jsName.data(), kCFStringEncodingASCII));
     id targetObject = (static_cast<ObjcInstance*>(instance))->getObject();
+#if PLATFORM(IOS)
+    id attributes = [targetObject respondsToSelector:@selector(attributeKeys)] ? [targetObject performSelector:@selector(attributeKeys)] : nil;
+#else
     id attributes = [targetObject attributeKeys];
+#endif
     if (attributes) {
         // Class overrides attributeKeys, use that array of key names.
         unsigned count = [attributes count];
index d1d37f5..3ca7357 100644 (file)
 #import "runtime/FunctionPrototype.h"
 #import <wtf/Assertions.h>
 
+#if PLATFORM(IOS)
+#import <Foundation/NSMapTable.h>
+#endif // PLATFORM(IOS)
+
 #ifdef NDEBUG
 #define OBJC_LOG(formatAndArgs...) ((void)0)
 #else
index 653731c..ff63cd5 100644 (file)
 #endif
 #endif
 
-#if PLATFORM(MAC)
+#if PLATFORM(MAC) && !PLATFORM(IOS)
 // New theme
 #define WTF_USE_NEW_THEME 1
 #endif // PLATFORM(MAC)
@@ -125,6 +125,11 @@ typedef float CGFloat;
 #define WTF_USE_CA 1
 #endif
 
+#if PLATFORM(IOS)
+#define WEBCORE_NAVIGATOR_PLATFORM wkGetPlatformNameForNavigator();
+#define WEBCORE_NAVIGATOR_VENDOR wkGetVendorNameForNavigator();
+#endif
+
 // FIXME: Move this to JavaScriptCore/wtf/Platform.h, which is where we define WTF_USE_AVFOUNDATION on the Mac.
 // https://bugs.webkit.org/show_bug.cgi?id=67334
 #if PLATFORM(WIN) && USE(CG) && HAVE(AVCF)
index e86df9f..4b5a882 100644 (file)
@@ -4789,7 +4789,7 @@ HTMLCanvasElement* Document::getCSSCanvasElement(const String& name)
 #if ENABLE(IOS_TEXT_AUTOSIZING)
 void Document::addAutoSizingNode(Node* node, float candidateSize)
 {
-    TextAutoSizingKey key(node->renderer()->style(), &document());
+    TextAutoSizingKey key(&node->renderer()->style(), &document());
     TextAutoSizingMap::AddResult result = m_textAutoSizedNodes.add(key, nullptr);
     if (result.isNewEntry)
         result.iterator->value = TextAutoSizingValue::create();
index 4ba0c5c..30d42dc 100644 (file)
@@ -165,8 +165,8 @@ struct AnnotatedRegionValue;
 
 #if ENABLE(TOUCH_EVENTS)
 #if PLATFORM(IOS)
-#include "DocumentIOSForward.h"
-#endif
+#include <WebKitAdditions/DocumentIOSForward.h>
+#endif // PLATFORM(IOS)
 class Touch;
 class TouchList;
 #endif
@@ -1114,7 +1114,7 @@ public:
 
 #if ENABLE(TOUCH_EVENTS)
 #if PLATFORM(IOS)
-#include "DocumentIOS.h"
+#include <WebKitAdditions/DocumentIOS.h>
 #else
     PassRefPtr<Touch> createTouch(DOMWindow*, EventTarget*, int identifier, int pageX, int pageY, int screenX, int screenY, int radiusX, int radiusY, float rotationAngle, float force, ExceptionCode&) const;
 #endif // PLATFORM(IOS)
index b0d8d2f..e84b586 100644 (file)
     // FIXME: Consider defining an ENABLE macro for iOS touch event code, say IOS_TOUCH_EVENTS,
     // and/or modifying the bindings scripts to support generating more complicated conditional code.
 #if defined(WTF_PLATFORM_IOS) && WTF_PLATFORM_IOS
-#include "DocumentIOS.idl"
+#include <WebKitAdditions/DocumentIOS.idl>
 #else
     [ReturnNewObject, RaisesException] Touch createTouch([Default=Undefined] optional DOMWindow window,
                                                      [Default=Undefined] optional EventTarget target,
diff --git a/Source/WebCore/dom/ios/TouchEvents.cpp b/Source/WebCore/dom/ios/TouchEvents.cpp
new file mode 100644 (file)
index 0000000..d0cf7a6
--- /dev/null
@@ -0,0 +1,36 @@
+/*
+ * Copyright (C) 2013 Apple Inc. All rights reserved.
+ *
+ * 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 INC. AND ITS CONTRIBUTORS ``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 INC. OR ITS 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.
+ */
+
+#include "config.h"
+
+#if PLATFORM(IOS) && ENABLE(TOUCH_EVENTS)
+
+#include <WebKitAdditions/DocumentIOS.cpp>
+#include <WebKitAdditions/GestureEventIOS.cpp>
+#include <WebKitAdditions/Touch.cpp>
+#include <WebKitAdditions/TouchEvent.cpp>
+#include <WebKitAdditions/TouchList.cpp>
+
+#endif
index d307af0..95310f5 100644 (file)
@@ -255,10 +255,18 @@ void ApplyStyleCommand::applyBlockStyle(EditingStyle *style)
     if (visibleStart.isNull() || visibleStart.isOrphan() || visibleEnd.isNull() || visibleEnd.isOrphan())
         return;
 
+#if !PLATFORM(IOS)
     // Save and restore the selection endpoints using their indices in the document, since
+#else
+    // Save and restore the selection endpoints using their indices in the editable root, since
+#endif
     // addBlockStyleIfNeeded may moveParagraphs, which can remove these endpoints.
     // Calculate start and end indices from the start of the tree that they're in.
+#if !PLATFORM(IOS)
     Node* scope = highestAncestor(visibleStart.deepEquivalent().deprecatedNode());
+#else
+    Node* scope = highestEditableRoot(visibleStart.deepEquivalent());
+#endif
     RefPtr<Range> startRange = Range::create(document(), firstPositionInNode(scope), visibleStart.deepEquivalent().parentAnchoredEquivalent());
     RefPtr<Range> endRange = Range::create(document(), firstPositionInNode(scope), visibleEnd.deepEquivalent().parentAnchoredEquivalent());
     int startIndex = TextIterator::rangeLength(startRange.get(), true);
index a630747..069d4d6 100644 (file)
 #include "DeleteButtonController.h"
 #endif
 
+#if PLATFORM(IOS)
+#include "BreakBlockquoteCommand.h"
+#endif
+
 namespace WebCore {
 
 using namespace HTMLNames;
@@ -102,6 +106,14 @@ void EditCommandComposition::unapply()
     // Low level operations, like RemoveNodeCommand, don't require a layout because the high level operations that use them perform one
     // if one is necessary (like for the creation of VisiblePositions).
     m_document->updateLayoutIgnorePendingStylesheets();
+#if PLATFORM(IOS)
+    // FIXME: Where should iPhone code deal with the composition?
+    // Since editing commands don't save/restore the composition, undoing without fixing
+    // up the composition will leave a stale, invalid composition, as in <rdar://problem/6831637>.
+    // Desktop handles this in -[WebHTMLView _updateSelectionForInputManager], but the phone
+    // goes another route.
+    frame->editor().cancelComposition();
+#endif
 
     {
 #if ENABLE(DELETION_UI)
@@ -190,6 +202,10 @@ void CompositeEditCommand::apply()
         case EditActionSetWritingDirection:
         case EditActionCut:
         case EditActionUnspecified:
+#if PLATFORM(IOS)
+        case EditActionDelete:
+        case EditActionDictation:
+#endif
             break;
         default:
             ASSERT_NOT_REACHED();
@@ -486,6 +502,49 @@ void CompositeEditCommand::splitTextNodeContainingElement(PassRefPtr<Text> text,
     applyCommandToComposite(SplitTextNodeContainingElementCommand::create(text, offset));
 }
 
+#if PLATFORM(IOS)
+void CompositeEditCommand::inputText(const String& text, bool selectInsertedText)
+{
+    unsigned offset = 0;
+    unsigned length = text.length();
+    
+    RefPtr<ContainerNode> scope;
+    unsigned startIndex = indexForVisiblePosition(endingSelection().visibleStart(), scope);
+    
+    size_t newline;
+    do {
+        newline = text.find('\n', offset);
+        if (newline != offset) {
+            int substringLength = newline == notFound ? length - offset : newline - offset;
+            RefPtr<InsertTextCommand> command = InsertTextCommand::create(document(), text.substring(offset, substringLength), false);
+            applyCommandToComposite(command);
+        }
+        if (newline != notFound) {
+            VisiblePosition caret(endingSelection().visibleStart());
+            if (enclosingNodeOfType(caret.deepEquivalent(), &isMailBlockquote)) {
+                // FIXME: Breaking a blockquote when the caret is just after a space will collapse the 
+                // space. Modify startIndex or length to compensate for this so that the ending selection 
+                // will be positioned correctly.
+                // <rdar://problem/9914462> breaking a Mail blockquote just after a space collapses the space
+                if (caret.previous().characterAfter() == ' ') {
+                    if (!offset && !startIndex)
+                        startIndex--;
+                    else if (!length)
+                        length--;
+                }
+                applyCommandToComposite(BreakBlockquoteCommand::create(document()));
+            } else
+                insertLineBreak();
+        }
+            
+        offset = newline + 1;
+    } while (newline != notFound && offset != length);
+    
+    if (selectInsertedText)
+        setEndingSelection(VisibleSelection(visiblePositionForIndex(startIndex, scope.get()), visiblePositionForIndex(startIndex + length, scope.get())));
+}
+#endif
+
 void CompositeEditCommand::insertTextIntoNode(PassRefPtr<Text> node, unsigned offset, const String& text)
 {
     if (!text.isEmpty())
@@ -535,7 +594,11 @@ void CompositeEditCommand::replaceTextInNodePreservingMarkers(PassRefPtr<Text> p
     replaceTextInNode(node, offset, count, replacementText);
     RefPtr<Range> newRange = Range::create(document(), node, offset, node, offset + replacementText.length());
     for (size_t i = 0; i < markers.size(); ++i)
+#if PLATFORM(IOS)
+        markerController.addMarker(newRange.get(), markers[i].type(), markers[i].description(), markers[i].alternatives(), markers[i].metadata());
+#else
         markerController.addMarker(newRange.get(), markers[i].type(), markers[i].description());
+#endif // PLATFORM(IOS)
 }
 
 Position CompositeEditCommand::positionOutsideTabSpan(const Position& pos)
@@ -1201,7 +1264,11 @@ void CompositeEditCommand::moveParagraphs(const VisiblePosition& startOfParagrap
     // anything if we're given an empty paragraph, but an empty paragraph can have style
     // too, <div><b><br></b></div> for example.  Save it so that we can preserve it later.
     RefPtr<EditingStyle> styleInEmptyParagraph;
+#if !PLATFORM(IOS)
     if (startOfParagraphToMove == endOfParagraphToMove && preserveStyle) {
+#else
+    if (startOfParagraphToMove == endOfParagraphToMove && preserveStyle && isRichlyEditablePosition(destination.deepEquivalent())) {
+#endif
         styleInEmptyParagraph = EditingStyle::create(startOfParagraphToMove.deepEquivalent());
         styleInEmptyParagraph->mergeTypingStyle(document());
         // The moved paragraph should assume the block style of the destination.
index e2a4992..28f702d 100644 (file)
@@ -104,6 +104,9 @@ protected:
     void deleteSelection(bool smartDelete = false, bool mergeBlocksAfterDelete = true, bool replace = false, bool expandForSpecialElements = true, bool sanitizeMarkup = true);
     void deleteSelection(const VisibleSelection&, bool smartDelete = false, bool mergeBlocksAfterDelete = true, bool replace = false, bool expandForSpecialElements = true, bool sanitizeMarkup = true);
     virtual void deleteTextFromNode(PassRefPtr<Text>, unsigned offset, unsigned count);
+#if PLATFORM(IOS)
+    void inputText(const String&, bool selectInsertedText = false);
+#endif
     bool isRemovableBlock(const Node*);
     void insertNodeAfter(PassRefPtr<Node>, PassRefPtr<Node> refChild);
     void insertNodeAt(PassRefPtr<Node>, const Position&);
index dec1fca..34e4cc0 100644 (file)
@@ -34,7 +34,9 @@ class DeleteButton : public HTMLImageElement {
 public:
     static PassRefPtr<DeleteButton> create(Document&);
 
+#if !PLATFORM(IOS)
     virtual bool willRespondToMouseClickEvents() OVERRIDE { return true; }
+#endif // !PLATFORM(IOS)
 
 private:
     explicit DeleteButton(Document&);
index ef786b9..a78769c 100644 (file)
@@ -331,6 +331,7 @@ void DeleteButtonController::hide()
 
 void DeleteButtonController::enable()
 {
+#if !PLATFORM(IOS)
     ASSERT(m_disableStack > 0);
     if (m_disableStack > 0)
         m_disableStack--;
@@ -341,13 +342,16 @@ void DeleteButtonController::enable()
         m_frame.document()->updateStyleIfNeeded();
         show(enclosingDeletableElement(m_frame.selection().selection()));
     }
+#endif
 }
 
 void DeleteButtonController::disable()
 {
+#if !PLATFORM(IOS)
     if (enabled())
         hide();
     m_disableStack++;
+#endif
 }
 
 class RemoveTargetCommand : public CompositeEditCommand {
index b3ac500..2b5457f 100644 (file)
@@ -861,7 +861,24 @@ void DeleteSelectionCommand::doApply()
         insertNodeAt(placeholder.get(), m_endingPosition);
     }
 
+#if PLATFORM(IOS)
+    // This checking is due to iphone shows the last entered character momentarily, removing and adding back the 
+    // space when deleting password cause space been showed insecurely.
+    bool isSecure = NO;
+    Node* node = m_endingPosition.deprecatedNode();
+    if (node && node->isTextNode()) {
+        Text* textNode = static_cast<Text*>(node);    
+        if (textNode->length() > 0) {
+            RenderObject* renderer = textNode->renderer();
+            isSecure = renderer->style().textSecurity() != TSNONE;
+        }
+    }
+        
+    if (!isSecure)
+        rebalanceWhitespaceAt(m_endingPosition);
+#else
     rebalanceWhitespaceAt(m_endingPosition);
+#endif
 
     calculateTypingStyleAfterDelete();
 
index 342b4b7..4c0f723 100644 (file)
@@ -43,8 +43,10 @@ public:
         return adoptRef(new DeleteSelectionCommand(selection, smartDelete, mergeBlocksAfterDelete, replace, expandForSpecialElements, sanitizeMarkup));
     }
 
-private:
+protected:
     DeleteSelectionCommand(Document&, bool smartDelete, bool mergeBlocksAfterDelete, bool replace, bool expandForSpecialElements, bool santizeMarkup);
+
+private:
     DeleteSelectionCommand(const VisibleSelection&, bool smartDelete, bool mergeBlocksAfterDelete, bool replace, bool expandForSpecialElements, bool sanitizeMarkup);
 
     virtual void doApply();
index 912e931..3d39759 100644 (file)
@@ -57,6 +57,10 @@ namespace WebCore {
         EditActionCut,
         EditActionBold,
         EditActionItalics,
+#if PLATFORM(IOS)
+        EditActionDelete,
+        EditActionDictation,
+#endif
         EditActionPaste,
         EditActionPasteFont,
         EditActionPasteRuler,
index 2e34aaf..24c4104 100644 (file)
@@ -51,6 +51,10 @@ public:
     const VisibleSelection& startingSelection() const { return m_startingSelection; }
     const VisibleSelection& endingSelection() const { return m_endingSelection; }
 
+#if PLATFORM(IOS)
+    virtual bool isInsertTextCommand() const { return false; }
+#endif
+    
     virtual bool isSimpleEditCommand() const { return false; }
     virtual bool isCompositeEditCommand() const { return false; }
     virtual bool isEditCommandComposition() const { return false; }
index adddb12..364ff80 100644 (file)
@@ -71,6 +71,10 @@ static const CSSPropertyID editingProperties[] = {
     CSSPropertyWhiteSpace,
     CSSPropertyWidows,
     CSSPropertyWordSpacing,
+#if PLATFORM(IOS)
+    CSSPropertyWebkitTapHighlightColor,
+    CSSPropertyWebkitCompositionFillColor,
+#endif
     CSSPropertyWebkitTextDecorationsInEffect,
     CSSPropertyWebkitTextFillColor,
 #if ENABLE(IOS_TEXT_AUTOSIZING)
index c713b1b..131cf77 100644 (file)
 #include "DeleteButtonController.h"
 #endif
 
+#if PLATFORM(IOS)
+#include "DictationCommandIOS.h"
+#include <wtf/text/StringBuilder.h>
+#include <wtf/text/WTFString.h>
+#endif
+
 namespace WebCore {
 
+#if PLATFORM(IOS)
+class ClearTextCommand : public DeleteSelectionCommand {
+public:
+    ClearTextCommand(Document& document);
+    static void CreateAndApply(const RefPtr<Frame> frame);
+    
+private:
+    virtual EditAction editingAction() const;
+};
+
+ClearTextCommand::ClearTextCommand(Document& document)
+    : DeleteSelectionCommand(document, false, true, false, false, true)
+{
+}
+
+EditAction ClearTextCommand::editingAction() const
+{
+    return EditActionDelete;
+}
+
+void ClearTextCommand::CreateAndApply(const RefPtr<Frame> frame)
+{
+    if (frame->selection().isNone())
+        return;
+
+    // Don't leave around stale composition state.
+    frame->editor().clear();
+    
+    const VisibleSelection oldSelection = frame->selection().selection();
+    frame->selection().selectAll();
+    RefPtr<ClearTextCommand> clearCommand = adoptRef(new ClearTextCommand(*frame->document()));
+    clearCommand->setStartingSelection(oldSelection);
+    applyCommand(clearCommand.release());
+}
+#endif
+
 using namespace HTMLNames;
 using namespace WTF;
 using namespace Unicode;
@@ -218,7 +260,15 @@ bool Editor::handleTextEvent(TextEvent* event)
 
     if (event->isPaste()) {
         if (event->pastingFragment())
+#if PLATFORM(IOS)
+        {
+            if (client()->performsTwoStepPaste(event->pastingFragment()))
+                return true;
+#endif
             replaceSelectionWithFragment(event->pastingFragment(), false, event->shouldSmartReplace(), event->shouldMatchStyle());
+#if PLATFORM(IOS)
+        }
+#endif
         else 
             replaceSelectionWithText(event->data(), false, event->shouldSmartReplace());
         return true;
@@ -391,6 +441,84 @@ void Editor::deleteSelectionWithSmartDelete(bool smartDelete)
     applyCommand(DeleteSelectionCommand::create(document(), smartDelete));
 }
 
+#if PLATFORM(IOS)
+void Editor::clearText()
+{
+    ClearTextCommand::CreateAndApply(&m_frame);
+}
+
+void Editor::insertDictationPhrases(PassOwnPtr<Vector<Vector<String> > > dictationPhrases, RetainPtr<id> metadata)
+{
+    if (m_frame.selection().isNone())
+        return;
+        
+    if (dictationPhrases->isEmpty())
+        return;
+        
+    applyCommand(DictationCommandIOS::create(document(), dictationPhrases, metadata));
+}
+
+void Editor::setDictationPhrasesAsChildOfElement(PassOwnPtr<Vector<Vector<String> > > dictationPhrases, RetainPtr<id> metadata, Element* element)
+{
+    // Clear the composition.
+    clear();
+    
+    // Clear the Undo stack, since the operations that follow are not Undoable, and will corrupt the stack.  Some day
+    // we could make them Undoable, and let callers clear the Undo stack explicitly if they wish.
+    clearUndoRedoOperations();
+    
+    m_frame.selection().clear();
+    
+    element->removeChildren();
+    
+    if (dictationPhrases->isEmpty()) {
+        client()->respondToChangedContents();
+        return;
+    }
+    
+    ExceptionCode ec;    
+    RefPtr<Range> context = document().createRange();
+    context->selectNodeContents(element, ec);
+    
+    StringBuilder dictationPhrasesBuilder;
+    size_t dictationPhraseCount = dictationPhrases->size();
+    for (size_t i = 0; i < dictationPhraseCount; i++) {
+        const String& firstInterpretation = dictationPhrases->at(i)[0];
+        dictationPhrasesBuilder.append(firstInterpretation);
+    }
+    String serializedDictationPhrases = dictationPhrasesBuilder.toString();
+    
+    element->appendChild(createFragmentFromText(*context.get(), serializedDictationPhrases), ec);
+    
+    // We need a layout in order to add markers below.
+    document().updateLayout();
+    
+    if (!element->firstChild()->isTextNode()) {
+        // Shouldn't happen.
+        ASSERT(element->firstChild()->isTextNode());
+        return;
+    }
+        
+    Text* textNode = static_cast<Text*>(element->firstChild());
+    int previousDictationPhraseStart = 0;
+    for (size_t i = 0; i < dictationPhraseCount; i++) {
+        const Vector<String>& interpretations = dictationPhrases->at(i);
+        int dictationPhraseLength = interpretations[0].length();
+        int dictationPhraseEnd = previousDictationPhraseStart + dictationPhraseLength;
+        if (interpretations.size() > 1) {
+            RefPtr<Range> dictationPhraseRange = Range::create(document(), textNode, previousDictationPhraseStart, textNode, dictationPhraseEnd);
+            document().markers().addDictationPhraseWithAlternativesMarker(dictationPhraseRange.get(), interpretations);
+        }
+        previousDictationPhraseStart = dictationPhraseEnd;
+    }
+    
+    RefPtr<Range> resultRange = Range::create(document(), textNode, 0, textNode, textNode->length());
+    document().markers().addDictationResultMarker(resultRange.get(), metadata);
+    
+    client()->respondToChangedContents();
+}
+#endif
+
 void Editor::pasteAsPlainText(const String& pastingText, bool smartReplace)
 {
     Node* target = findEventTargetFromSelection();
@@ -507,6 +635,86 @@ PassRefPtr<Range> Editor::selectedRange()
     return m_frame.selection().toNormalizedRange();
 }
 
+#if PLATFORM(IOS)
+void Editor::confirmMarkedText()
+{
+    // FIXME: This is a hacky workaround for the keyboard calling this method too late -
+    // after the selection and focus have already changed.  See <rdar://problem/5975559>
+    Element* focused = document().focusedElement();
+    Node* composition = compositionNode();
+    
+    if (composition && focused && focused != composition && !composition->isDescendantOrShadowDescendantOf(focused)) {
+        cancelComposition();
+        document().setFocusedElement(focused);
+    } else
+        confirmComposition();
+}
+
+void Editor::setTextAsChildOfElement(const String& text, Element* elem)
+{
+    // Clear the composition
+    clear();
+    
+    // Clear the Undo stack, since the operations that follow are not Undoable, and will corrupt the stack.  Some day
+    // we could make them Undoable, and let callers clear the Undo stack explicitly if they wish.
+    clearUndoRedoOperations();
+    
+    // If the element is empty already and we're not adding text, we can early return and avoid clearing/setting
+    // a selection at [0, 0] and the expense involved in creation VisiblePositions.
+    if (!elem->firstChild() && text.isEmpty())
+        return;
+    
+    // As a side effect this function sets a caret selection after the inserted content.  Much of what 
+    // follows is more expensive if there is a selection, so clear it since it's going to change anyway.
+    m_frame.selection().clear();
+    
+    // clear out all current children of element
+    elem->removeChildren();
+
+    if (text.length()) {
+        // insert new text
+        // remove element from tree while doing it
+        // FIXME: The element we're inserting into is often the body element.  It seems strange to be removing it
+        // (even if it is only temporary).  ReplaceSelectionCommand doesn't bother doing this when it inserts
+        // content, why should we here?
+        ExceptionCode ec;
+        RefPtr<Node> parent = elem->parentNode();
+        RefPtr<Node> siblingAfter = elem->nextSibling();
+        if (parent)
+            elem->remove(ec);    
+            
+        RefPtr<Range> context = document().createRange();
+        context->selectNodeContents(elem, ec);
+        RefPtr<DocumentFragment> fragment = createFragmentFromText(*context.get(), text);
+        elem->appendChild(fragment, ec);
+    
+        // restore element to document
+        if (parent) {
+            if (siblingAfter)
+                parent->insertBefore(elem, siblingAfter.get(), ec);
+            else
+                parent->appendChild(elem, ec);
+        }
+    }
+
+    // set the selection to the end
+    VisibleSelection selection;
+
+    Position pos = createLegacyEditingPosition(elem, elem->childNodeCount());
+
+    VisiblePosition visiblePos(pos, VP_DEFAULT_AFFINITY);
+    if (visiblePos.isNull())
+        return;
+
+    selection.setBase(visiblePos);
+    selection.setExtent(visiblePos);
+     
+    m_frame.selection().setSelection(selection);
+    
+    client()->respondToChangedContents();
+}
+#endif
+
 bool Editor::shouldDeleteRange(Range* range) const
 {
     if (!range || range->collapsed(IGNORE_EXCEPTION))
@@ -546,6 +754,12 @@ bool Editor::shouldInsertText(const String& text, Range* range, EditorInsertActi
 
 void Editor::notifyComponentsOnChangedSelection(const VisibleSelection& oldSelection, FrameSelection::SetSelectionOptions options)
 {
+#if PLATFORM(IOS)
+    // FIXME: Merge this to open source https://bugs.webkit.org/show_bug.cgi?id=38830
+    if (m_ignoreCompositionSelectionChange)
+        return;
+#endif
+
     if (client())
         client()->respondToChangedSelection(&m_frame);
     setStartNewKillRingSequence(true);
@@ -704,6 +918,14 @@ void Editor::clearLastEditCommand()
 {
     m_lastEditCommand.clear();
 }
+#if PLATFORM(IOS)
+// If the selection is adjusted from UIKit without closing the typing, the typing command may
+// have a stale selection.
+void Editor::ensureLastEditCommandHasCurrentSelectionIfOpenForMoreTyping()
+{
+    TypingCommand::ensureLastEditCommandHasCurrentSelectionIfOpenForMoreTyping(&m_frame, m_frame.selection().selection());
+}
+#endif
 
 // Returns whether caller should continue with "the default processing", which is the same as 
 // the event handler NOT setting the return value to false
@@ -1088,13 +1310,13 @@ void Editor::copy()
             canSmartCopyOrDelete() ? Pasteboard::CanSmartReplace : Pasteboard::CannotSmartReplace);
     } else {
         if (HTMLImageElement* imageElement = imageElementFromImageDocument(document())) {
-#if (PLATFORM(MAC) && !PLATFORM(IOS)) || PLATFORM(EFL) || PLATFORM(NIX)
+#if PLATFORM(MAC) || PLATFORM(EFL) || PLATFORM(NIX)
             writeImageToPasteboard(*Pasteboard::createForCopyAndPaste(), *imageElement, document().url(), document().title());
 #else
             Pasteboard::createForCopyAndPaste()->writeImage(*imageElement, document().url(), document().title());
 #endif
         } else {
-#if (PLATFORM(MAC) && !PLATFORM(IOS)) || PLATFORM(EFL) || PLATFORM(NIX)
+#if PLATFORM(MAC) || PLATFORM(EFL) || PLATFORM(NIX)
             writeSelectionToPasteboard(*Pasteboard::createForCopyAndPaste());
 #else
             // FIXME: Convert all other platforms to match Mac and delete this.
@@ -1169,6 +1391,7 @@ void Editor::simplifyMarkup(Node* startNode, Node* endNode)
     applyCommand(SimplifyMarkupCommand::create(document(), startNode, (endNode) ? NodeTraversal::next(endNode) : 0));
 }
 
+#if !PLATFORM(IOS)
 void Editor::copyURL(const URL& url, const String& title)
 {
     copyURL(url, title, *Pasteboard::createForCopyAndPaste());
@@ -1203,6 +1426,7 @@ void Editor::copyImage(const HitTestResult& result)
     Pasteboard::createForCopyAndPaste()->writeImage(*element, url, result.altDisplayString());
 #endif
 }
+#endif
 
 bool Editor::isContinuousSpellCheckingEnabled() const
 {
@@ -1413,6 +1637,12 @@ void Editor::toggleUnderline()
 
 void Editor::setBaseWritingDirection(WritingDirection direction)
 {
+#if PLATFORM(IOS)
+    if (inSameParagraph(m_frame.selection().selection().visibleStart(), m_frame.selection().selection().visibleEnd()) && 
+        baseWritingDirectionForSelectionStart() == direction)
+        return;
+#endif
+        
     Element* focusedElement = document().focusedElement();
     if (focusedElement && isHTMLTextFormControlElement(*focusedElement)) {
         if (direction == NaturalWritingDirection)
@@ -1561,6 +1791,10 @@ void Editor::setComposition(const String& text, const Vector<CompositionUnderlin
         return;
     }
 
+#if PLATFORM(IOS)
+    client()->startDelayingAndCoalescingContentChangeNotifications();
+#endif
+
     Element* target = document().focusedElement();
     if (target) {
         // Dispatch an appropriate composition event to the focused node.
@@ -1636,6 +1870,10 @@ void Editor::setComposition(const String& text, const Vector<CompositionUnderlin
     }
 
     setIgnoreCompositionSelectionChange(false);
+
+#if PLATFORM(IOS)        
+    client()->stopDelayingAndCoalescingContentChangeNotifications();
+#endif
 }
 
 void Editor::ignoreSpelling()
@@ -1668,6 +1906,7 @@ void Editor::learnSpelling()
     textChecker()->learnWord(text);
 }
 
+#if !PLATFORM(IOS)
 void Editor::advanceToNextMisspelling(bool startBeforeSelection)
 {
     // The basic approach is to search in two phases - from the selection end to the end of the doc, and
@@ -1840,6 +2079,7 @@ void Editor::advanceToNextMisspelling(bool startBeforeSelection)
         document().markers().addMarker(misspellingRange.get(), DocumentMarker::Spelling);
     }
 }
+#endif // !PLATFORM(IOS)
 
 String Editor::misspelledWordAtCaretOrRange(Node* clickedNode) const
 {
@@ -1954,8 +2194,10 @@ void Editor::showSpellingGuessPanel()
         client()->showSpellingUI(false);
         return;
     }
-    
+
+#if !PLATFORM(IOS)
     advanceToNextMisspelling(true);
+#endif
     client()->showSpellingUI(true);
 }
 
@@ -1982,6 +2224,18 @@ void Editor::markMisspellingsAndBadGrammar(const VisibleSelection &movingSelecti
 
 void Editor::markMisspellingsAfterTypingToWord(const VisiblePosition &wordStart, const VisibleSelection& selectionAfterTyping, bool doReplacement)
 {
+#if PLATFORM(IOS)
+    UNUSED_PARAM(selectionAfterTyping);
+    UNUSED_PARAM(doReplacement);
+    TextCheckingTypeMask textCheckingOptions = 0;
+    if (isContinuousSpellCheckingEnabled())
+        textCheckingOptions |= TextCheckingTypeSpelling;
+    if (!(textCheckingOptions & TextCheckingTypeSpelling))
+        return;
+
+    VisibleSelection adjacentWords = VisibleSelection(startOfWord(wordStart, LeftWordIfOnBoundary), endOfWord(wordStart, RightWordIfOnBoundary));
+    markAllMisspellingsAndBadGrammarInRanges(textCheckingOptions, adjacentWords.toNormalizedRange().get(), adjacentWords.toNormalizedRange().get());
+#else
 #if !USE(AUTOMATIC_TEXT_REPLACEMENT)
     UNUSED_PARAM(doReplacement);
 #endif
@@ -2056,10 +2310,12 @@ void Editor::markMisspellingsAfterTypingToWord(const VisiblePosition &wordStart,
     
     // Check grammar of entire sentence
     markBadGrammar(VisibleSelection(startOfSentence(wordStart), endOfSentence(wordStart)));
+#endif
 }
     
 void Editor::markMisspellingsOrBadGrammar(const VisibleSelection& selection, bool checkSpelling, RefPtr<Range>& firstMisspellingRange)
 {
+#if !PLATFORM(IOS)
     // This function is called with a selection already expanded to word boundaries.
     // Might be nice to assert that here.
     
@@ -2095,6 +2351,11 @@ void Editor::markMisspellingsOrBadGrammar(const VisibleSelection& selection, boo
         ASSERT_NOT_REACHED();
 #endif
     }    
+#else
+        UNUSED_PARAM(selection);
+        UNUSED_PARAM(checkSpelling);
+        UNUSED_PARAM(firstMisspellingRange);
+#endif // !PLATFORM(IOS)
 }
 
 bool Editor::isSpellCheckingEnabledFor(Node* node) const
@@ -2372,6 +2633,7 @@ void Editor::markAndReplaceFor(PassRefPtr<SpellCheckRequest> request, const Vect
 
 void Editor::changeBackToReplacedString(const String& replacedString)
 {
+#if !PLATFORM(IOS)
     ASSERT(unifiedTextCheckerEnabled());
 
     if (replacedString.isEmpty())
@@ -2387,6 +2649,10 @@ void Editor::changeBackToReplacedString(const String& replacedString)
     RefPtr<Range> changedRange = paragraph.subrange(paragraph.checkingStart(), replacedString.length());
     changedRange->startContainer()->document().markers().addMarker(changedRange.get(), DocumentMarker::Replacement, String());
     m_alternativeTextController->markReversed(changedRange.get());
+#else
+    ASSERT_NOT_REACHED();
+    UNUSED_PARAM(replacedString);
+#endif // !PLATFORM(IOS)
 }
 
 
@@ -2487,7 +2753,11 @@ void Editor::updateMarkersForWordsAffectedByEditing(bool doNotRemoveIfSelectionA
     for (size_t i = 0; i < markers.size(); ++i)
         m_alternativeTextController->removeDictationAlternativesForMarker(markers[i]);
 
+#if PLATFORM(IOS)
+    document().markers().removeMarkers(wordRange.get(), DocumentMarker::Spelling | DocumentMarker::CorrectionIndicator | DocumentMarker::SpellCheckingExemption | DocumentMarker::DictationAlternatives | DocumentMarker::DictationPhraseWithAlternatives, DocumentMarkerController::RemovePartiallyOverlappingMarker);
+#else
     document().markers().removeMarkers(wordRange.get(), DocumentMarker::Spelling | DocumentMarker::Grammar | DocumentMarker::CorrectionIndicator | DocumentMarker::SpellCheckingExemption | DocumentMarker::DictationAlternatives, DocumentMarkerController::RemovePartiallyOverlappingMarker);
+#endif
     document().markers().clearDescriptionOnMarkersIntersectingRange(wordRange.get(), DocumentMarker::Replacement);
 }
 
@@ -2527,6 +2797,11 @@ void Editor::setIgnoreCompositionSelectionChange(bool ignore)
         return;
 
     m_ignoreCompositionSelectionChange = ignore;
+#if PLATFORM(IOS)
+    // FIXME: Merge this to open source https://bugs.webkit.org/show_bug.cgi?id=38830
+    if (!ignore)
+        notifyComponentsOnChangedSelection(m_frame.selection().selection(), 0);
+#endif
     if (!ignore)
         revealSelectionAfterEditingOperation(ScrollAlignment::alignToEdgeIfNeeded, RevealExtent);
 }
@@ -2656,6 +2931,11 @@ void Editor::changeSelectionAfterCommand(const VisibleSelection& newSelection,
     // change the caret's DOM position (["hello", 0]). In these situations the above FrameSelection::setSelection call
     // does not call EditorClient::respondToChangedSelection(), which, on the Mac, sends selection change notifications and
     // starts a new kill ring sequence, but we want to do these things (matches AppKit).
+#if PLATFORM(IOS)
+    // FIXME: Merge this to open source https://bugs.webkit.org/show_bug.cgi?id=38830
+    if (m_ignoreCompositionSelectionChange)
+        return;
+#endif
     if (selectionDidNotChangeDOMPosition && client())
         client()->respondToChangedSelection(&m_frame);
 }
@@ -2727,6 +3007,10 @@ IntRect Editor::firstRectForRange(Range* range) const
 
 bool Editor::shouldChangeSelection(const VisibleSelection& oldSelection, const VisibleSelection& newSelection, EAffinity affinity, bool stillSelecting) const
 {
+#if PLATFORM(IOS)
+    if (m_frame.selectionChangeCallbacksDisabled())
+        return true;
+#endif
     return client() && client()->shouldChangeSelectedRange(oldSelection.toNormalizedRange().get(), newSelection.toNormalizedRange().get(), affinity, stillSelecting);
 }
 
@@ -3021,7 +3305,20 @@ void Editor::respondToChangedSelection(const VisibleSelection& oldSelection, Fra
         bool caretBrowsing = m_frame.settings().caretBrowsingEnabled();
         if (m_frame.selection().selection().isContentEditable() || caretBrowsing) {
             VisiblePosition newStart(m_frame.selection().selection().visibleStart());
+#if !PLATFORM(IOS)
             newAdjacentWords = VisibleSelection(startOfWord(newStart, LeftWordIfOnBoundary), endOfWord(newStart, RightWordIfOnBoundary));
+#else
+            // If this bug gets fixed, this PLATFORM(IOS) code could be removed:
+            // <rdar://problem/7259611> Word boundary code on iPhone gives different results than desktop
+            EWordSide startWordSide = LeftWordIfOnBoundary;
+            UChar32 c = newStart.characterBefore();
+            // FIXME: VisiblePosition::characterAfter() and characterBefore() do not emit newlines the same
+            // way as TextIterator, so we do an isStartOfParagraph check here.
+            if (isSpaceOrNewline(c) || c == 0xA0 || isStartOfParagraph(newStart)) {
+                startWordSide = RightWordIfOnBoundary;
+            }
+            newAdjacentWords = VisibleSelection(startOfWord(newStart, startWordSide), endOfWord(newStart, RightWordIfOnBoundary));
+#endif // !PLATFORM(IOS)
             if (isContinuousGrammarCheckingEnabled)
                 newSelectedSentence = VisibleSelection(startOfSentence(newStart), endOfSentence(newStart));
         }
@@ -3103,14 +3400,17 @@ TextCheckingTypeMask Editor::resolveTextCheckingTypeMask(TextCheckingTypeMask te
 {
     bool shouldMarkSpelling = textCheckingOptions & TextCheckingTypeSpelling;
     bool shouldMarkGrammar = textCheckingOptions & TextCheckingTypeGrammar;
+#if !PLATFORM(IOS)
     bool shouldShowCorrectionPanel = textCheckingOptions & TextCheckingTypeShowCorrectionPanel;
     bool shouldCheckForCorrection = shouldShowCorrectionPanel || (textCheckingOptions & TextCheckingTypeCorrection);
+#endif
 
     TextCheckingTypeMask checkingTypes = 0;
     if (shouldMarkSpelling)
         checkingTypes |= TextCheckingTypeSpelling;
     if (shouldMarkGrammar)
         checkingTypes |= TextCheckingTypeGrammar;
+#if !PLATFORM(IOS)
     if (shouldCheckForCorrection)
         checkingTypes |= TextCheckingTypeCorrection;
     if (shouldShowCorrectionPanel)
@@ -3131,6 +3431,7 @@ TextCheckingTypeMask Editor::resolveTextCheckingTypeMask(TextCheckingTypeMask te
             checkingTypes |= TextCheckingTypeCorrection;
     }
 #endif
+#endif // !PLATFORM(IOS)
 
     return checkingTypes;
 }
index d9bb5c5..20e174b 100644 (file)
@@ -126,9 +126,11 @@ public:
     void pasteAsPlainText();
     void performDelete();
 
+#if !PLATFORM(IOS)
     void copyURL(const URL&, const String& title);
     void copyURL(const URL&, const String& title, Pasteboard&);
     void copyImage(const HitTestResult&);
+#endif
 
     String readPlainTextFromPasteboard(Pasteboard&);
 
@@ -161,9 +163,17 @@ public:
     void removeFormattingAndStyle();
 
     void clearLastEditCommand();
+#if PLATFORM(IOS)
+    void ensureLastEditCommandHasCurrentSelectionIfOpenForMoreTyping();
+#endif
 
     bool deleteWithDirection(SelectionDirection, TextGranularity, bool killRing, bool isTypingAction);
     void deleteSelectionWithSmartDelete(bool smartDelete);
+#if PLATFORM(IOS)
+    void clearText();
+    void removeUnchangeableStyles();
+#endif
+    
     bool dispatchCPPEvent(const AtomicString&, ClipboardAccessPolicy);
     
     void applyStyle(StyleProperties*, EditAction = EditActionUnspecified);
@@ -235,9 +245,14 @@ public:
     void toggleOverwriteModeEnabled();
 
     void markAllMisspellingsAndBadGrammarInRanges(TextCheckingTypeMask, Range* spellingRange, Range* grammarRange);
+#if PLATFORM(IOS)
+    NO_RETURN_DUE_TO_ASSERT
+#endif
     void changeBackToReplacedString(const String& replacedString);
 
+#if !PLATFORM(IOS)
     void advanceToNextMisspelling(bool startBeforeSelection = false);
+#endif // !PLATFORM(IOS)
     void showSpellingGuessPanel();
     bool spellingPanelIsShowing();
 
@@ -303,6 +318,14 @@ public:
     EditingBehavior behavior() const;
 
     PassRefPtr<Range> selectedRange();
+
+#if PLATFORM(IOS)
+    void confirmMarkedText();
+    void setTextAsChildOfElement(const String&, Element*);
+    void setTextAlignmentForChangedBaseWritingDirection(WritingDirection);
+    void insertDictationPhrases(PassOwnPtr<Vector<Vector<String> > > dictationPhrases, RetainPtr<id> metadata);
+    void setDictationPhrasesAsChildOfElement(PassOwnPtr<Vector<Vector<String> > > dictationPhrases, RetainPtr<id> metadata, Element* element);
+#endif
     
     void addToKillRing(Range*, bool prepend);
 
@@ -400,13 +423,15 @@ public:
     bool insertParagraphSeparatorInQuotedContent();
     const SimpleFontData* fontForSelection(bool&) const;
     NSDictionary* fontAttributesForSelectionStart() const;
+    String stringSelectionForPasteboard();
+    String stringSelectionForPasteboardWithImageAltText();
+    PassRefPtr<DocumentFragment> webContentFromPasteboard(Pasteboard&, Range& context, bool allowPlainText, bool& chosePlainText);
+#if !PLATFORM(IOS)
     bool canCopyExcludingStandaloneImages();
     void takeFindStringFromSelection();
     void readSelectionFromPasteboard(const String& pasteboardName);
-    String stringSelectionForPasteboard();
-    String stringSelectionForPasteboardWithImageAltText();
     PassRefPtr<SharedBuffer> dataSelectionForPasteboard(const String& pasteboardName);
-    PassRefPtr<DocumentFragment> webContentFromPasteboard(Pasteboard&, Range& context, bool allowPlainText, bool& chosePlainText);
+#endif // !PLATFORM(IOS)
 #endif
 
 #if PLATFORM(MAC) || PLATFORM(EFL) || PLATFORM(NIX)
index 0150635..2be3d48 100644 (file)
@@ -302,6 +302,14 @@ static bool executeCut(Frame& frame, Event*, EditorCommandSource source, const S
     return true;
 }
 
+#if PLATFORM(IOS)
+static bool executeClearText(Frame& frame, Event*, EditorCommandSource, const String&)
+{
+    frame.editor().clearText();
+    return true;
+}
+#endif
+
 static bool executeDefaultParagraphSeparator(Frame& frame, Event*, EditorCommandSource, const String& value)
 {
     if (equalIgnoringCase(value, "div"))
@@ -1093,7 +1101,7 @@ static bool executeSwapWithMark(Frame& frame, Event*, EditorCommandSource, const
     return true;
 }
 
-#if PLATFORM(MAC)
+#if PLATFORM(MAC) && !PLATFORM(IOS)
 static bool executeTakeFindStringFromSelection(Frame& frame, Event*, EditorCommandSource, const String&)
 {
     frame.editor().takeFindStringFromSelection();
@@ -1237,13 +1245,29 @@ static bool enableCaretInEditableText(Frame& frame, Event* event, EditorCommandS
 
 static bool enabledCopy(Frame& frame, Event*, EditorCommandSource)
 {
+#if !PLATFORM(IOS)
     return frame.editor().canDHTMLCopy() || frame.editor().canCopy();
+#else
+    return frame.editor().canCopy();
+#endif
 }
 
 static bool enabledCut(Frame& frame, Event*, EditorCommandSource)
 {
+#if !PLATFORM(IOS)
     return frame.editor().canDHTMLCut() || frame.editor().canCut();
+#else
+    return frame.editor().canCut();
+#endif
+}
+
+#if PLATFORM(IOS)
+static bool enabledClearText(Frame& frame, Event*, EditorCommandSource)
+{
+    UNUSED_PARAM(frame);
+    return false;
 }
+#endif
 
 static bool enabledInEditableText(Frame& frame, Event* event, EditorCommandSource)
 {
@@ -1296,7 +1320,7 @@ static bool enabledRedo(Frame& frame, Event*, EditorCommandSource)
     return frame.editor().canRedo();
 }
 
-#if PLATFORM(MAC)
+#if PLATFORM(MAC) && !PLATFORM(IOS)
 static bool enabledTakeFindStringFromSelection(Frame& frame, Event*, EditorCommandSource)
 {
     return frame.editor().canCopyExcludingStandaloneImages();
@@ -1603,9 +1627,16 @@ static const CommandMap& createCommandMap()
         { "PasteGlobalSelection", { executePasteGlobalSelection, supportedFromMenuOrKeyBinding, enabledPaste, stateNone, valueNull, notTextInsertion, allowExecutionWhenDisabled } },
 #endif
 
-#if PLATFORM(MAC)
+#if PLATFORM(MAC) && !PLATFORM(IOS)
         { "TakeFindStringFromSelection", { executeTakeFindStringFromSelection, supportedFromMenuOrKeyBinding, enabledTakeFindStringFromSelection, stateNone, valueNull, notTextInsertion, doNotAllowExecutionWhenDisabled } },
 #endif
+#if PLATFORM(IOS)
+        { "ClearText", { executeClearText, supported, enabledClearText, stateNone, valueNull, notTextInsertion, allowExecutionWhenDisabled } },
+#endif
+
+#if PLATFORM(GTK) || PLATFORM(QT)
+        { "PasteGlobalSelection", { executePasteGlobalSelection, supportedFromMenuOrKeyBinding, enabledPaste, stateNone, valueNull, notTextInsertion, allowExecutionWhenDisabled } },
+#endif
     };
 
     // These unsupported commands are listed here since they appear in the Microsoft
index 4b1e67d..4a0883e 100644 (file)
 #include <stdio.h>
 #include <wtf/text/CString.h>
 
+#if PLATFORM(IOS)
+#include "Chrome.h"
+#include "ChromeClient.h"
+#include "Color.h"
+#include "RenderLayer.h"
+#include "RenderObject.h"
+#include "RenderStyle.h"
+#endif
+
 #define EDIT_DEBUG 0
 
 namespace WebCore {
@@ -107,6 +116,12 @@ FrameSelection::FrameSelection(Frame* frame)
     , m_isCaretBlinkingSuspended(false)
     , m_focused(frame && frame->page() && frame->page()->focusController().focusedFrame() == frame)
     , m_shouldShowBlockCursor(false)
+#if PLATFORM(IOS)
+    , m_updateAppearanceEnabled(false)
+    , m_caretBlinks(true)
+    , m_closeTypingSuppressions(0)
+    , m_scrollingSuppressCount(0)
+#endif
 {
     if (shouldAlwaysUseDirectionalSelection(m_frame))
         m_selection.setIsDirectional(true);
@@ -268,7 +283,11 @@ void FrameSelection::setSelection(const VisibleSelection& newSelection, SetSelec
 
     m_granularity = granularity;
 
+#if PLATFORM(IOS)
+    if (closeTyping && m_closeTypingSuppressions == 0)
+#else
     if (closeTyping)
+#endif
         TypingCommand::closeTyping(m_frame);
 
     if (shouldClearTypingStyle)
@@ -620,6 +639,11 @@ VisiblePosition FrameSelection::modifyExtendingRight(TextGranularity granularity
         // FIXME: implement all of the above?
         pos = modifyExtendingForward(granularity);
         break;
+#if PLATFORM(IOS)
+    case DocumentGranularity:
+        ASSERT_NOT_REACHED();
+        break;
+#endif
     }
 #if ENABLE(USERSELECT_ALL)
     adjustPositionForUserSelectAll(pos, directionOfEnclosingBlock() == LTR);
@@ -646,6 +670,11 @@ VisiblePosition FrameSelection::modifyExtendingForward(TextGranularity granulari
     case ParagraphGranularity:
         pos = nextParagraphPosition(pos, lineDirectionPointForBlockDirectionNavigation(EXTENT));
         break;
+#if PLATFORM(IOS)
+    case DocumentGranularity:
+        ASSERT_NOT_REACHED();
+        break;
+#endif
     case SentenceBoundary:
         pos = endOfSentence(endForPlatform());
         break;
@@ -703,6 +732,11 @@ VisiblePosition FrameSelection::modifyMovingRight(TextGranularity granularity)
     case LineBoundary:
         pos = rightBoundaryOfLine(startForPlatform(), directionOfEnclosingBlock());
         break;
+#if PLATFORM(IOS)
+    case DocumentGranularity:
+        ASSERT_NOT_REACHED();
+        break;
+#endif
     }
     return pos;
 }
@@ -735,6 +769,11 @@ VisiblePosition FrameSelection::modifyMovingForward(TextGranularity granularity)
     case ParagraphGranularity:
         pos = nextParagraphPosition(endForPlatform(), lineDirectionPointForBlockDirectionNavigation(START));
         break;
+#if PLATFORM(IOS)
+    case DocumentGranularity:
+        ASSERT_NOT_REACHED();
+        break;
+#endif
     case SentenceBoundary:
         pos = endOfSentence(endForPlatform());
         break;
@@ -791,6 +830,11 @@ VisiblePosition FrameSelection::modifyExtendingLeft(TextGranularity granularity)
     case DocumentBoundary:
         pos = modifyExtendingBackward(granularity);
         break;
+#if PLATFORM(IOS)
+    case DocumentGranularity:
+        ASSERT_NOT_REACHED();
+        break;
+#endif
     }
 #if ENABLE(USERSELECT_ALL)
     adjustPositionForUserSelectAll(pos, !(directionOfEnclosingBlock() == LTR));
@@ -838,6 +882,11 @@ VisiblePosition FrameSelection::modifyExtendingBackward(TextGranularity granular
         else
             pos = startOfDocument(pos);
         break;
+#if PLATFORM(IOS)
+    case DocumentGranularity:
+        ASSERT_NOT_REACHED();
+        break;
+#endif
     }
 #if ENABLE(USERSELECT_ALL)
     adjustPositionForUserSelectAll(pos, !(directionOfEnclosingBlock() == LTR));
@@ -877,6 +926,11 @@ VisiblePosition FrameSelection::modifyMovingLeft(TextGranularity granularity)
     case LineBoundary:
         pos = leftBoundaryOfLine(startForPlatform(), directionOfEnclosingBlock());
         break;
+#if PLATFORM(IOS)
+    case DocumentGranularity:
+        ASSERT_NOT_REACHED();
+        break;
+#endif
     }
     return pos;
 }
@@ -919,6 +973,11 @@ VisiblePosition FrameSelection::modifyMovingBackward(TextGranularity granularity
         else
             pos = startOfDocument(pos);
         break;
+#if PLATFORM(IOS)
+    case DocumentGranularity:
+        ASSERT_NOT_REACHED();
+        break;
+#endif
     }
     return pos;
 }
@@ -1668,6 +1727,12 @@ bool FrameSelection::setSelectedRange(Range* range, EAffinity affinity, bool clo
     // FIXME: Can we provide extentAffinity?
     VisiblePosition visibleStart(range->startPosition(), collapsed ? affinity : DOWNSTREAM);
     VisiblePosition visibleEnd(range->endPosition(), SEL_DEFAULT_AFFINITY);
+#if PLATFORM(IOS)
+    if (range->startContainer() && visibleStart.isNull())
+        return false;
+    if (range->endContainer() && visibleEnd.isNull())
+        return false;
+#endif
     setSelection(VisibleSelection(visibleStart, visibleEnd), ClearTypingStyle | (closeTyping ? CloseTyping : 0));
     return true;
 }
@@ -1685,6 +1750,12 @@ void FrameSelection::focusedOrActiveStateChanged()
 
     document->updateStyleIfNeeded();
 
+#if USE(UIKIT_EDITING)
+    // Caret blinking (blinks | does not blink)
+    if (activeAndFocused)
+        setSelectionFromNone();
+    setCaretVisible(activeAndFocused);
+#else
     // Because RenderObject::selectionBackgroundColor() and
     // RenderObject::selectionForegroundColor() check if the frame is active,
     // we have to update places those colors were painted.
@@ -1708,6 +1779,7 @@ void FrameSelection::focusedOrActiveStateChanged()
             if (renderer && renderer->style().hasAppearance())
                 renderer->theme().stateChanged(renderer, FocusState);
     }
+#endif
 }
 
 void FrameSelection::pageActivationChanged()
@@ -1738,6 +1810,11 @@ inline static bool shouldStopBlinkingDueToTypingCommand(Frame* frame)
 
 void FrameSelection::updateAppearance()
 {
+#if PLATFORM(IOS)
+    if (!m_updateAppearanceEnabled)
+        return;
+#endif
+
     // Paint a block cursor instead of a caret in overtype mode unless the caret is at the end of a line (in this case
     // the FrameSelection will paint a blinking caret as usual).
     VisiblePosition forwardPosition;
@@ -1912,6 +1989,10 @@ PassRefPtr<MutableStyleProperties> FrameSelection::copyTypingStyle() const
 
 bool FrameSelection::shouldDeleteSelection(const VisibleSelection& selection) const
 {
+#if PLATFORM(IOS)
+    if (m_frame->selectionChangeCallbacksDisabled())
+        return true;
+#endif
     return m_frame->editor().client()->shouldDeleteRange(selection.toNormalizedRange().get());
 }
 
@@ -2010,11 +2091,24 @@ void FrameSelection::revealSelection(const ScrollAlignment& alignment, RevealExt
     Position start = this->start();
     ASSERT(start.deprecatedNode());
     if (start.deprecatedNode() && start.deprecatedNode()->renderer()) {
+#if PLATFORM(IOS)
+        if (RenderLayer* layer = start.deprecatedNode()->renderer()->enclosingLayer()) {
+            if (!m_scrollingSuppressCount) {
+                layer->setAdjustForIOSCaretWhenScrolling(true);
+                layer->scrollRectToVisible(rect, alignment, alignment);
+                layer->setAdjustForIOSCaretWhenScrolling(false);
+                updateAppearance();
+                if (m_frame->page())
+                    m_frame->page()->chrome().client().notifyRevealedSelectionByScrollingFrame(m_frame);
+            }
+        }
+#else
         // FIXME: This code only handles scrolling the startContainer's layer, but
         // the selection rect could intersect more than just that.
         // See <rdar://problem/4799899>.
         if (start.deprecatedNode()->renderer()->scrollRectToVisible(rect, alignment, alignment))
             updateAppearance();
+#endif
     }
 }
 
@@ -2024,9 +2118,14 @@ void FrameSelection::setSelectionFromNone()
     // entire WebView is editable or designMode is on for this document).
 
     Document* document = m_frame->document();
+#if !PLATFORM(IOS)
     bool caretBrowsing = m_frame->settings().caretBrowsingEnabled();
     if (!isNone() || !(document->hasEditableStyle() || caretBrowsing))
         return;
+#else
+    if (!document || !(isNone() || isStartOfDocument(VisiblePosition(selection().start(), selection().affinity()))) || !document->rendererIsEditable())
+        return;
+#endif
 
     Node* node = document->documentElement();
     while (node && !node->hasTagName(bodyTag))
@@ -2037,6 +2136,10 @@ void FrameSelection::setSelectionFromNone()
 
 bool FrameSelection::shouldChangeSelection(const VisibleSelection& newSelection) const
 {
+#if PLATFORM(IOS)
+    if (m_frame->selectionChangeCallbacksDisabled())
+        return true;
+#endif
     return m_frame->editor().shouldChangeSelection(selection(), newSelection, newSelection.affinity(), false);
 }
 
@@ -2072,6 +2175,429 @@ void FrameSelection::showTreeForThis() const
 
 #endif
 
+#if PLATFORM(IOS)
+void FrameSelection::expandSelectionToElementContainingCaretSelection()
+{
+    RefPtr<Range> range = elementRangeContainingCaretSelection();
+    if (!range)
+        return;
+    VisibleSelection selection(range.get(), DOWNSTREAM);
+    setSelection(selection);
+}
+
+PassRefPtr<Range> FrameSelection::elementRangeContainingCaretSelection() const
+{
+    if (m_selection.isNone())
+        return nullptr;
+
+    VisibleSelection selection = m_selection;
+    if (selection.isNone())
+        return nullptr;
+
+    VisiblePosition visiblePos(selection.start(), VP_DEFAULT_AFFINITY);
+    if (visiblePos.isNull())
+        return nullptr;
+
+    Node* node = visiblePos.deepEquivalent().deprecatedNode();
+    Element* element = deprecatedEnclosingBlockFlowElement(node);
+    if (!element)
+        return nullptr;
+
+    Position startPos = createLegacyEditingPosition(element, 0);
+    Position endPos = createLegacyEditingPosition(element, element->childNodeCount());
+    
+    VisiblePosition startVisiblePos(startPos, VP_DEFAULT_AFFINITY);
+    VisiblePosition endVisiblePos(endPos, VP_DEFAULT_AFFINITY);
+    if (startVisiblePos.isNull() || endVisiblePos.isNull())
+        return nullptr;
+
+    selection.setBase(startVisiblePos);
+    selection.setExtent(endVisiblePos);
+
+    return selection.toNormalizedRange();
+}
+
+void FrameSelection::expandSelectionToWordContainingCaretSelection()
+{
+    VisibleSelection selection(wordSelectionContainingCaretSelection(m_selection));        
+    if (selection.isCaretOrRange())
+        setSelection(selection);
+}
+
+PassRefPtr<Range> FrameSelection::wordRangeContainingCaretSelection()
+{
+    return wordSelectionContainingCaretSelection(m_selection).toNormalizedRange();
+}
+
+void FrameSelection::expandSelectionToStartOfWordContainingCaretSelection()
+{
+    if (m_selection.isNone() || isStartOfDocument(m_selection.start()))
+        return;
+
+    VisiblePosition s1(m_selection.start());
+    VisiblePosition e1(m_selection.end());
+
+    VisibleSelection expanded(wordSelectionContainingCaretSelection(m_selection));
+    VisiblePosition s2(expanded.start());
+
+    // Don't allow the start to become greater after the expansion.
+    if (s2.isNull() || s2 > s1)
+        s2 = s1;
+
+    moveTo(s2, e1);
+}
+
+UChar FrameSelection::characterInRelationToCaretSelection(int amount) const
+{
+    if (m_selection.isNone())
+        return 0;
+
+    VisibleSelection selection = m_selection;
+    ASSERT(selection.isCaretOrRange());
+
+    VisiblePosition visiblePosition(selection.start(), VP_DEFAULT_AFFINITY);
+
+    if (amount < 0) {
+        int count = abs(amount);
+        for (int i = 0; i < count; i++)
+            visiblePosition = visiblePosition.previous();    
+        return visiblePosition.characterBefore();
+    }
+    for (int i = 0; i < amount; i++)
+        visiblePosition = visiblePosition.next();    
+    return visiblePosition.characterAfter();
+}
+
+UChar FrameSelection::characterBeforeCaretSelection() const
+{
+    if (m_selection.isNone())
+        return 0;
+
+    VisibleSelection selection = m_selection;
+    ASSERT(selection.isCaretOrRange());
+
+    VisiblePosition visiblePosition(selection.start(), VP_DEFAULT_AFFINITY);
+    return visiblePosition.characterBefore();
+}
+
+UChar FrameSelection::characterAfterCaretSelection() const
+{
+    if (m_selection.isNone())
+        return 0;
+
+    VisibleSelection selection = m_selection;
+    ASSERT(selection.isCaretOrRange());
+
+    VisiblePosition visiblePosition(selection.end(), VP_DEFAULT_AFFINITY);
+    return visiblePosition.characterAfter();
+}
+
+int FrameSelection::wordOffsetInRange(const Range *range) const
+{
+    if (!range)
+        return -1;
+
+    VisibleSelection selection = m_selection;
+    if (!selection.isCaret())
+        return -1;
+
+    // FIXME: This will only work in cases where the selection remains in
+    // the same node after it is expanded. Improve to handle more complicated
+    // cases.
+    ExceptionCode ec = 0;
+    int result = selection.start().deprecatedEditingOffset() - range->startOffset(ec);
+    ASSERT(!ec);
+    if (result < 0)
+        result = 0;
+    return result;
+}
+
+bool FrameSelection::spaceFollowsWordInRange(const Range *range) const
+{
+    if (!range)
+        return false;
+    ExceptionCode ec = 0;
+    Node* node = range->endContainer(ec);
+    ASSERT(!ec);
+    int endOffset = range->endOffset(ec);
+    ASSERT(!ec);
+    VisiblePosition pos(createLegacyEditingPosition(node, endOffset), VP_DEFAULT_AFFINITY);
+    return isSpaceOrNewline(pos.characterAfter());
+}
+
+bool FrameSelection::selectionAtDocumentStart() const
+{
+    VisibleSelection selection = m_selection;
+    if (selection.isNone())
+        return false;
+
+    Position startPos(selection.start());
+    VisiblePosition pos(createLegacyEditingPosition(startPos.deprecatedNode(), startPos.deprecatedEditingOffset()), VP_DEFAULT_AFFINITY);
+    if (pos.isNull())
+        return false;
+
+    return isStartOfDocument(pos);
+}
+
+bool FrameSelection::selectionAtSentenceStart() const
+{
+    VisibleSelection selection = m_selection;
+    if (selection.isNone())
+        return false;
+
+    return actualSelectionAtSentenceStart(selection);
+}
+
+bool FrameSelection::selectionAtWordStart() const
+{
+    VisibleSelection selection = m_selection;
+    if (selection.isNone())
+        return false;
+
+    Position startPos(selection.start());
+    VisiblePosition pos(createLegacyEditingPosition(startPos.deprecatedNode(), startPos.deprecatedEditingOffset()), VP_DEFAULT_AFFINITY);
+    if (pos.isNull())
+        return false;
+
+    if (isStartOfParagraph(pos))
+        return true;
+        
+    bool result = true;
+    unsigned previousCount = 0;
+    for (pos = pos.previous(); !pos.isNull(); pos = pos.previous()) {
+        previousCount++;
+        if (isStartOfParagraph(pos)) {
+            if (previousCount == 1)
+                result = false;
+            break;
+        }
+        UChar c(pos.characterAfter());
+        if (c) {
+            result = isSpaceOrNewline(c) || c == 0xA0 || (u_ispunct(c) && c != ',' && c != '-' && c != '\'');
+            break;
+        }
+    }
+
+    return result;
+}
+
+PassRefPtr<Range> FrameSelection::rangeByMovingCurrentSelection(int amount) const
+{
+    return rangeByAlteringCurrentSelection(AlterationMove, amount);
+}
+
+PassRefPtr<Range> FrameSelection::rangeByExtendingCurrentSelection(int amount) const
+{
+    return rangeByAlteringCurrentSelection(AlterationExtend, amount);
+}
+
+void FrameSelection::selectRangeOnElement(unsigned location, unsigned length, Node* node)
+{
+    RefPtr<Range> resultRange = m_frame->document()->createRange();
+    ExceptionCode ec = 0;
+    resultRange->setStart(node, location, ec);
+    ASSERT(!ec);
+    resultRange->setEnd(node, location + length, ec);
+    ASSERT(!ec);
+    VisibleSelection selection = VisibleSelection(resultRange.get(), SEL_DEFAULT_AFFINITY);
+    setSelection(selection, true);
+}
+
+VisibleSelection FrameSelection::wordSelectionContainingCaretSelection(const VisibleSelection& selection)
+{
+    if (selection.isNone())
+        return VisibleSelection();
+
+    ASSERT(selection.isCaretOrRange());
+    FrameSelection frameSelection;
+    frameSelection.setSelection(selection);
+
+    Position startPosBeforeExpansion(selection.start());
+    Position endPosBeforeExpansion(selection.end());
+    VisiblePosition startVisiblePosBeforeExpansion(startPosBeforeExpansion, VP_DEFAULT_AFFINITY);
+    VisiblePosition endVisiblePosBeforeExpansion(endPosBeforeExpansion, VP_DEFAULT_AFFINITY);
+    if (endVisiblePosBeforeExpansion.isNull())
+        return VisibleSelection();
+
+    if (isEndOfParagraph(endVisiblePosBeforeExpansion)) {
+        UChar c(endVisiblePosBeforeExpansion.characterBefore());
+        if (isSpaceOrNewline(c) || c == 0xA0) {
+            // End of paragraph with space.
+            return VisibleSelection();
+        }
+    }
+
+    // If at end of paragraph, move backwards one character.
+    // This has the effect of selecting the word on the line (which is
+    // what we want, rather than selecting past the end of the line).
+    if (isEndOfParagraph(endVisiblePosBeforeExpansion) && !isStartOfParagraph(endVisiblePosBeforeExpansion))
+        frameSelection.modify(FrameSelection::AlterationMove, DirectionBackward, CharacterGranularity);
+
+    VisibleSelection newSelection = frameSelection.selection();
+    newSelection.expandUsingGranularity(WordGranularity);
+    frameSelection.setSelection(newSelection, frameSelection.granularity());
+
+    Position startPos(frameSelection.selection().start());
+    Position endPos(frameSelection.selection().end());
+
+    // Expansion cannot be allowed to change selection so that it is no longer
+    // touches (or contains) the original, unexpanded selection.
+    // Enforce this on the way into these additional calculations to give them
+    // the best chance to yield a suitable answer.
+    if (startPos > startPosBeforeExpansion)
+        startPos = startPosBeforeExpansion;
+    if (endPos < endPosBeforeExpansion)
+        endPos = endPosBeforeExpansion;
+
+    VisiblePosition startVisiblePos(startPos, VP_DEFAULT_AFFINITY);
+    VisiblePosition endVisiblePos(endPos, VP_DEFAULT_AFFINITY);
+
+    if (startVisiblePos.isNull() || endVisiblePos.isNull()) {
+        // Start or end is nil
+        return VisibleSelection();
+    }
+
+    if (isEndOfLine(endVisiblePosBeforeExpansion)) {
+        VisiblePosition previous(endVisiblePos.previous());
+        if (previous == endVisiblePos) {
+            // Empty document
+            return VisibleSelection();
+        }
+        UChar c(previous.characterAfter());
+        if (isSpaceOrNewline(c) || c == 0xA0) {
+            // Space at end of line
+            return VisibleSelection();
+        }
+    }
+
+    // Expansion has selected past end of line.
+    // Try repositioning backwards.
+    if (isEndOfLine(startVisiblePos) && isStartOfLine(endVisiblePos)) {
+        VisiblePosition previous(startVisiblePos.previous());
+        if (isEndOfLine(previous)) {
+            // On empty line
+            return VisibleSelection();
+        }
+        UChar c(previous.characterAfter());
+        if (isSpaceOrNewline(c) || c == 0xA0) {
+            // Space at end of line
+            return VisibleSelection();
+        }
+        frameSelection.moveTo(startVisiblePos);
+        frameSelection.modify(FrameSelection::AlterationExtend, DirectionBackward, WordGranularity);
+        startPos = frameSelection.selection().start();
+        endPos = frameSelection.selection().end();
+        startVisiblePos = VisiblePosition(startPos, VP_DEFAULT_AFFINITY);
+        endVisiblePos = VisiblePosition(endPos, VP_DEFAULT_AFFINITY);
+        if (startVisiblePos.isNull() || endVisiblePos.isNull()) {
+            // Start or end is nil
+            return VisibleSelection();
+        }
+    }
+
+    // Now loop backwards until we find a non-space.
+    while (endVisiblePos != startVisiblePos) {
+        VisiblePosition previous(endVisiblePos.previous());
+        UChar c(previous.characterAfter());
+        if (!isSpaceOrNewline(c) && c != 0xA0)
+            break;
+        endVisiblePos = previous;
+    }
+
+    // Expansion cannot be allowed to change selection so that it is no longer
+    // touches (or contains) the original, unexpanded selection.
+    // Enforce this on the way out of the function to preserve the invariant.
+    if (startVisiblePos > startVisiblePosBeforeExpansion)
+        startVisiblePos = startVisiblePosBeforeExpansion;
+    if (endVisiblePos < endVisiblePosBeforeExpansion)
+        endVisiblePos = endVisiblePosBeforeExpansion;
+
+    return VisibleSelection(startVisiblePos, endVisiblePos);    
+}
+
+bool FrameSelection::actualSelectionAtSentenceStart(const VisibleSelection& sel) const
+{
+    Position startPos(sel.start());
+    VisiblePosition pos(createLegacyEditingPosition(startPos.deprecatedNode(), startPos.deprecatedEditingOffset()), VP_DEFAULT_AFFINITY);
+    if (pos.isNull())
+        return false;
+
+    if (isStartOfParagraph(pos))
+        return true;
+    bool result = true;
+    bool sawSpace = false;
+    unsigned previousCount = 0;
+    for (pos = pos.previous(); !pos.isNull(); pos = pos.previous()) {
+        previousCount++;
+        if (isStartOfParagraph(pos)) {
+            if (previousCount == 1 || (previousCount == 2 && sawSpace))
+                result = false;
+            break;
+        }
+        UChar c(pos.characterAfter());
+        if (c) {
+            if (isSpaceOrNewline(c) || c == 0xA0) {
+                sawSpace = true;
+            }
+            else {
+                result = (c == '.' || c == '!' || c == '?');
+                break;
+            }
+        }
+    }
+    
+    return result;
+}
+
+PassRefPtr<Range> FrameSelection::rangeByAlteringCurrentSelection(EAlteration alteration, int amount) const
+{
+    if (m_selection.isNone())
+        return nullptr;
+
+    if (!amount)
+        return toNormalizedRange();
+
+    FrameSelection frameSelection;
+    frameSelection.setSelection(m_selection);
+    SelectionDirection direction = amount > 0 ? DirectionForward : DirectionBackward;
+    for (int i = 0; i < abs(amount); i++)
+        frameSelection.modify(alteration, direction, CharacterGranularity);
+    return frameSelection.toNormalizedRange();
+}
+
+void FrameSelection::clearCurrentSelection()
+{
+    setSelection(VisibleSelection());
+}
+
+void FrameSelection::setCaretBlinks(bool caretBlinks)
+{
+    if (m_caretBlinks == caretBlinks)
+        return;
+#if ENABLE(TEXT_CARET)
+    m_frame->document()->updateLayoutIgnorePendingStylesheets(); 
+    if (m_caretPaint) {
+        m_caretPaint = false; 
+        invalidateCaretRect(); 
+    }
+#endif
+    if (caretBlinks)
+        setFocusedElementIfNeeded();
+    m_caretBlinks = caretBlinks;
+    updateAppearance();
+}
+
+void FrameSelection::setCaretColor(const Color& caretColor)
+{
+    if (m_caretColor != caretColor) {
+        m_caretColor = caretColor;
+        if (caretIsVisible() && m_caretBlinks && isCaret())
+            invalidateCaretRect();
+    }
+}
+#endif // PLATFORM(IOS)
+
 }
 
 #ifndef NDEBUG
index e8805c1..ea7d902 100644 (file)
 #include "VisibleSelection.h"
 #include <wtf/Noncopyable.h>
 
+#if PLATFORM(IOS)
+#include "Color.h"
+#endif
+
 namespace WebCore {
 
 class CharacterData;
@@ -228,6 +232,43 @@ public:
     void showTreeForThis() const;
 #endif
 
+#if PLATFORM(IOS)
+public:
+    void expandSelectionToElementContainingCaretSelection();
+    PassRefPtr<Range> elementRangeContainingCaretSelection() const;
+    void expandSelectionToWordContainingCaretSelection();
+    PassRefPtr<Range> wordRangeContainingCaretSelection();
+    void expandSelectionToStartOfWordContainingCaretSelection();
+    UChar characterInRelationToCaretSelection(int amount) const;
+    UChar characterBeforeCaretSelection() const;
+    UChar characterAfterCaretSelection() const;
+    int wordOffsetInRange(const Range*) const;
+    bool spaceFollowsWordInRange(const Range*) const;
+    bool selectionAtDocumentStart() const;
+    bool selectionAtSentenceStart() const;
+    bool selectionAtWordStart() const;
+    PassRefPtr<Range> rangeByMovingCurrentSelection(int amount) const;
+    PassRefPtr<Range> rangeByExtendingCurrentSelection(int amount) const;
+    void selectRangeOnElement(unsigned location, unsigned length, Node*);
+    void suppressCloseTyping() { ++m_closeTypingSuppressions; }
+    void restoreCloseTyping() { --m_closeTypingSuppressions; }
+    void clearCurrentSelection();
+    void setCaretBlinks(bool caretBlinks = true);
+    void setCaretColor(const Color&);
+    static VisibleSelection wordSelectionContainingCaretSelection(const VisibleSelection&);
+    void setUpdateAppearanceEnabled(bool enabled) { m_updateAppearanceEnabled = enabled; }
+    void suppressScrolling() { ++m_scrollingSuppressCount; }
+    void restoreScrolling()
+    {
+        ASSERT(m_scrollingSuppressCount);
+        --m_scrollingSuppressCount;
+    }
+private:
+    bool actualSelectionAtSentenceStart(const VisibleSelection&) const;
+    PassRefPtr<Range> rangeByAlteringCurrentSelection(EAlteration, int amount) const;
+public:
+#endif
+
     bool shouldChangeSelection(const VisibleSelection&) const;
     bool shouldDeleteSelection(const VisibleSelection&) const;
     enum EndPointsAdjustmentMode { AdjustEndpointsAtBidiBoundary, DoNotAdjsutEndpoints };
@@ -309,6 +350,14 @@ private:
     bool m_isCaretBlinkingSuspended : 1;
     bool m_focused : 1;
     bool m_shouldShowBlockCursor : 1;
+
+#if PLATFORM(IOS)
+    bool m_updateAppearanceEnabled : 1;
+    bool m_caretBlinks : 1;
+    Color m_caretColor;
+    int m_closeTypingSuppressions;
+    int m_scrollingSuppressCount;
+#endif
 };
 
 inline EditingStyle* FrameSelection::typingStyle() const
index b5d06b2..370d4bf 100644 (file)
@@ -32,6 +32,9 @@
 #include "RenderText.h"
 #include "Settings.h"
 #include "Text.h"
+#if PLATFORM(IOS)
+#include "RenderText.h"
+#endif
 
 namespace WebCore {
 
@@ -68,6 +71,14 @@ void InsertIntoTextNodeCommand::doApply()
         cache->nodeTextChangeNotification(m_node.get(), AXObjectCache::AXTextInserted, m_offset, m_text);
 }
 
+#if PLATFORM(IOS)
+void InsertIntoTextNodeCommand::doReapply()
+{
+    ExceptionCode ec;
+    m_node->insertData(m_offset, m_text, ec);
+}
+#endif
+    
 void InsertIntoTextNodeCommand::doUnapply()
 {
     if (!m_node->hasEditableStyle())