summaryrefslogtreecommitdiff
path: root/Source
diff options
context:
space:
mode:
authorSimon Hausmann <simon.hausmann@digia.com>2012-09-25 13:02:02 +0200
committerSimon Hausmann <simon.hausmann@digia.com>2012-09-25 13:02:02 +0200
commit715be629d51174233403237bfc563cf150087dc8 (patch)
tree4cff72df808db977624338b0a38d8b6d1bd73c57 /Source
parentdc6262b587c71c14e30d93e57ed812e36a79a33e (diff)
downloadqtwebkit-715be629d51174233403237bfc563cf150087dc8.tar.gz
Imported WebKit commit ce614b0924ba46f78d4435e28ff93c8525fbb7cc (http://svn.webkit.org/repository/webkit/trunk@129485)
New snapshot that includes MingW build fixes
Diffstat (limited to 'Source')
-rw-r--r--Source/JavaScriptCore/ChangeLog260
-rwxr-xr-xSource/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.def1
-rw-r--r--Source/JavaScriptCore/assembler/MIPSAssembler.h12
-rw-r--r--Source/JavaScriptCore/assembler/MacroAssemblerMIPS.h75
-rw-r--r--Source/JavaScriptCore/bytecode/CodeBlock.cpp52
-rw-r--r--Source/JavaScriptCore/bytecode/Instruction.h2
-rw-r--r--Source/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp1
-rw-r--r--Source/JavaScriptCore/dfg/DFGOperations.cpp7
-rw-r--r--Source/JavaScriptCore/dfg/DFGOperations.h1
-rw-r--r--Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp5
-rw-r--r--Source/JavaScriptCore/dfg/DFGSpeculativeJIT32_64.cpp34
-rw-r--r--Source/JavaScriptCore/dfg/DFGSpeculativeJIT64.cpp26
-rw-r--r--Source/JavaScriptCore/interpreter/AbstractPC.cpp6
-rw-r--r--Source/JavaScriptCore/interpreter/AbstractPC.h15
-rw-r--r--Source/JavaScriptCore/interpreter/CallFrame.h3
-rw-r--r--Source/JavaScriptCore/interpreter/Interpreter.cpp3864
-rw-r--r--Source/JavaScriptCore/interpreter/Interpreter.h36
-rw-r--r--Source/JavaScriptCore/jit/ExecutableAllocatorFixedVMPool.cpp2
-rw-r--r--Source/JavaScriptCore/llint/LowLevelInterpreter32_64.asm4
-rw-r--r--Source/JavaScriptCore/llint/LowLevelInterpreter64.asm4
-rw-r--r--Source/JavaScriptCore/offlineasm/asm.rb2
-rw-r--r--Source/JavaScriptCore/offlineasm/cloop.rb8
-rw-r--r--Source/JavaScriptCore/offlineasm/instructions.rb8
-rw-r--r--Source/JavaScriptCore/offlineasm/offsets.rb1
-rw-r--r--Source/JavaScriptCore/offlineasm/parser.rb6
-rw-r--r--Source/JavaScriptCore/runtime/Executable.cpp24
-rw-r--r--Source/JavaScriptCore/runtime/Executable.h13
-rw-r--r--Source/JavaScriptCore/runtime/JSActivation.h24
-rw-r--r--Source/JavaScriptCore/runtime/JSGlobalData.cpp18
-rw-r--r--Source/JavaScriptCore/runtime/JSGlobalData.h22
-rw-r--r--Source/JavaScriptCore/runtime/JSGlobalObject.cpp2
-rw-r--r--Source/JavaScriptCore/runtime/JSGlobalObjectFunctions.cpp8
-rw-r--r--Source/JavaScriptCore/runtime/JSObject.cpp18
-rw-r--r--Source/JavaScriptCore/runtime/JSObject.h32
-rw-r--r--Source/JavaScriptCore/runtime/LiteralParser.cpp3
-rw-r--r--Source/JavaScriptCore/runtime/ObjectConstructor.cpp2
-rw-r--r--Source/JavaScriptCore/runtime/SparseArrayValueMap.cpp4
-rw-r--r--Source/Platform/ChangeLog29
-rw-r--r--Source/Platform/chromium/public/WebFilterOperation.h57
-rw-r--r--Source/WTF/ChangeLog334
-rw-r--r--Source/WTF/GNUmakefile.list.am1
-rw-r--r--Source/WTF/WTF.gypi1
-rw-r--r--Source/WTF/WTF.pro1
-rw-r--r--Source/WTF/WTF.vcproj/WTF.vcproj4
-rw-r--r--Source/WTF/WTF.xcodeproj/project.pbxproj118
-rw-r--r--Source/WTF/wtf/MemoryInstrumentation.h31
-rw-r--r--Source/WTF/wtf/MemoryInstrumentationVector.h61
-rw-r--r--Source/WTF/wtf/OSAllocatorPosix.cpp4
-rw-r--r--Source/WTF/wtf/Platform.h34
-rw-r--r--Source/WTF/wtf/gobject/GTypedefs.h5
-rw-r--r--Source/WTF/wtf/text/WTFString.h4
-rw-r--r--Source/WTF/wtf/url/api/ParsedURL.cpp112
-rw-r--r--Source/WTF/wtf/url/api/ParsedURL.h11
-rw-r--r--Source/WTF/wtf/url/api/URLBuffer.h (renamed from Source/WTF/wtf/url/src/URLBuffer.h)56
-rw-r--r--Source/WTF/wtf/url/api/URLQueryCharsetConverter.h54
-rw-r--r--Source/WTF/wtf/url/src/RawURLBuffer.h57
-rw-r--r--Source/WTF/wtf/url/src/URLCanon.h617
-rw-r--r--Source/WTF/wtf/url/src/URLCanonEtc.cpp374
-rw-r--r--Source/WTF/wtf/url/src/URLCanonFilesystemurl.cpp164
-rw-r--r--Source/WTF/wtf/url/src/URLCanonFileurl.cpp224
-rw-r--r--Source/WTF/wtf/url/src/URLCanonHost.cpp383
-rw-r--r--Source/WTF/wtf/url/src/URLCanonICU.cpp187
-rw-r--r--Source/WTF/wtf/url/src/URLCanonIP.cpp683
-rw-r--r--Source/WTF/wtf/url/src/URLCanonInternal.cpp310
-rw-r--r--Source/WTF/wtf/url/src/URLCanonInternal.h394
-rw-r--r--Source/WTF/wtf/url/src/URLCanonMailto.cpp134
-rw-r--r--Source/WTF/wtf/url/src/URLCanonPath.cpp372
-rw-r--r--Source/WTF/wtf/url/src/URLCanonPathurl.cpp122
-rw-r--r--Source/WTF/wtf/url/src/URLCanonQuery.cpp189
-rw-r--r--Source/WTF/wtf/url/src/URLCanonRelative.cpp572
-rw-r--r--Source/WTF/wtf/url/src/URLCanonStdURL.cpp210
-rw-r--r--Source/WTF/wtf/url/src/URLCharacterTypes.cpp203
-rw-r--r--Source/WTF/wtf/url/src/URLCharacterTypes.h78
-rw-r--r--Source/WTF/wtf/url/src/URLComponent.h56
-rw-r--r--Source/WTF/wtf/url/src/URLEscape.cpp43
-rw-r--r--Source/WTF/wtf/url/src/URLEscape.h53
-rw-r--r--Source/WTF/wtf/url/src/URLFile.h116
-rw-r--r--Source/WTF/wtf/url/src/URLParse.cpp787
-rw-r--r--Source/WTF/wtf/url/src/URLParse.h167
-rw-r--r--Source/WTF/wtf/url/src/URLParseFile.cpp251
-rw-r--r--Source/WTF/wtf/url/src/URLParseInternal.h119
-rw-r--r--Source/WTF/wtf/url/src/URLParser.h596
-rw-r--r--Source/WTF/wtf/url/src/URLQueryCanonicalizer.h109
-rw-r--r--Source/WTF/wtf/url/src/URLSegments.cpp4
-rw-r--r--Source/WTF/wtf/url/src/URLSegments.h92
-rw-r--r--Source/WTF/wtf/url/src/URLUtil.cpp494
-rw-r--r--Source/WTF/wtf/url/src/URLUtil.h137
-rw-r--r--Source/WTF/wtf/url/src/URLUtilInternal.h58
-rw-r--r--Source/WebCore/CMakeLists.txt1
-rw-r--r--Source/WebCore/ChangeLog1624
-rw-r--r--Source/WebCore/GNUmakefile.list.am7
-rw-r--r--Source/WebCore/Modules/indexeddb/DOMWindowIndexedDatabase.cpp6
-rw-r--r--Source/WebCore/Modules/indexeddb/DOMWindowIndexedDatabase.h4
-rw-r--r--Source/WebCore/Modules/indexeddb/DOMWindowIndexedDatabase.idl14
-rw-r--r--Source/WebCore/Modules/indexeddb/WorkerContextIndexedDatabase.cpp6
-rw-r--r--Source/WebCore/Modules/indexeddb/WorkerContextIndexedDatabase.h4
-rw-r--r--Source/WebCore/Modules/indexeddb/WorkerContextIndexedDatabase.idl32
-rw-r--r--Source/WebCore/Modules/mediastream/RTCPeerConnection.cpp2
-rw-r--r--Source/WebCore/Modules/mediastream/RTCPeerConnection.h2
-rw-r--r--Source/WebCore/Modules/mediastream/RTCPeerConnection.idl2
-rw-r--r--Source/WebCore/Modules/webaudio/BiquadProcessor.cpp1
-rw-r--r--Source/WebCore/PlatformBlackBerry.cmake1
-rw-r--r--Source/WebCore/Resources/pagepopups/calendarPicker.js6
-rw-r--r--Source/WebCore/Target.pri2
-rw-r--r--Source/WebCore/WebCore.exp.in11
-rw-r--r--Source/WebCore/WebCore.gypi4
-rwxr-xr-xSource/WebCore/WebCore.vcproj/WebCore.vcproj8
-rw-r--r--Source/WebCore/WebCore.xcodeproj/project.pbxproj16
-rw-r--r--Source/WebCore/bindings/generic/RuntimeEnabledFeatures.h11
-rw-r--r--Source/WebCore/bindings/js/JSDOMWindowShell.h1
-rw-r--r--Source/WebCore/bindings/js/JSHTMLCanvasElementCustom.cpp16
-rw-r--r--Source/WebCore/bindings/js/JSInjectedScriptManager.cpp8
-rw-r--r--Source/WebCore/bindings/js/ScriptFunctionCall.cpp7
-rw-r--r--Source/WebCore/bindings/js/SerializedScriptValue.cpp2
-rw-r--r--Source/WebCore/bindings/scripts/CodeGeneratorGObject.pm2
-rw-r--r--Source/WebCore/bindings/v8/V8PerIsolateData.cpp3
-rw-r--r--Source/WebCore/bindings/v8/custom/V8ArrayBufferViewCustom.h12
-rw-r--r--Source/WebCore/bindings/v8/custom/V8HTMLCanvasElementCustom.cpp16
-rw-r--r--Source/WebCore/css/CSSGradientValue.cpp3
-rw-r--r--Source/WebCore/css/CSSImageSetValue.cpp3
-rw-r--r--Source/WebCore/css/CSSMediaRule.cpp3
-rw-r--r--Source/WebCore/css/CSSParser.cpp2
-rw-r--r--Source/WebCore/css/CSSParserValues.h2
-rw-r--r--Source/WebCore/css/CSSRule.cpp6
-rw-r--r--Source/WebCore/css/CSSRule.h6
-rw-r--r--Source/WebCore/css/CSSRuleList.cpp3
-rw-r--r--Source/WebCore/css/CSSSelector.cpp4
-rw-r--r--Source/WebCore/css/CSSSelector.h1
-rw-r--r--Source/WebCore/css/CSSStyleSheet.cpp3
-rw-r--r--Source/WebCore/css/CSSValueList.cpp3
-rw-r--r--Source/WebCore/css/MediaList.cpp3
-rw-r--r--Source/WebCore/css/MediaQuery.cpp3
-rw-r--r--Source/WebCore/css/SelectorChecker.cpp9
-rw-r--r--Source/WebCore/css/StylePropertySet.cpp5
-rw-r--r--Source/WebCore/css/StyleResolver.cpp60
-rw-r--r--Source/WebCore/css/StyleResolver.h2
-rw-r--r--Source/WebCore/css/StyleRule.cpp3
-rw-r--r--Source/WebCore/css/StyleSheetContents.cpp7
-rw-r--r--Source/WebCore/css/StyleSheetList.cpp27
-rw-r--r--Source/WebCore/css/StyleSheetList.h26
-rw-r--r--Source/WebCore/css/WebKitCSSKeyframesRule.cpp5
-rw-r--r--Source/WebCore/css/WebKitCSSRegionRule.cpp3
-rw-r--r--Source/WebCore/dom/CharacterData.idl5
-rw-r--r--Source/WebCore/dom/ContainerNode.cpp95
-rw-r--r--Source/WebCore/dom/Document.cpp615
-rw-r--r--Source/WebCore/dom/Document.h128
-rw-r--r--Source/WebCore/dom/DocumentStyleSheetCollection.cpp484
-rw-r--r--Source/WebCore/dom/DocumentStyleSheetCollection.h143
-rw-r--r--Source/WebCore/dom/DocumentType.idl3
-rw-r--r--Source/WebCore/dom/Element.cpp9
-rw-r--r--Source/WebCore/dom/Element.idl4
-rw-r--r--Source/WebCore/dom/ElementAttributeData.cpp3
-rw-r--r--Source/WebCore/dom/EventNames.h2
-rw-r--r--Source/WebCore/dom/Node.cpp2
-rw-r--r--Source/WebCore/dom/ProcessingInstruction.cpp15
-rw-r--r--Source/WebCore/dom/StyleElement.cpp15
-rw-r--r--Source/WebCore/html/DateTimeFieldsState.cpp7
-rw-r--r--Source/WebCore/html/DateTimeFieldsState.h3
-rw-r--r--Source/WebCore/html/HTMLLinkElement.cpp15
-rw-r--r--Source/WebCore/html/HTMLQuoteElement.cpp3
-rw-r--r--Source/WebCore/html/HTMLViewSourceDocument.cpp3
-rw-r--r--Source/WebCore/html/TimeInputType.cpp24
-rw-r--r--Source/WebCore/html/TimeInputType.h1
-rw-r--r--Source/WebCore/html/parser/HTMLTreeBuilder.cpp4
-rw-r--r--Source/WebCore/html/shadow/DateTimeEditElement.cpp21
-rw-r--r--Source/WebCore/html/shadow/DateTimeEditElement.h3
-rw-r--r--Source/WebCore/html/shadow/DateTimeFieldElement.cpp5
-rw-r--r--Source/WebCore/html/shadow/DateTimeFieldElement.h2
-rw-r--r--Source/WebCore/html/shadow/DateTimeFieldElements.cpp26
-rw-r--r--Source/WebCore/html/shadow/DateTimeFieldElements.h5
-rw-r--r--Source/WebCore/html/track/TextTrackCue.cpp3
-rw-r--r--Source/WebCore/inspector/InjectedScriptCanvasModule.cpp18
-rw-r--r--Source/WebCore/inspector/InjectedScriptCanvasModule.h6
-rw-r--r--Source/WebCore/inspector/InjectedScriptCanvasModuleSource.js337
-rw-r--r--Source/WebCore/inspector/Inspector.json33
-rw-r--r--Source/WebCore/inspector/InspectorCSSAgent.cpp89
-rw-r--r--Source/WebCore/inspector/InspectorCSSAgent.h4
-rw-r--r--Source/WebCore/inspector/InspectorCanvasAgent.cpp34
-rw-r--r--Source/WebCore/inspector/InspectorCanvasAgent.h4
-rw-r--r--Source/WebCore/inspector/InspectorCanvasInstrumentation.h14
-rw-r--r--Source/WebCore/inspector/InspectorClient.h2
-rw-r--r--Source/WebCore/inspector/InspectorDOMAgent.cpp6
-rw-r--r--Source/WebCore/inspector/InspectorInstrumentation.h1
-rw-r--r--Source/WebCore/inspector/InspectorOverlay.cpp3
-rw-r--r--Source/WebCore/inspector/InspectorPageAgent.cpp7
-rw-r--r--Source/WebCore/inspector/InspectorProfilerAgent.cpp13
-rw-r--r--Source/WebCore/inspector/InspectorProfilerAgent.h1
-rw-r--r--Source/WebCore/inspector/InspectorStyleSheet.cpp27
-rw-r--r--Source/WebCore/inspector/InspectorStyleSheet.h1
-rw-r--r--Source/WebCore/inspector/front-end/AuditRules.js8
-rw-r--r--Source/WebCore/inspector/front-end/CSSStyleModel.js32
-rw-r--r--Source/WebCore/inspector/front-end/DOMAgent.js5
-rw-r--r--Source/WebCore/inspector/front-end/DefaultTextEditor.js35
-rw-r--r--Source/WebCore/inspector/front-end/FilteredItemSelectionDialog.js22
-rw-r--r--Source/WebCore/inspector/front-end/InspectorFrontendAPI.js2
-rw-r--r--Source/WebCore/inspector/front-end/ObjectPropertiesSection.js2
-rw-r--r--Source/WebCore/inspector/front-end/ResourceScriptMapping.js5
-rw-r--r--Source/WebCore/inspector/front-end/SettingsScreen.js75
-rw-r--r--Source/WebCore/inspector/front-end/StylesSidebarPane.js156
-rw-r--r--Source/WebCore/inspector/front-end/UserAgentSupport.js45
-rw-r--r--Source/WebCore/inspector/front-end/externs.js5
-rw-r--r--Source/WebCore/inspector/front-end/inspector.css1
-rw-r--r--Source/WebCore/inspector/front-end/inspector.js6
-rw-r--r--Source/WebCore/loader/DocumentLoader.cpp7
-rw-r--r--Source/WebCore/loader/FrameLoader.cpp5
-rw-r--r--Source/WebCore/loader/SubresourceLoader.cpp10
-rw-r--r--Source/WebCore/loader/cache/CachedImage.cpp1
-rw-r--r--Source/WebCore/loader/cache/CachedImage.h3
-rwxr-xr-xSource/WebCore/loader/cache/CachedResource.cpp3
-rw-r--r--Source/WebCore/loader/cache/CachedResource.h2
-rw-r--r--Source/WebCore/loader/cache/CachedResourceLoader.cpp116
-rw-r--r--Source/WebCore/loader/cache/CachedResourceLoader.h19
-rw-r--r--Source/WebCore/loader/cache/MemoryCache.cpp3
-rw-r--r--Source/WebCore/mathml/MathMLMathElement.cpp2
-rw-r--r--Source/WebCore/page/FeatureObserver.h1
-rw-r--r--Source/WebCore/page/Page.cpp3
-rw-r--r--Source/WebCore/page/PageGroup.cpp3
-rw-r--r--Source/WebCore/page/Settings.cpp17
-rw-r--r--Source/WebCore/page/Settings.h4
-rw-r--r--Source/WebCore/page/ValidationMessageClient.h2
-rw-r--r--Source/WebCore/page/mac/EventHandlerMac.mm7
-rw-r--r--Source/WebCore/platform/FractionalLayoutUnit.h11
-rw-r--r--Source/WebCore/platform/KURLWTFURL.cpp73
-rw-r--r--Source/WebCore/platform/SharedBuffer.cpp5
-rw-r--r--Source/WebCore/platform/blackberry/AuthenticationChallengeManager.cpp253
-rw-r--r--Source/WebCore/platform/blackberry/AuthenticationChallengeManager.h35
-rw-r--r--Source/WebCore/platform/blackberry/CookieManager.cpp11
-rw-r--r--Source/WebCore/platform/blackberry/CookieManager.h1
-rw-r--r--Source/WebCore/platform/blackberry/CookieParser.cpp5
-rw-r--r--Source/WebCore/platform/blackberry/CookieParser.h2
-rw-r--r--Source/WebCore/platform/blackberry/PageClientBlackBerry.h2
-rw-r--r--Source/WebCore/platform/cairo/WidgetBackingStoreCairo.cpp2
-rw-r--r--Source/WebCore/platform/chromium/PlatformSupport.h12
-rw-r--r--Source/WebCore/platform/chromium/ScrollbarThemeChromiumAndroid.cpp23
-rw-r--r--Source/WebCore/platform/chromium/ScrollbarThemeChromiumAndroid.h1
-rw-r--r--Source/WebCore/platform/clutter/GRefPtrClutter.cpp53
-rw-r--r--Source/WebCore/platform/clutter/GRefPtrClutter.h34
-rw-r--r--Source/WebCore/platform/graphics/BitmapImage.cpp3
-rw-r--r--Source/WebCore/platform/graphics/BitmapImage.h1
-rw-r--r--Source/WebCore/platform/graphics/blackberry/MediaPlayerPrivateBlackBerry.cpp41
-rw-r--r--Source/WebCore/platform/graphics/blackberry/MediaPlayerPrivateBlackBerry.h3
-rw-r--r--Source/WebCore/platform/graphics/chromium/CrossProcessFontLoading.mm16
-rw-r--r--Source/WebCore/platform/graphics/clutter/GraphicsLayerClutter.h2
-rw-r--r--Source/WebCore/platform/graphics/clutter/PlatformClutterLayerClient.h51
-rw-r--r--Source/WebCore/platform/graphics/clutter/TransformationMatrixClutter.cpp54
-rw-r--r--Source/WebCore/platform/graphics/mac/ComplexTextController.cpp10
-rw-r--r--Source/WebCore/platform/graphics/opengl/Extensions3DOpenGLCommon.cpp2
-rw-r--r--Source/WebCore/platform/graphics/transforms/TransformationMatrix.h6
-rw-r--r--Source/WebCore/platform/gtk/GtkInputMethodFilter.cpp2
-rw-r--r--Source/WebCore/platform/gtk/GtkWidgetBackingStoreX11.cpp4
-rw-r--r--Source/WebCore/platform/mac/KURLMac.mm2
-rw-r--r--Source/WebCore/platform/mock/GeolocationClientMock.cpp28
-rw-r--r--Source/WebCore/platform/mock/GeolocationClientMock.h12
-rw-r--r--Source/WebCore/platform/network/FormData.cpp3
-rw-r--r--Source/WebCore/platform/network/ResourceRequestBase.cpp3
-rw-r--r--Source/WebCore/platform/network/blackberry/CredentialBackingStore.cpp2
-rw-r--r--Source/WebCore/platform/network/blackberry/NetworkJob.cpp30
-rw-r--r--Source/WebCore/platform/network/blackberry/NetworkJob.h5
-rw-r--r--Source/WebCore/platform/text/mac/LocaleMac.h2
-rw-r--r--Source/WebCore/platform/text/mac/LocaleMac.mm53
-rw-r--r--Source/WebCore/plugins/gtk/PluginViewGtk.cpp2
-rw-r--r--Source/WebCore/rendering/ExclusionRectangle.cpp18
-rw-r--r--Source/WebCore/rendering/ExclusionRectangle.h21
-rw-r--r--Source/WebCore/rendering/ExclusionShape.cpp96
-rw-r--r--Source/WebCore/rendering/ExclusionShape.h37
-rw-r--r--Source/WebCore/rendering/RenderBR.cpp2
-rwxr-xr-xSource/WebCore/rendering/RenderBlock.cpp10
-rw-r--r--Source/WebCore/rendering/RenderFlowThread.cpp11
-rw-r--r--Source/WebCore/rendering/RenderFlowThread.h2
-rw-r--r--Source/WebCore/rendering/RenderInline.cpp10
-rw-r--r--Source/WebCore/rendering/RenderMeter.cpp17
-rw-r--r--Source/WebCore/rendering/RenderMeter.h2
-rw-r--r--Source/WebCore/rendering/RenderMultiColumnFlowThread.cpp7
-rw-r--r--Source/WebCore/rendering/RenderMultiColumnFlowThread.h2
-rwxr-xr-xSource/WebCore/rendering/RenderObject.cpp4
-rw-r--r--Source/WebCore/rendering/RenderObject.h3
-rw-r--r--Source/WebCore/rendering/RenderObjectChildList.cpp2
-rw-r--r--Source/WebCore/rendering/RenderTableRow.cpp2
-rw-r--r--Source/WebCore/rendering/RenderWidget.cpp45
-rw-r--r--Source/WebCore/rendering/RenderWidget.h29
-rw-r--r--Source/WebCore/rendering/RootInlineBox.cpp2
-rw-r--r--Source/WebCore/rendering/WrapShapeInfo.cpp16
-rw-r--r--Source/WebCore/rendering/WrapShapeInfo.h8
-rw-r--r--Source/WebCore/rendering/style/RenderStyle.cpp4
-rw-r--r--Source/WebCore/rendering/style/StyleRareNonInheritedData.cpp3
-rwxr-xr-xSource/WebCore/testing/InternalSettings.cpp8
-rwxr-xr-xSource/WebCore/testing/InternalSettings.h3
-rwxr-xr-xSource/WebCore/testing/InternalSettings.idl1
-rw-r--r--Source/WebCore/testing/Internals.cpp89
-rw-r--r--Source/WebCore/testing/Internals.h8
-rw-r--r--Source/WebCore/testing/Internals.idl2
-rw-r--r--Source/WebKit/ChangeLog13
-rw-r--r--Source/WebKit/PlatformBlackBerry.cmake1
-rw-r--r--Source/WebKit/blackberry/Api/BlackBerryGlobal.cpp3
-rw-r--r--Source/WebKit/blackberry/Api/WebCookieJar.cpp60
-rw-r--r--Source/WebKit/blackberry/Api/WebCookieJar.h70
-rw-r--r--Source/WebKit/blackberry/Api/WebPage.cpp28
-rw-r--r--Source/WebKit/blackberry/Api/WebPage.h3
-rw-r--r--Source/WebKit/blackberry/Api/WebPage_p.h4
-rw-r--r--Source/WebKit/blackberry/Api/WebString.cpp5
-rw-r--r--Source/WebKit/blackberry/Api/WebString.h1
-rw-r--r--Source/WebKit/blackberry/ChangeLog85
-rw-r--r--Source/WebKit/blackberry/WebCoreSupport/AboutDataEnableFeatures.in2
-rw-r--r--Source/WebKit/blackberry/WebKitSupport/DumpRenderTreeSupport.cpp15
-rw-r--r--Source/WebKit/blackberry/WebKitSupport/DumpRenderTreeSupport.h3
-rw-r--r--Source/WebKit/chromium/ChangeLog118
-rw-r--r--Source/WebKit/chromium/DEPS2
-rw-r--r--Source/WebKit/chromium/WebKit.gyp2
-rw-r--r--Source/WebKit/chromium/public/WebGeolocationClientMock.h2
-rw-r--r--Source/WebKit/chromium/public/WebRuntimeFeatures.h4
-rw-r--r--Source/WebKit/chromium/public/WebViewClient.h7
-rw-r--r--Source/WebKit/chromium/src/PlatformSupport.cpp18
-rw-r--r--Source/WebKit/chromium/src/ValidationMessageClientImpl.cpp97
-rw-r--r--Source/WebKit/chromium/src/ValidationMessageClientImpl.h56
-rw-r--r--Source/WebKit/chromium/src/WebDocument.cpp3
-rw-r--r--Source/WebKit/chromium/src/WebGeolocationClientMock.cpp19
-rw-r--r--Source/WebKit/chromium/src/WebPageSerializerImpl.cpp65
-rw-r--r--Source/WebKit/chromium/src/WebRuntimeFeatures.cpp9
-rw-r--r--Source/WebKit/chromium/src/WebViewImpl.cpp3
-rw-r--r--Source/WebKit/chromium/src/WebViewImpl.h2
-rw-r--r--Source/WebKit/chromium/tests/FilterOperationsTest.cpp103
-rw-r--r--Source/WebKit/chromium/tests/MemoryInstrumentationTest.cpp72
-rw-r--r--Source/WebKit/efl/ChangeLog12
-rw-r--r--Source/WebKit/efl/ewk/ewk_view.cpp1
-rw-r--r--Source/WebKit/gtk/ChangeLog41
-rw-r--r--Source/WebKit/gtk/WebCoreSupport/AcceleratedCompositingContextClutter.cpp5
-rw-r--r--Source/WebKit/gtk/WebCoreSupport/DumpRenderTreeSupportGtk.cpp23
-rw-r--r--Source/WebKit/gtk/WebCoreSupport/DumpRenderTreeSupportGtk.h4
-rw-r--r--Source/WebKit/mac/ChangeLog21
-rw-r--r--Source/WebKit/mac/WebView/WebHTMLView.mm3
-rw-r--r--Source/WebKit/mac/WebView/WebView.mm4
-rw-r--r--Source/WebKit/mac/WebView/WebViewPrivate.h2
-rw-r--r--Source/WebKit/qt/ChangeLog11
-rw-r--r--Source/WebKit/qt/WebCoreSupport/DumpRenderTreeSupportQt.cpp17
-rw-r--r--Source/WebKit/qt/WebCoreSupport/DumpRenderTreeSupportQt.h4
-rw-r--r--Source/WebKit2/ChangeLog317
-rw-r--r--Source/WebKit2/GNUmakefile.am2
-rw-r--r--Source/WebKit2/GNUmakefile.list.am1
-rw-r--r--Source/WebKit2/PlatformEfl.cmake3
-rw-r--r--Source/WebKit2/Target.pri1
-rw-r--r--Source/WebKit2/UIProcess/API/efl/tests/UnitTestUtils/EWK2UnitTestEnvironment.cpp2
-rw-r--r--Source/WebKit2/UIProcess/API/gtk/WebKitContextMenuClient.cpp2
-rw-r--r--Source/WebKit2/UIProcess/API/gtk/WebKitEditingCommands.h9
-rw-r--r--Source/WebKit2/UIProcess/API/gtk/WebKitResourceLoadClient.cpp2
-rw-r--r--Source/WebKit2/UIProcess/API/gtk/WebKitUIClient.cpp11
-rw-r--r--Source/WebKit2/UIProcess/API/gtk/WebKitURIRequest.cpp18
-rw-r--r--Source/WebKit2/UIProcess/API/gtk/WebKitURIRequestPrivate.h1
-rw-r--r--Source/WebKit2/UIProcess/API/gtk/WebKitWebView.cpp197
-rw-r--r--Source/WebKit2/UIProcess/API/gtk/WebKitWebViewBase.cpp6
-rw-r--r--Source/WebKit2/UIProcess/API/gtk/WebKitWebViewBasePrivate.h2
-rw-r--r--Source/WebKit2/UIProcess/API/gtk/WebKitWebViewPrivate.h15
-rw-r--r--Source/WebKit2/UIProcess/API/gtk/docs/webkit2gtk-sections.txt1
-rw-r--r--Source/WebKit2/UIProcess/API/gtk/tests/TestWebViewEditor.cpp60
-rw-r--r--Source/WebKit2/UIProcess/API/mac/WKProcessGroup.mm2
-rw-r--r--Source/WebKit2/UIProcess/Launcher/ProcessLauncher.h2
-rw-r--r--Source/WebKit2/UIProcess/WebProcessProxy.cpp17
-rw-r--r--Source/WebKit2/UIProcess/WebProcessProxy.h1
-rw-r--r--Source/WebKit2/UIProcess/cairo/BackingStoreCairo.cpp2
-rw-r--r--Source/WebKit2/UIProcess/efl/WebProcessProxyEfl.cpp42
-rw-r--r--Source/WebKit2/UIProcess/gtk/WebProcessProxyGtk.cpp35
-rw-r--r--Source/WebKit2/UIProcess/mac/WebProcessProxyMac.mm11
-rw-r--r--Source/WebKit2/UIProcess/qt/WebProcessProxyQt.cpp35
-rw-r--r--Source/WebKit2/UIProcess/win/WebProcessProxyWin.cpp4
-rw-r--r--Source/WebKit2/WebProcess/InjectedBundle/API/c/WKBundlePage.cpp19
-rw-r--r--Source/WebKit2/WebProcess/InjectedBundle/API/c/WKBundlePagePrivate.h4
-rw-r--r--Source/WebKit2/WebProcess/Plugins/Netscape/x11/NetscapePluginX11.cpp2
-rw-r--r--Source/WebKit2/win/WebKit2.def21
-rw-r--r--Source/WebKit2/win/WebKit2CFLite.def20
-rw-r--r--Source/api.pri9
-rw-r--r--Source/autotools/symbols.filter20
-rw-r--r--Source/cmake/OptionsEfl.cmake17
371 files changed, 14468 insertions, 7547 deletions
diff --git a/Source/JavaScriptCore/ChangeLog b/Source/JavaScriptCore/ChangeLog
index 5d81031ba..403a38c70 100644
--- a/Source/JavaScriptCore/ChangeLog
+++ b/Source/JavaScriptCore/ChangeLog
@@ -1,3 +1,263 @@
+2012-09-24 Gavin Barraclough <barraclough@apple.com>
+
+ https://bugs.webkit.org/show_bug.cgi?id=97530
+ Regression, freeze applied to numeric properties of non-array objects
+
+ Reviewed by Filip Pizlo.
+
+ Object.freeze has a fast implementation in JSObject, but this hasn't been updated to take into account numeric properties in butterflies.
+ For now, just fall back to the generic implementation if the object has numeric properties.
+
+ * runtime/ObjectConstructor.cpp:
+ (JSC::objectConstructorFreeze):
+ - fallback if the object has a non-zero indexed property vector length.
+
+2012-09-24 Gavin Barraclough <barraclough@apple.com>
+
+ Bug in numeric accessors on global environment
+ https://bugs.webkit.org/show_bug.cgi?id=97526
+
+ Reviewed by Geoff Garen.
+
+ I've hit this assert in test262 in browser, but haven't yet worked out how to repro in a test case :-/
+ The sparsemap is failing to map back from the global object to the window shell.
+ A test case would need to resolve a numeric property name against the global environment.
+
+ (JSC::SparseArrayEntry::get):
+ (JSC::SparseArrayEntry::put):
+ - Add missing toThisObject calls.
+
+2012-09-24 Filip Pizlo <fpizlo@apple.com>
+
+ SerializedScriptValue isn't aware of indexed storage, but should be
+ https://bugs.webkit.org/show_bug.cgi?id=97515
+ <rdar://problem/12361874>
+
+ Reviewed by Sam Weinig.
+
+ Export a method that WebCore now uses.
+
+ * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.def:
+ * runtime/JSObject.h:
+ (JSObject):
+
+2012-09-24 Gavin Barraclough <barraclough@apple.com>
+
+ Remove JSObject::unwrappedGlobalObject(), JSObject::unwrappedObject()
+ https://bugs.webkit.org/show_bug.cgi?id=97519
+
+ Reviewed by Geoff Garen.
+
+ unwrappedGlobalObject() was only needed because globalObject() doesn't always return a helpful result -
+ specifically for WebCore's window shell the structure's globalObject is set to null. We can fix this by
+ simply keeping the structure up to date as the window navigates, obviating the need for this function.
+
+ The only other use of unwrappedObject() came from globalFuncEval(), and this can be trivially removed
+ by flipping the way we perform this globalObject check (which we may also be able to remove!) - instead
+ of getting the globalObject from the provided this value & comparing to the expected globalObject, we
+ can get the this value from the expected globalObject, and compare to that provided.
+
+ * runtime/JSGlobalObject.cpp:
+ - Call globalObject() instead of unwrappedGlobalObject().
+ * runtime/JSGlobalObjectFunctions.cpp:
+ (JSC::globalFuncEval):
+ - Changed to compare this object values, instead of globalObjects -
+ this means we only need to be able to map globalObject -> this,
+ and not vice versa.
+ * runtime/JSObject.cpp:
+ (JSC::JSObject::allowsAccessFrom):
+ (JSC::JSObject::createInheritorID):
+ - Call globalObject() instead of unwrappedGlobalObject().
+ * runtime/JSObject.h:
+ (JSObject):
+ - Removed unwrappedGlobalObject(), unwrappedObject().
+
+2012-09-24 Mark Lam <mark.lam@apple.com>
+
+ Deleting the classic interpreter and cleaning up some build options.
+ https://bugs.webkit.org/show_bug.cgi?id=96969.
+
+ Reviewed by Geoffrey Garen.
+
+ * bytecode/CodeBlock.cpp:
+ (JSC::CodeBlock::dump):
+ (JSC::CodeBlock::finalizeUnconditionally):
+ (JSC::CodeBlock::stronglyVisitStrongReferences):
+ (JSC):
+ * bytecode/Instruction.h:
+ (JSC::Instruction::Instruction):
+ * interpreter/AbstractPC.cpp:
+ (JSC::AbstractPC::AbstractPC):
+ * interpreter/AbstractPC.h:
+ (AbstractPC):
+ * interpreter/CallFrame.h:
+ (ExecState):
+ * interpreter/Interpreter.cpp:
+ (JSC):
+ (JSC::Interpreter::Interpreter):
+ (JSC::Interpreter::~Interpreter):
+ (JSC::Interpreter::initialize):
+ (JSC::Interpreter::isOpcode):
+ (JSC::Interpreter::unwindCallFrame):
+ (JSC::getLineNumberForCallFrame):
+ (JSC::getCallerInfo):
+ (JSC::getSourceURLFromCallFrame):
+ (JSC::Interpreter::execute):
+ (JSC::Interpreter::executeCall):
+ (JSC::Interpreter::executeConstruct):
+ (JSC::Interpreter::retrieveArgumentsFromVMCode):
+ (JSC::Interpreter::retrieveCallerFromVMCode):
+ (JSC::Interpreter::retrieveLastCaller):
+ * interpreter/Interpreter.h:
+ (JSC::Interpreter::getOpcodeID):
+ (Interpreter):
+ * jit/ExecutableAllocatorFixedVMPool.cpp:
+ (JSC::FixedVMPoolExecutableAllocator::FixedVMPoolExecutableAllocator):
+ * offlineasm/asm.rb:
+ * offlineasm/offsets.rb:
+ * runtime/Executable.cpp:
+ (JSC::EvalExecutable::compileInternal):
+ (JSC::ProgramExecutable::compileInternal):
+ (JSC::FunctionExecutable::compileForCallInternal):
+ (JSC::FunctionExecutable::compileForConstructInternal):
+ * runtime/Executable.h:
+ (JSC::NativeExecutable::create):
+ (NativeExecutable):
+ (JSC::NativeExecutable::finishCreation):
+ * runtime/JSGlobalData.cpp:
+ (JSC):
+ (JSC::JSGlobalData::JSGlobalData):
+ (JSC::JSGlobalData::getHostFunction):
+ * runtime/JSGlobalData.h:
+ (JSGlobalData):
+ (JSC::JSGlobalData::canUseJIT):
+ (JSC::JSGlobalData::canUseRegExpJIT):
+ * runtime/Options.cpp:
+ (JSC::Options::initialize):
+
+2012-09-24 Filip Pizlo <fpizlo@apple.com>
+
+ Nested try/finally should not confuse the finally unpopper in BytecodeGenerator::emitComplexJumpScopes
+ https://bugs.webkit.org/show_bug.cgi?id=97508
+ <rdar://problem/12361132>
+
+ Reviewed by Sam Weinig.
+
+ We're reusing some vector for multiple iterations of a loop, but we were forgetting to clear its
+ contents from one iteration to the next. Hence if you did multiple iterations of finally unpopping
+ (like in a nested try/finally and a jump out of both of them) then you'd get a corrupted try
+ context stack afterwards.
+
+ * bytecompiler/BytecodeGenerator.cpp:
+ (JSC::BytecodeGenerator::emitComplexJumpScopes):
+
+2012-09-24 Filip Pizlo <fpizlo@apple.com>
+
+ ValueToInt32 bool case does bad things to registers
+ https://bugs.webkit.org/show_bug.cgi?id=97505
+ <rdar://problem/12356331>
+
+ Reviewed by Mark Hahnenberg.
+
+ * dfg/DFGSpeculativeJIT.cpp:
+ (JSC::DFG::SpeculativeJIT::compileValueToInt32):
+
+2012-09-24 Mark Lam <mark.lam@apple.com>
+
+ Add cloopDo instruction for debugging the llint C++ backend.
+ https://bugs.webkit.org/show_bug.cgi?id=97502.
+
+ Reviewed by Geoffrey Garen.
+
+ * offlineasm/cloop.rb:
+ * offlineasm/instructions.rb:
+ * offlineasm/parser.rb:
+
+2012-09-24 Filip Pizlo <fpizlo@apple.com>
+
+ JSArray::putByIndex asserts with readonly property on prototype
+ https://bugs.webkit.org/show_bug.cgi?id=97435
+ <rdar://problem/12357084>
+
+ Reviewed by Geoffrey Garen.
+
+ Boy, there were some problems:
+
+ - putDirectIndex() should know that it can set the index quickly even if it's a hole and we're
+ in SlowPut mode, since that's the whole point of PutDirect.
+
+ - We should have a fast path for putByIndex().
+
+ - The LiteralParser should not use push(), since that may throw if we're having a bad time.
+
+ * interpreter/Interpreter.cpp:
+ (JSC::eval):
+ * runtime/JSObject.h:
+ (JSC::JSObject::putByIndexInline):
+ (JSObject):
+ (JSC::JSObject::putDirectIndex):
+ * runtime/LiteralParser.cpp:
+ (JSC::::parse):
+
+2012-09-24 Mark Lam <mark.lam@apple.com>
+
+ Added a missing "if VALUE_PROFILER" around an access to ArrayProfile record.
+ https://bugs.webkit.org/show_bug.cgi?id=97496.
+
+ Reviewed by Filip Pizlo.
+
+ * llint/LowLevelInterpreter32_64.asm:
+ * llint/LowLevelInterpreter64.asm:
+
+2012-09-24 Geoffrey Garen <ggaren@apple.com>
+
+ Inlined activation tear-off in the DFG
+ https://bugs.webkit.org/show_bug.cgi?id=97487
+
+ Reviewed by Filip Pizlo.
+
+ * dfg/DFGOperations.cpp:
+ * dfg/DFGOperations.h: Activation tear-off is always inlined now, so I
+ removed its out-of-line implementation.
+
+ * dfg/DFGSpeculativeJIT32_64.cpp:
+ (JSC::DFG::SpeculativeJIT::compile):
+ * dfg/DFGSpeculativeJIT64.cpp:
+ (JSC::DFG::SpeculativeJIT::compile): Inlined the variable copy and update
+ of JSVariableObject::m_registers. This usually turns into < 10 instructions,
+ which is close to pure win as compared to the operation function call.
+
+ * runtime/JSActivation.h:
+ (JSActivation):
+ (JSC::JSActivation::registersOffset):
+ (JSC::JSActivation::tearOff):
+ (JSC::JSActivation::isTornOff):
+ (JSC):
+ (JSC::JSActivation::storageOffset):
+ (JSC::JSActivation::storage): Tiny bit of refactoring so the JIT can
+ share the pointer math helper functions we use internally.
+
+2012-09-24 Balazs Kilvady <kilvadyb@homejinni.com>
+
+ MIPS: store8 functions added to MacroAssembler.
+
+ MIPS store8 functions
+ https://bugs.webkit.org/show_bug.cgi?id=97243
+
+ Reviewed by Oliver Hunt.
+
+ Add MIPS store8 functions.
+
+ * assembler/MIPSAssembler.h:
+ (JSC::MIPSAssembler::lhu): New function.
+ (MIPSAssembler):
+ (JSC::MIPSAssembler::sb): New function.
+ (JSC::MIPSAssembler::sh): New function.
+ * assembler/MacroAssemblerMIPS.h:
+ (JSC::MacroAssemblerMIPS::store8): New function.
+ (MacroAssemblerMIPS):
+ (JSC::MacroAssemblerMIPS::store16): New function.
+
2012-09-23 Geoffrey Garen <ggaren@apple.com>
PutScopedVar should not be marked as clobbering the world
diff --git a/Source/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.def b/Source/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.def
index f7c0457bf..eda306f3c 100755
--- a/Source/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.def
+++ b/Source/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.def
@@ -277,6 +277,7 @@ EXPORTS
?put@JSObject@JSC@@SAXPAVJSCell@2@PAVExecState@2@VPropertyName@2@VJSValue@2@AAVPutPropertySlot@2@@Z
?putByIndex@JSObject@JSC@@SAXPAVJSCell@2@PAVExecState@2@IVJSValue@2@_N@Z
?putDirectIndexBeyondVectorLength@JSObject@JSC@@AAE_NPAVExecState@2@IVJSValue@2@IW4PutDirectIndexMode@2@@Z
+ ?putDirectMayBeIndex@JSObject@JSC@@QAEXPAVExecState@2@VPropertyName@2@VJSValue@2@@Z
?putDirectVirtual@JSGlobalObject@JSC@@SAXPAVJSObject@2@PAVExecState@2@VPropertyName@2@VJSValue@2@I@Z
?putDirectVirtual@JSObject@JSC@@SAXPAV12@PAVExecState@2@VPropertyName@2@VJSValue@2@I@Z
?randomNumber@WTF@@YANXZ
diff --git a/Source/JavaScriptCore/assembler/MIPSAssembler.h b/Source/JavaScriptCore/assembler/MIPSAssembler.h
index 65307d950..d3f8af996 100644
--- a/Source/JavaScriptCore/assembler/MIPSAssembler.h
+++ b/Source/JavaScriptCore/assembler/MIPSAssembler.h
@@ -405,6 +405,18 @@ public:
loadDelayNop();
}
+ void sb(RegisterID rt, RegisterID rs, int offset)
+ {
+ emitInst(0xa0000000 | (rt << OP_SH_RT) | (rs << OP_SH_RS)
+ | (offset & 0xffff));
+ }
+
+ void sh(RegisterID rt, RegisterID rs, int offset)
+ {
+ emitInst(0xa4000000 | (rt << OP_SH_RT) | (rs << OP_SH_RS)
+ | (offset & 0xffff));
+ }
+
void sw(RegisterID rt, RegisterID rs, int offset)
{
emitInst(0xac000000 | (rt << OP_SH_RT) | (rs << OP_SH_RS)
diff --git a/Source/JavaScriptCore/assembler/MacroAssemblerMIPS.h b/Source/JavaScriptCore/assembler/MacroAssemblerMIPS.h
index b3afae8df..22830a621 100644
--- a/Source/JavaScriptCore/assembler/MacroAssemblerMIPS.h
+++ b/Source/JavaScriptCore/assembler/MacroAssemblerMIPS.h
@@ -786,6 +786,81 @@ public:
return dataLabel;
}
+ void store8(RegisterID src, BaseIndex address)
+ {
+ if (address.offset >= -32768 && address.offset <= 32767
+ && !m_fixedWidth) {
+ /*
+ sll addrTemp, address.index, address.scale
+ addu addrTemp, addrTemp, address.base
+ sb src, address.offset(addrTemp)
+ */
+ m_assembler.sll(addrTempRegister, address.index, address.scale);
+ m_assembler.addu(addrTempRegister, addrTempRegister, address.base);
+ m_assembler.sb(src, addrTempRegister, address.offset);
+ } else {
+ /*
+ sll addrTemp, address.index, address.scale
+ addu addrTemp, addrTemp, address.base
+ lui immTemp, (address.offset + 0x8000) >> 16
+ addu addrTemp, addrTemp, immTemp
+ sb src, (address.offset & 0xffff)(at)
+ */
+ m_assembler.sll(addrTempRegister, address.index, address.scale);
+ m_assembler.addu(addrTempRegister, addrTempRegister, address.base);
+ m_assembler.lui(immTempRegister, (address.offset + 0x8000) >> 16);
+ m_assembler.addu(addrTempRegister, addrTempRegister,
+ immTempRegister);
+ m_assembler.sb(src, addrTempRegister, address.offset);
+ }
+ }
+
+ void store8(TrustedImm32 imm, void* address)
+ {
+ /*
+ li immTemp, imm
+ li addrTemp, address
+ sb src, 0(addrTemp)
+ */
+ if (!imm.m_value && !m_fixedWidth) {
+ move(TrustedImmPtr(address), addrTempRegister);
+ m_assembler.sb(MIPSRegisters::zero, addrTempRegister, 0);
+ } else {
+ move(imm, immTempRegister);
+ move(TrustedImmPtr(address), addrTempRegister);
+ m_assembler.sb(immTempRegister, addrTempRegister, 0);
+ }
+ }
+
+ void store16(RegisterID src, BaseIndex address)
+ {
+ if (address.offset >= -32768 && address.offset <= 32767
+ && !m_fixedWidth) {
+ /*
+ sll addrTemp, address.index, address.scale
+ addu addrTemp, addrTemp, address.base
+ sh src, address.offset(addrTemp)
+ */
+ m_assembler.sll(addrTempRegister, address.index, address.scale);
+ m_assembler.addu(addrTempRegister, addrTempRegister, address.base);
+ m_assembler.sh(src, addrTempRegister, address.offset);
+ } else {
+ /*
+ sll addrTemp, address.index, address.scale
+ addu addrTemp, addrTemp, address.base
+ lui immTemp, (address.offset + 0x8000) >> 16
+ addu addrTemp, addrTemp, immTemp
+ sh src, (address.offset & 0xffff)(at)
+ */
+ m_assembler.sll(addrTempRegister, address.index, address.scale);
+ m_assembler.addu(addrTempRegister, addrTempRegister, address.base);
+ m_assembler.lui(immTempRegister, (address.offset + 0x8000) >> 16);
+ m_assembler.addu(addrTempRegister, addrTempRegister,
+ immTempRegister);
+ m_assembler.sh(src, addrTempRegister, address.offset);
+ }
+ }
+
void store32(RegisterID src, ImplicitAddress address)
{
if (address.offset >= -32768 && address.offset <= 32767
diff --git a/Source/JavaScriptCore/bytecode/CodeBlock.cpp b/Source/JavaScriptCore/bytecode/CodeBlock.cpp
index 54dccb9ed..bd8bfec0d 100644
--- a/Source/JavaScriptCore/bytecode/CodeBlock.cpp
+++ b/Source/JavaScriptCore/bytecode/CodeBlock.cpp
@@ -588,25 +588,6 @@ void CodeBlock::dump(ExecState* exec)
} while (i < m_globalResolveInfos.size());
}
#endif
-#if ENABLE(CLASSIC_INTERPRETER)
- if (!m_globalResolveInstructions.isEmpty() || !m_propertyAccessInstructions.isEmpty())
- dataLog("\nStructures:\n");
-
- if (!m_globalResolveInstructions.isEmpty()) {
- size_t i = 0;
- do {
- printStructures(&instructions()[m_globalResolveInstructions[i]]);
- ++i;
- } while (i < m_globalResolveInstructions.size());
- }
- if (!m_propertyAccessInstructions.isEmpty()) {
- size_t i = 0;
- do {
- printStructures(&instructions()[m_propertyAccessInstructions[i]]);
- ++i;
- } while (i < m_propertyAccessInstructions.size());
- }
-#endif
if (m_rareData && !m_rareData->m_exceptionHandlers.isEmpty()) {
dataLog("\nException Handlers:\n");
@@ -2065,9 +2046,7 @@ void CodeBlock::finalizeUnconditionally()
{
#if ENABLE(LLINT)
Interpreter* interpreter = m_globalData->interpreter;
- // interpreter->classicEnabled() returns true if the old C++ interpreter is enabled. If that's enabled
- // then we're not using LLInt.
- if (!interpreter->classicEnabled() && !!numberOfInstructions()) {
+ if (!!numberOfInstructions()) {
for (size_t size = m_propertyAccessInstructions.size(), i = 0; i < size; ++i) {
Instruction* curInstruction = &instructions()[m_propertyAccessInstructions[i]];
switch (interpreter->getOpcodeID(curInstruction[0].u.opcode)) {
@@ -2260,14 +2239,6 @@ void CodeBlock::stronglyVisitStrongReferences(SlotVisitor& visitor)
visitor.append(&m_functionExprs[i]);
for (size_t i = 0; i < m_functionDecls.size(); ++i)
visitor.append(&m_functionDecls[i]);
-#if ENABLE(CLASSIC_INTERPRETER)
- if (m_globalData->interpreter->classicEnabled() && !!numberOfInstructions()) {
- for (size_t size = m_propertyAccessInstructions.size(), i = 0; i < size; ++i)
- visitStructures(visitor, &instructions()[m_propertyAccessInstructions[i]]);
- for (size_t size = m_globalResolveInstructions.size(), i = 0; i < size; ++i)
- visitStructures(visitor, &instructions()[m_globalResolveInstructions[i]]);
- }
-#endif
updateAllPredictions(Collection);
}
@@ -2444,27 +2415,6 @@ void CodeBlock::expressionRangeForBytecodeOffset(unsigned bytecodeOffset, int& d
return;
}
-#if ENABLE(CLASSIC_INTERPRETER)
-bool CodeBlock::hasGlobalResolveInstructionAtBytecodeOffset(unsigned bytecodeOffset)
-{
- if (m_globalResolveInstructions.isEmpty())
- return false;
-
- int low = 0;
- int high = m_globalResolveInstructions.size();
- while (low < high) {
- int mid = low + (high - low) / 2;
- if (m_globalResolveInstructions[mid] <= bytecodeOffset)
- low = mid + 1;
- else
- high = mid;
- }
-
- if (!low || m_globalResolveInstructions[low - 1] != bytecodeOffset)
- return false;
- return true;
-}
-#endif
#if ENABLE(JIT)
bool CodeBlock::hasGlobalResolveInfoAtBytecodeOffset(unsigned bytecodeOffset)
{
diff --git a/Source/JavaScriptCore/bytecode/Instruction.h b/Source/JavaScriptCore/bytecode/Instruction.h
index 6c1260abc..b276fd957 100644
--- a/Source/JavaScriptCore/bytecode/Instruction.h
+++ b/Source/JavaScriptCore/bytecode/Instruction.h
@@ -154,7 +154,7 @@ namespace JSC {
Instruction(Opcode opcode)
{
-#if !ENABLE(COMPUTED_GOTO_CLASSIC_INTERPRETER)
+#if !ENABLE(COMPUTED_GOTO_OPCODES)
// We have to initialize one of the pointer members to ensure that
// the entire struct is initialized, when opcode is not a pointer.
u.jsCell.clear();
diff --git a/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp b/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp
index 13a2defff..9e993ec65 100644
--- a/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp
+++ b/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp
@@ -2483,6 +2483,7 @@ PassRefPtr<Label> BytecodeGenerator::emitComplexJumpScopes(Label* target, Contro
context.start = afterFinally;
m_tryContextStack.append(context);
}
+ poppedTryContexts.clear();
}
if (flipLabelScopes)
m_labelScopes = savedLabelScopes;
diff --git a/Source/JavaScriptCore/dfg/DFGOperations.cpp b/Source/JavaScriptCore/dfg/DFGOperations.cpp
index 3452b2f0d..eaa0f47f7 100644
--- a/Source/JavaScriptCore/dfg/DFGOperations.cpp
+++ b/Source/JavaScriptCore/dfg/DFGOperations.cpp
@@ -1167,13 +1167,6 @@ JSCell* DFG_OPERATION operationCreateInlinedArguments(
return result;
}
-void DFG_OPERATION operationTearOffActivation(ExecState* exec, JSCell* activationCell)
-{
- JSGlobalData& globalData = exec->globalData();
- NativeCallFrameTracer tracer(&globalData, exec);
- jsCast<JSActivation*>(activationCell)->tearOff(exec->globalData());
-}
-
void DFG_OPERATION operationTearOffArguments(ExecState* exec, JSCell* argumentsCell, JSCell* activationCell)
{
ASSERT(exec->codeBlock()->usesArguments());
diff --git a/Source/JavaScriptCore/dfg/DFGOperations.h b/Source/JavaScriptCore/dfg/DFGOperations.h
index f86f5cf1f..3b947ecbf 100644
--- a/Source/JavaScriptCore/dfg/DFGOperations.h
+++ b/Source/JavaScriptCore/dfg/DFGOperations.h
@@ -177,7 +177,6 @@ char* DFG_OPERATION operationLinkConstruct(ExecState*) WTF_INTERNAL;
JSCell* DFG_OPERATION operationCreateActivation(ExecState*) WTF_INTERNAL;
JSCell* DFG_OPERATION operationCreateArguments(ExecState*) WTF_INTERNAL;
JSCell* DFG_OPERATION operationCreateInlinedArguments(ExecState*, InlineCallFrame*) WTF_INTERNAL;
-void DFG_OPERATION operationTearOffActivation(ExecState*, JSCell*) WTF_INTERNAL;
void DFG_OPERATION operationTearOffArguments(ExecState*, JSCell*, JSCell*) WTF_INTERNAL;
void DFG_OPERATION operationTearOffInlinedArguments(ExecState*, JSCell*, JSCell*, InlineCallFrame*) WTF_INTERNAL;
EncodedJSValue DFG_OPERATION operationGetArgumentsLength(ExecState*, int32_t) WTF_INTERNAL;
diff --git a/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp b/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp
index e42752d8a..05b1e741e 100644
--- a/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp
+++ b/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp
@@ -1907,9 +1907,10 @@ void SpeculativeJIT::compileValueToInt32(Node& node)
SpeculateBooleanOperand op1(this, node.child1());
GPRTemporary result(this, op1);
- m_jit.and32(JITCompiler::TrustedImm32(1), op1.gpr());
+ m_jit.move(op1.gpr(), result.gpr());
+ m_jit.and32(JITCompiler::TrustedImm32(1), result.gpr());
- integerResult(op1.gpr(), m_compileIndex);
+ integerResult(result.gpr(), m_compileIndex);
return;
}
diff --git a/Source/JavaScriptCore/dfg/DFGSpeculativeJIT32_64.cpp b/Source/JavaScriptCore/dfg/DFGSpeculativeJIT32_64.cpp
index 8039ad2ab..70709b52f 100644
--- a/Source/JavaScriptCore/dfg/DFGSpeculativeJIT32_64.cpp
+++ b/Source/JavaScriptCore/dfg/DFGSpeculativeJIT32_64.cpp
@@ -30,7 +30,7 @@
#if ENABLE(DFG_JIT)
#include "DFGSlowPathGenerator.h"
-#include "JSVariableObject.h"
+#include "JSActivation.h"
namespace JSC { namespace DFG {
@@ -4070,16 +4070,38 @@ void SpeculativeJIT::compile(Node& node)
case TearOffActivation: {
JSValueOperand activationValue(this, node.child1());
+ GPRTemporary scratch(this);
GPRReg activationValueTagGPR = activationValue.tagGPR();
GPRReg activationValuePayloadGPR = activationValue.payloadGPR();
+ GPRReg scratchGPR = scratch.gpr();
- JITCompiler::Jump created = m_jit.branch32(JITCompiler::NotEqual, activationValueTagGPR, TrustedImm32(JSValue::EmptyValueTag));
-
- addSlowPathGenerator(
- slowPathCall(
- created, this, operationTearOffActivation, NoResult, activationValuePayloadGPR));
+ JITCompiler::Jump notCreated = m_jit.branch32(JITCompiler::Equal, activationValueTagGPR, TrustedImm32(JSValue::EmptyValueTag));
+
+ SharedSymbolTable* symbolTable = m_jit.symbolTableFor(node.codeOrigin);
+ int registersOffset = JSActivation::registersOffset(symbolTable);
+
+ int captureEnd = symbolTable->captureEnd();
+ for (int i = symbolTable->captureStart(); i < captureEnd; ++i) {
+ m_jit.loadPtr(
+ JITCompiler::Address(
+ GPRInfo::callFrameRegister, i * sizeof(Register) + OBJECT_OFFSETOF(EncodedValueDescriptor, asBits.tag)),
+ scratchGPR);
+ m_jit.storePtr(
+ scratchGPR, JITCompiler::Address(
+ activationValuePayloadGPR, registersOffset + i * sizeof(Register) + OBJECT_OFFSETOF(EncodedValueDescriptor, asBits.tag)));
+ m_jit.loadPtr(
+ JITCompiler::Address(
+ GPRInfo::callFrameRegister, i * sizeof(Register) + OBJECT_OFFSETOF(EncodedValueDescriptor, asBits.payload)),
+ scratchGPR);
+ m_jit.storePtr(
+ scratchGPR, JITCompiler::Address(
+ activationValuePayloadGPR, registersOffset + i * sizeof(Register) + OBJECT_OFFSETOF(EncodedValueDescriptor, asBits.payload)));
+ }
+ m_jit.addPtr(TrustedImm32(registersOffset), activationValuePayloadGPR, scratchGPR);
+ m_jit.storePtr(scratchGPR, JITCompiler::Address(activationValuePayloadGPR, JSActivation::offsetOfRegisters()));
+ notCreated.link(&m_jit);
noResult(m_compileIndex);
break;
}
diff --git a/Source/JavaScriptCore/dfg/DFGSpeculativeJIT64.cpp b/Source/JavaScriptCore/dfg/DFGSpeculativeJIT64.cpp
index 8488d261d..d7cec27c1 100644
--- a/Source/JavaScriptCore/dfg/DFGSpeculativeJIT64.cpp
+++ b/Source/JavaScriptCore/dfg/DFGSpeculativeJIT64.cpp
@@ -4041,14 +4041,28 @@ void SpeculativeJIT::compile(Node& node)
ASSERT(!node.codeOrigin.inlineCallFrame);
JSValueOperand activationValue(this, node.child1());
+ GPRTemporary scratch(this);
GPRReg activationValueGPR = activationValue.gpr();
+ GPRReg scratchGPR = scratch.gpr();
- JITCompiler::Jump created = m_jit.branchTestPtr(JITCompiler::NonZero, activationValueGPR);
-
- addSlowPathGenerator(
- slowPathCall(
- created, this, operationTearOffActivation, NoResult, activationValueGPR));
-
+ JITCompiler::Jump notCreated = m_jit.branchTestPtr(JITCompiler::Zero, activationValueGPR);
+
+ SharedSymbolTable* symbolTable = m_jit.symbolTableFor(node.codeOrigin);
+ int registersOffset = JSActivation::registersOffset(symbolTable);
+
+ int captureEnd = symbolTable->captureEnd();
+ for (int i = symbolTable->captureStart(); i < captureEnd; ++i) {
+ m_jit.loadPtr(
+ JITCompiler::Address(
+ GPRInfo::callFrameRegister, i * sizeof(Register)), scratchGPR);
+ m_jit.storePtr(
+ scratchGPR, JITCompiler::Address(
+ activationValueGPR, registersOffset + i * sizeof(Register)));
+ }
+ m_jit.addPtr(TrustedImm32(registersOffset), activationValueGPR, scratchGPR);
+ m_jit.storePtr(scratchGPR, JITCompiler::Address(activationValueGPR, JSActivation::offsetOfRegisters()));
+
+ notCreated.link(&m_jit);
noResult(m_compileIndex);
break;
}
diff --git a/Source/JavaScriptCore/interpreter/AbstractPC.cpp b/Source/JavaScriptCore/interpreter/AbstractPC.cpp
index f986e8872..12bc3a768 100644
--- a/Source/JavaScriptCore/interpreter/AbstractPC.cpp
+++ b/Source/JavaScriptCore/interpreter/AbstractPC.cpp
@@ -45,12 +45,6 @@ AbstractPC::AbstractPC(JSGlobalData& globalData, ExecState* exec)
return;
}
#endif
-
-#if ENABLE(CLASSIC_INTERPRETER)
- UNUSED_PARAM(globalData);
- m_pointer = exec->returnVPC();
- m_mode = Interpreter;
-#endif
}
} // namespace JSC
diff --git a/Source/JavaScriptCore/interpreter/AbstractPC.h b/Source/JavaScriptCore/interpreter/AbstractPC.h
index 5ed74472e..09a6db8ea 100644
--- a/Source/JavaScriptCore/interpreter/AbstractPC.h
+++ b/Source/JavaScriptCore/interpreter/AbstractPC.h
@@ -60,21 +60,6 @@ public:
}
#endif
-#if ENABLE(CLASSIC_INTERPRETER)
- AbstractPC(Instruction* vPC)
- : m_pointer(vPC)
- , m_mode(Interpreter)
- {
- }
-
- bool hasInterpreterReturnAddress() const { return m_mode == Interpreter; }
- Instruction* interpreterReturnAddress() const
- {
- ASSERT(hasInterpreterReturnAddress());
- return static_cast<Instruction*>(m_pointer);
- }
-#endif
-
bool isSet() const { return m_mode != None; }
bool operator!() const { return !isSet(); }
diff --git a/Source/JavaScriptCore/interpreter/CallFrame.h b/Source/JavaScriptCore/interpreter/CallFrame.h
index da1222ac9..4758e5bd0 100644
--- a/Source/JavaScriptCore/interpreter/CallFrame.h
+++ b/Source/JavaScriptCore/interpreter/CallFrame.h
@@ -148,9 +148,6 @@ namespace JSC {
return 0;
}
#endif
-#if ENABLE(CLASSIC_INTERPRETER)
- Instruction* returnVPC() const { return this[RegisterFile::ReturnPC].vPC(); }
-#endif
#if USE(JSVALUE32_64)
Instruction* currentVPC() const
{
diff --git a/Source/JavaScriptCore/interpreter/Interpreter.cpp b/Source/JavaScriptCore/interpreter/Interpreter.cpp
index 3b3409bd6..3107a5dab 100644
--- a/Source/JavaScriptCore/interpreter/Interpreter.cpp
+++ b/Source/JavaScriptCore/interpreter/Interpreter.cpp
@@ -72,7 +72,7 @@
#include "JIT.h"
#endif
-#define WTF_USE_GCC_COMPUTED_GOTO_WORKAROUND ((ENABLE(COMPUTED_GOTO_CLASSIC_INTERPRETER) || ENABLE(LLINT)) && !defined(__llvm__))
+#define WTF_USE_GCC_COMPUTED_GOTO_WORKAROUND (ENABLE(LLINT) && !defined(__llvm__))
using namespace std;
@@ -88,14 +88,6 @@ static int depth(CodeBlock* codeBlock, JSScope* sc)
return sc->localDepth();
}
-#if ENABLE(CLASSIC_INTERPRETER)
-static NEVER_INLINE JSValue concatenateStrings(ExecState* exec, Register* strings, unsigned count)
-{
- return jsString(exec, strings, count);
-}
-
-#endif // ENABLE(CLASSIC_INTERPRETER)
-
ALWAYS_INLINE CallFrame* Interpreter::slideRegisterWindowForCall(CodeBlock* newCodeBlock, RegisterFile* registerFile, CallFrame* callFrame, size_t registerOffset, int argumentCountIncludingThis)
{
// This ensures enough space for the worst case scenario of zero arguments passed by the caller.
@@ -123,16 +115,6 @@ ALWAYS_INLINE CallFrame* Interpreter::slideRegisterWindowForCall(CodeBlock* newC
return newCallFrame;
}
-#if ENABLE(CLASSIC_INTERPRETER)
-static NEVER_INLINE bool isInvalidParamForIn(CallFrame* callFrame, JSValue value, JSValue& exceptionData)
-{
- if (value.isObject())
- return false;
- exceptionData = createInvalidParamError(callFrame, "in" , value);
- return true;
-}
-#endif
-
JSValue eval(CallFrame* callFrame)
{
if (!callFrame->argumentCount())
@@ -166,6 +148,9 @@ JSValue eval(CallFrame* callFrame)
return parsedObject;
}
}
+
+ // If the literal parser bailed, it should not have thrown exceptions.
+ ASSERT(!callFrame->globalData().exception);
JSValue exceptionValue;
eval = callerCodeBlock->evalCodeCache().getSlow(callFrame, callerCodeBlock->ownerExecutable(), callerCodeBlock->isStrictMode(), programSource, callerScopeChain, exceptionValue);
@@ -265,59 +250,22 @@ Interpreter::Interpreter()
#if !ASSERT_DISABLED
, m_initialized(false)
#endif
- , m_classicEnabled(false)
{
}
Interpreter::~Interpreter()
{
-#if ENABLE(LLINT) && ENABLE(COMPUTED_GOTO_OPCODES)
- if (m_classicEnabled)
- delete[] m_opcodeTable;
-#endif
}
void Interpreter::initialize(bool canUseJIT)
{
UNUSED_PARAM(canUseJIT);
- // If we have LLInt, then we shouldn't be building any kind of classic interpreter.
-#if ENABLE(LLINT) && ENABLE(CLASSIC_INTERPRETER)
-#error "Building both LLInt and the Classic Interpreter is not supported because it doesn't make sense."
-#endif
-
-#if ENABLE(COMPUTED_GOTO_OPCODES)
-#if ENABLE(LLINT)
+#if ENABLE(COMPUTED_GOTO_OPCODES) && ENABLE(LLINT)
m_opcodeTable = LLInt::opcodeMap();
for (int i = 0; i < numOpcodeIDs; ++i)
m_opcodeIDTable.add(m_opcodeTable[i], static_cast<OpcodeID>(i));
- m_classicEnabled = false;
-
-#elif ENABLE(COMPUTED_GOTO_CLASSIC_INTERPRETER)
- if (canUseJIT) {
- // If the JIT is present, don't use jump destinations for opcodes.
- for (int i = 0; i < numOpcodeIDs; ++i) {
- Opcode opcode = bitwise_cast<void*>(static_cast<uintptr_t>(i));
- m_opcodeTable[i] = opcode;
- }
- m_classicEnabled = false;
- } else {
- privateExecute(InitializeAndReturn, 0, 0);
-
- for (int i = 0; i < numOpcodeIDs; ++i)
- m_opcodeIDTable.add(m_opcodeTable[i], static_cast<OpcodeID>(i));
-
- m_classicEnabled = true;
- }
-#endif // ENABLE(COMPUTED_GOTO_CLASSIC_INTERPRETER)
-
-#else // !ENABLE(COMPUTED_GOTO_OPCODES)
-#if ENABLE(CLASSIC_INTERPRETER)
- m_classicEnabled = true;
-#else
- m_classicEnabled = false;
#endif
-#endif // !ENABLE(COMPUTED_GOTO_OPCODES)
#if !ASSERT_DISABLED
m_initialized = true;
@@ -431,12 +379,12 @@ bool Interpreter::isOpcode(Opcode opcode)
{
#if ENABLE(COMPUTED_GOTO_OPCODES)
#if !ENABLE(LLINT)
- if (!m_classicEnabled)
- return static_cast<OpcodeID>(bitwise_cast<uintptr_t>(opcode)) <= op_end;
-#endif
+ return static_cast<OpcodeID>(bitwise_cast<uintptr_t>(opcode)) <= op_end;
+#else
return opcode != HashTraits<Opcode>::emptyValue()
&& !HashTraits<Opcode>::isDeletedValue(opcode)
&& m_opcodeIDTable.contains(opcode);
+#endif
#else
return opcode >= 0 && opcode <= op_end;
#endif
@@ -481,19 +429,8 @@ NEVER_INLINE bool Interpreter::unwindCallFrame(CallFrame*& callFrame, JSValue ex
// Because of how the JIT records call site->bytecode offset
// information the JIT reports the bytecodeOffset for the returnPC
// to be at the beginning of the opcode that has caused the call.
- // In the interpreter we have an actual return address, which is
- // the beginning of next instruction to execute. To get an offset
- // inside the call instruction that triggered the exception we
- // have to subtract 1.
-#if ENABLE(JIT) && ENABLE(CLASSIC_INTERPRETER)
- if (callerFrame->globalData().canUseJIT())
- bytecodeOffset = codeBlock->bytecodeOffset(callerFrame, callFrame->returnPC());
- else
- bytecodeOffset = codeBlock->bytecodeOffset(callFrame->returnVPC()) - 1;
-#elif ENABLE(JIT) || ENABLE(LLINT)
+#if ENABLE(JIT) || ENABLE(LLINT)
bytecodeOffset = codeBlock->bytecodeOffset(callerFrame, callFrame->returnPC());
-#else
- bytecodeOffset = codeBlock->bytecodeOffset(callFrame->returnVPC()) - 1;
#endif
callFrame = callerFrame;
@@ -559,18 +496,12 @@ static int getLineNumberForCallFrame(JSGlobalData* globalData, CallFrame* callFr
CodeBlock* codeBlock = callFrame->codeBlock();
if (!codeBlock)
return -1;
-#if ENABLE(CLASSIC_INTERPRETER)
- if (!globalData->canUseJIT())
- return codeBlock->lineNumberForBytecodeOffset(callFrame->bytecodeOffsetForNonDFGCode() - 1);
-#endif
#if ENABLE(JIT) || ENABLE(LLINT)
#if ENABLE(DFG_JIT)
if (codeBlock->getJITType() == JITCode::DFGJIT)
return codeBlock->lineNumberForBytecodeOffset(codeBlock->codeOrigin(callFrame->codeOriginIndexForDFG()).bytecodeIndex);
#endif
return codeBlock->lineNumberForBytecodeOffset(callFrame->bytecodeOffsetForNonDFGCode());
-#else
- return -1;
#endif
}
@@ -601,13 +532,6 @@ static CallFrame* getCallerInfo(JSGlobalData* globalData, CallFrame* callFrame,
if (callframeIsHost) {
// Don't need to deal with inline callframes here as by definition we haven't
// inlined a call with an intervening native call frame.
-#if ENABLE(CLASSIC_INTERPRETER)
- if (!globalData->canUseJIT()) {
- bytecodeOffset = callerFrame->bytecodeOffsetForNonDFGCode();
- lineNumber = callerCodeBlock->lineNumberForBytecodeOffset(bytecodeOffset - 1);
- return callerFrame;
- }
-#endif
#if ENABLE(JIT) || ENABLE(LLINT)
#if ENABLE(DFG_JIT)
if (callerCodeBlock && callerCodeBlock->getJITType() == JITCode::DFGJIT) {
@@ -618,13 +542,6 @@ static CallFrame* getCallerInfo(JSGlobalData* globalData, CallFrame* callFrame,
bytecodeOffset = callerFrame->bytecodeOffsetForNonDFGCode();
#endif
} else {
-#if ENABLE(CLASSIC_INTERPRETER)
- if (!globalData->canUseJIT()) {
- bytecodeOffset = callerCodeBlock->bytecodeOffset(callFrame->returnVPC());
- lineNumber = callerCodeBlock->lineNumberForBytecodeOffset(bytecodeOffset - 1);
- return callerFrame;
- }
-#endif
#if ENABLE(JIT) || ENABLE(LLINT)
#if ENABLE(DFG_JIT)
if (callFrame->isInlineCallFrame()) {
@@ -662,16 +579,7 @@ static CallFrame* getCallerInfo(JSGlobalData* globalData, CallFrame* callFrame,
static ALWAYS_INLINE const String getSourceURLFromCallFrame(CallFrame* callFrame)
{
ASSERT(!callFrame->hasHostCallFrameFlag());
-#if ENABLE(CLASSIC_INTERPRETER)
-#if ENABLE(JIT)
- if (callFrame->globalData().canUseJIT())
- return callFrame->codeBlock()->ownerExecutable()->sourceURL();
-#endif
- return callFrame->codeBlock()->source()->url();
-
-#else
return callFrame->codeBlock()->ownerExecutable()->sourceURL();
-#endif
}
static StackFrameCodeType getStackFrameCodeType(CallFrame* callFrame)
@@ -978,14 +886,9 @@ failedJSONP:
m_reentryDepth++;
#if ENABLE(LLINT_C_LOOP)
result = LLInt::CLoop::execute(newCallFrame, llint_program_prologue);
-#else // !ENABLE(LLINT_C_LOOP)
-#if ENABLE(JIT)
- if (!classicEnabled())
- result = program->generatedJITCode().execute(&m_registerFile, newCallFrame, scope->globalData());
- else
+#elif ENABLE(JIT)
+ result = program->generatedJITCode().execute(&m_registerFile, newCallFrame, scope->globalData());
#endif // ENABLE(JIT)
- result = privateExecute(Normal, &m_registerFile, newCallFrame);
-#endif // !ENABLE(LLINT_C_LOOP)
m_reentryDepth--;
}
@@ -1054,14 +957,9 @@ JSValue Interpreter::executeCall(CallFrame* callFrame, JSObject* function, CallT
m_reentryDepth++;
#if ENABLE(LLINT_C_LOOP)
result = LLInt::CLoop::execute(newCallFrame, llint_function_for_call_prologue);
-#else // ENABLE(LLINT_C_LOOP)
-#if ENABLE(JIT)
- if (!classicEnabled())
- result = callData.js.functionExecutable->generatedJITCodeForCall().execute(&m_registerFile, newCallFrame, callDataScope->globalData());
- else
+#elif ENABLE(JIT)
+ result = callData.js.functionExecutable->generatedJITCodeForCall().execute(&m_registerFile, newCallFrame, callDataScope->globalData());
#endif // ENABLE(JIT)
- result = privateExecute(Normal, &m_registerFile, newCallFrame);
-#endif // !ENABLE(LLINT_C_LOOP)
m_reentryDepth--;
}
@@ -1153,14 +1051,9 @@ JSObject* Interpreter::executeConstruct(CallFrame* callFrame, JSObject* construc
m_reentryDepth++;
#if ENABLE(LLINT_C_LOOP)
result = LLInt::CLoop::execute(newCallFrame, llint_function_for_construct_prologue);
-#else // !ENABLE(LLINT_C_LOOP)
-#if ENABLE(JIT)
- if (!classicEnabled())
- result = constructData.js.functionExecutable->generatedJITCodeForConstruct().execute(&m_registerFile, newCallFrame, constructDataScope->globalData());
- else
+#elif ENABLE(JIT)
+ result = constructData.js.functionExecutable->generatedJITCodeForConstruct().execute(&m_registerFile, newCallFrame, constructDataScope->globalData());
#endif // ENABLE(JIT)
- result = privateExecute(Normal, &m_registerFile, newCallFrame);
-#endif // !ENABLE(LLINT_C_LOOP)
m_reentryDepth--;
}
@@ -1260,21 +1153,9 @@ JSValue Interpreter::execute(CallFrameClosure& closure)
m_reentryDepth++;
#if ENABLE(LLINT_C_LOOP)
result = LLInt::CLoop::execute(closure.newCallFrame, llint_function_for_call_prologue);
-#else // !ENABLE(LLINT_C_LOOP)
-#if ENABLE(JIT)
-#if ENABLE(CLASSIC_INTERPRETER)
- if (closure.newCallFrame->globalData().canUseJIT())
-#endif
- result = closure.functionExecutable->generatedJITCodeForCall().execute(&m_registerFile, closure.newCallFrame, closure.globalData);
-#if ENABLE(CLASSIC_INTERPRETER)
- else
-#endif
+#elif ENABLE(JIT)
+ result = closure.functionExecutable->generatedJITCodeForCall().execute(&m_registerFile, closure.newCallFrame, closure.globalData);
#endif // ENABLE(JIT)
-#if ENABLE(CLASSIC_INTERPRETER)
- result = privateExecute(Normal, &m_registerFile, closure.newCallFrame);
-#endif
-#endif // !ENABLE(LLINT_C_LOOP)
-
m_reentryDepth--;
}
@@ -1365,20 +1246,9 @@ JSValue Interpreter::execute(EvalExecutable* eval, CallFrame* callFrame, JSValue
#if ENABLE(LLINT_C_LOOP)
result = LLInt::CLoop::execute(newCallFrame, llint_eval_prologue);
-#else // !ENABLE(LLINT_C_LOOP)
-#if ENABLE(JIT)
-#if ENABLE(CLASSIC_INTERPRETER)
- if (callFrame->globalData().canUseJIT())
-#endif
- result = eval->generatedJITCode().execute(&m_registerFile, newCallFrame, scope->globalData());
-#if ENABLE(CLASSIC_INTERPRETER)
- else
-#endif
+#elif ENABLE(JIT)
+ result = eval->generatedJITCode().execute(&m_registerFile, newCallFrame, scope->globalData());
#endif // ENABLE(JIT)
-#if ENABLE(CLASSIC_INTERPRETER)
- result = privateExecute(Normal, &m_registerFile, newCallFrame);
-#endif
-#endif // !ENABLE(LLINT_C_LOOP)
m_reentryDepth--;
}
@@ -1417,3693 +1287,6 @@ NEVER_INLINE void Interpreter::debug(CallFrame* callFrame, DebugHookID debugHook
}
}
-#if ENABLE(CLASSIC_INTERPRETER)
-NEVER_INLINE JSScope* Interpreter::createNameScope(CallFrame* callFrame, const Instruction* vPC)
-{
- CodeBlock* codeBlock = callFrame->codeBlock();
- Identifier& property = codeBlock->identifier(vPC[1].u.operand);
- JSValue value = callFrame->r(vPC[2].u.operand).jsValue();
- unsigned attributes = vPC[3].u.operand;
- JSNameScope* scope = JSNameScope::create(callFrame, property, value, attributes);
- return scope;
-}
-
-NEVER_INLINE void Interpreter::tryCachePutByID(CallFrame* callFrame, CodeBlock* codeBlock, Instruction* vPC, JSValue baseValue, const PutPropertySlot& slot)
-{
- // Recursive invocation may already have specialized this instruction.
- if (vPC[0].u.opcode != getOpcode(op_put_by_id))
- return;
-
- if (!baseValue.isCell())
- return;
-
- // Uncacheable: give up.
- if (!slot.isCacheable()) {
- vPC[0] = getOpcode(op_put_by_id_generic);
- return;
- }
-
- JSCell* baseCell = baseValue.asCell();
- Structure* structure = baseCell->structure();
-
- if (structure->isUncacheableDictionary() || structure->typeInfo().prohibitsPropertyCaching()) {
- vPC[0] = getOpcode(op_put_by_id_generic);
- return;
- }
-
- // Cache miss: record Structure to compare against next time.
- Structure* lastStructure = vPC[4].u.structure.get();
- if (structure != lastStructure) {
- // First miss: record Structure to compare against next time.
- if (!lastStructure) {
- vPC[4].u.structure.set(callFrame->globalData(), codeBlock->ownerExecutable(), structure);
- return;
- }
-
- // Second miss: give up.
- vPC[0] = getOpcode(op_put_by_id_generic);
- return;
- }
-
- // Cache hit: Specialize instruction and ref Structures.
-
- // If baseCell != slot.base(), then baseCell must be a proxy for another object.
- if (baseCell != slot.base()) {
- vPC[0] = getOpcode(op_put_by_id_generic);
- return;
- }
-
- // Structure transition, cache transition info
- if (slot.type() == PutPropertySlot::NewProperty) {
- if (structure->isDictionary()) {
- vPC[0] = getOpcode(op_put_by_id_generic);
- return;
- }
-
- // put_by_id_transition checks the prototype chain for setters.
- normalizePrototypeChain(callFrame, baseCell);
- JSCell* owner = codeBlock->ownerExecutable();
- JSGlobalData& globalData = callFrame->globalData();
- // Get the prototype here because the call to prototypeChain could cause a
- // GC allocation, which we don't want to happen while we're in the middle of
- // initializing the union.
- StructureChain* prototypeChain = structure->prototypeChain(callFrame);
- vPC[0] = getOpcode(op_put_by_id_transition);
- vPC[4].u.structure.set(globalData, owner, structure->previousID());
- vPC[5].u.structure.set(globalData, owner, structure);
- vPC[6].u.structureChain.set(callFrame->globalData(), codeBlock->ownerExecutable(), prototypeChain);
- ASSERT(vPC[6].u.structureChain);
- vPC[7] = slot.cachedOffset();
- return;
- }
-
- vPC[0] = getOpcode(op_put_by_id_replace);
- vPC[5] = slot.cachedOffset();
-}
-
-NEVER_INLINE void Interpreter::uncachePutByID(CodeBlock*, Instruction* vPC)
-{
- vPC[0] = getOpcode(op_put_by_id);
- vPC[4] = 0;
-}
-
-NEVER_INLINE void Interpreter::tryCacheGetByID(CallFrame* callFrame, CodeBlock* codeBlock, Instruction* vPC, JSValue baseValue, const Identifier& propertyName, const PropertySlot& slot)
-{
- // Recursive invocation may already have specialized this instruction.
- if (vPC[0].u.opcode != getOpcode(op_get_by_id))
- return;
-
- // FIXME: Cache property access for immediates.
- if (!baseValue.isCell()) {
- vPC[0] = getOpcode(op_get_by_id_generic);
- return;
- }
-
- if (isJSArray(baseValue) && propertyName == callFrame->propertyNames().length) {
- vPC[0] = getOpcode(op_get_array_length);
- return;
- }
-
- if (isJSString(baseValue) && propertyName == callFrame->propertyNames().length) {
- vPC[0] = getOpcode(op_get_string_length);
- return;
- }
-
- // Uncacheable: give up.
- if (!slot.isCacheable()) {
- vPC[0] = getOpcode(op_get_by_id_generic);
- return;
- }
-
- Structure* structure = baseValue.asCell()->structure();
-
- if (structure->isUncacheableDictionary() || structure->typeInfo().prohibitsPropertyCaching()) {
- vPC[0] = getOpcode(op_get_by_id_generic);
- return;
- }
-
- // Cache miss
- Structure* lastStructure = vPC[4].u.structure.get();
- if (structure != lastStructure) {
- // First miss: record Structure to compare against next time.
- if (!lastStructure) {
- vPC[4].u.structure.set(callFrame->globalData(), codeBlock->ownerExecutable(), structure);
- return;
- }
-
- // Second miss: give up.
- vPC[0] = getOpcode(op_get_by_id_generic);
- return;
- }
-
- // Cache hit: Specialize instruction and ref Structures.
-
- if (slot.slotBase() == baseValue) {
- switch (slot.cachedPropertyType()) {
- case PropertySlot::Getter:
- vPC[0] = getOpcode(op_get_by_id_getter_self);
- vPC[5] = slot.cachedOffset();
- break;
- case PropertySlot::Custom:
- vPC[0] = getOpcode(op_get_by_id_custom_self);
- vPC[5] = slot.customGetter();
- break;
- default:
- vPC[0] = getOpcode(op_get_by_id_self);
- vPC[5] = slot.cachedOffset();
- break;
- }
- return;
- }
-
- if (structure->isDictionary()) {
- vPC[0] = getOpcode(op_get_by_id_generic);
- return;
- }
-
- if (slot.slotBase() == structure->prototypeForLookup(callFrame)) {
- ASSERT(slot.slotBase().isObject());
-
- JSObject* baseObject = asObject(slot.slotBase());
- PropertyOffset offset = slot.cachedOffset();
-
- // Since we're accessing a prototype in a loop, it's a good bet that it
- // should not be treated as a dictionary.
- if (baseObject->structure()->isDictionary()) {
- baseObject->flattenDictionaryObject(callFrame->globalData());
- offset = baseObject->structure()->get(callFrame->globalData(), propertyName);
- }
-
- ASSERT(!baseObject->structure()->isUncacheableDictionary());
-
- switch (slot.cachedPropertyType()) {
- case PropertySlot::Getter:
- vPC[0] = getOpcode(op_get_by_id_getter_proto);
- vPC[6] = offset;
- break;
- case PropertySlot::Custom:
- vPC[0] = getOpcode(op_get_by_id_custom_proto);
- vPC[6] = slot.customGetter();
- break;
- default:
- vPC[0] = getOpcode(op_get_by_id_proto);
- vPC[6] = offset;
- break;
- }
- vPC[5].u.structure.set(callFrame->globalData(), codeBlock->ownerExecutable(), baseObject->structure());
- return;
- }
-
- PropertyOffset offset = slot.cachedOffset();
- size_t count = normalizePrototypeChain(callFrame, baseValue, slot.slotBase(), propertyName, offset);
- if (!count) {
- vPC[0] = getOpcode(op_get_by_id_generic);
- return;
- }
-
-
- StructureChain* prototypeChain = structure->prototypeChain(callFrame);
- switch (slot.cachedPropertyType()) {
- case PropertySlot::Getter:
- vPC[0] = getOpcode(op_get_by_id_getter_chain);
- vPC[7] = offset;
- break;
- case PropertySlot::Custom:
- vPC[0] = getOpcode(op_get_by_id_custom_chain);
- vPC[7] = slot.customGetter();
- break;
- default:
- vPC[0] = getOpcode(op_get_by_id_chain);
- vPC[7] = offset;
- break;
- }
- vPC[4].u.structure.set(callFrame->globalData(), codeBlock->ownerExecutable(), structure);
- vPC[5].u.structureChain.set(callFrame->globalData(), codeBlock->ownerExecutable(), prototypeChain);
- vPC[6] = count;
-}
-
-NEVER_INLINE void Interpreter::uncacheGetByID(CodeBlock*, Instruction* vPC)
-{
- vPC[0] = getOpcode(op_get_by_id);
- vPC[4] = 0;
-}
-
-#endif // ENABLE(CLASSIC_INTERPRETER)
-
-#if !ENABLE(LLINT_C_LOOP)
-
-JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFile, CallFrame* callFrame)
-{
- // One-time initialization of our address tables. We have to put this code
- // here because our labels are only in scope inside this function.
- if (UNLIKELY(flag == InitializeAndReturn)) {
- #if ENABLE(COMPUTED_GOTO_CLASSIC_INTERPRETER)
- #define LIST_OPCODE_LABEL(id, length) &&id,
- static Opcode labels[] = { FOR_EACH_OPCODE_ID(LIST_OPCODE_LABEL) };
- for (size_t i = 0; i < WTF_ARRAY_LENGTH(labels); ++i)
- m_opcodeTable[i] = labels[i];
- #undef LIST_OPCODE_LABEL
- #endif // ENABLE(COMPUTED_GOTO_CLASSIC_INTERPRETER)
- return JSValue();
- }
-
- ASSERT(m_initialized);
- ASSERT(m_classicEnabled);
-
-#if ENABLE(JIT)
-#if ENABLE(CLASSIC_INTERPRETER)
- // Mixing Interpreter + JIT is not supported.
- if (callFrame->globalData().canUseJIT())
-#endif
- ASSERT_NOT_REACHED();
-#endif
-
-#if !ENABLE(CLASSIC_INTERPRETER)
- UNUSED_PARAM(registerFile);
- UNUSED_PARAM(callFrame);
- return JSValue();
-#else
-
- ASSERT(callFrame->globalData().topCallFrame == callFrame);
-
- JSGlobalData* globalData = &callFrame->globalData();
- JSValue exceptionValue;
- HandlerInfo* handler = 0;
- CallFrame** topCallFrameSlot = &globalData->topCallFrame;
-
- CodeBlock* codeBlock = callFrame->codeBlock();
- Instruction* vPC = codeBlock->instructions().begin();
- unsigned tickCount = globalData->timeoutChecker.ticksUntilNextCheck();
- JSValue functionReturnValue;
-
-#define CHECK_FOR_EXCEPTION() \
- do { \
- if (UNLIKELY(globalData->exception != JSValue())) { \
- exceptionValue = globalData->exception; \
- goto vm_throw; \
- } \
- } while (0)
-
-#if ENABLE(OPCODE_STATS)
- OpcodeStats::resetLastInstruction();
-#endif
-
-#define CHECK_FOR_TIMEOUT() \
- if (!--tickCount) { \
- if (globalData->terminator.shouldTerminate() || globalData->timeoutChecker.didTimeOut(callFrame)) { \
- exceptionValue = jsNull(); \
- goto vm_throw; \
- } \
- tickCount = globalData->timeoutChecker.ticksUntilNextCheck(); \
- }
-
-#if ENABLE(OPCODE_SAMPLING)
- #define SAMPLE(codeBlock, vPC) m_sampler->sample(codeBlock, vPC)
-#else
- #define SAMPLE(codeBlock, vPC)
-#endif
-
-#define UPDATE_BYTECODE_OFFSET() \
- do {\
- callFrame->setBytecodeOffsetForNonDFGCode(vPC - codeBlock->instructions().data() + 1);\
- } while (0)
-
-#if ENABLE(COMPUTED_GOTO_CLASSIC_INTERPRETER)
- #define NEXT_INSTRUCTION() SAMPLE(codeBlock, vPC); goto *vPC->u.opcode
-#if ENABLE(OPCODE_STATS)
- #define DEFINE_OPCODE(opcode) \
- opcode:\
- OpcodeStats::recordInstruction(opcode);\
- UPDATE_BYTECODE_OFFSET();
-#else
- #define DEFINE_OPCODE(opcode) opcode: UPDATE_BYTECODE_OFFSET();
-#endif // !ENABLE(OPCODE_STATS)
- NEXT_INSTRUCTION();
-#else // !ENABLE(COMPUTED_GOTO_CLASSIC_INTERPRETER)
- #define NEXT_INSTRUCTION() SAMPLE(codeBlock, vPC); goto interpreterLoopStart
-#if ENABLE(OPCODE_STATS)
- #define DEFINE_OPCODE(opcode) \
- case opcode:\
- OpcodeStats::recordInstruction(opcode);\
- UPDATE_BYTECODE_OFFSET();
-#else
- #define DEFINE_OPCODE(opcode) case opcode: UPDATE_BYTECODE_OFFSET();
-#endif
- while (1) { // iterator loop begins
- interpreterLoopStart:;
- switch (vPC->u.opcode)
-#endif // !ENABLE(COMPUTED_GOTO_CLASSIC_INTERPRETER)
- {
- DEFINE_OPCODE(op_new_object) {
- /* new_object dst(r)
-
- Constructs a new empty Object instance using the original
- constructor, and puts the result in register dst.
- */
- int dst = vPC[1].u.operand;
- callFrame->uncheckedR(dst) = JSValue(constructEmptyObject(callFrame));
-
- vPC += OPCODE_LENGTH(op_new_object);
- NEXT_INSTRUCTION();
- }
- DEFINE_OPCODE(op_new_array) {
- /* new_array dst(r) firstArg(r) argCount(n)
-
- Constructs a new Array instance using the original
- constructor, and puts the result in register dst.
- The array will contain argCount elements with values
- taken from registers starting at register firstArg.
- */
- int dst = vPC[1].u.operand;
- int firstArg = vPC[2].u.operand;
- int argCount = vPC[3].u.operand;
- callFrame->uncheckedR(dst) = JSValue(constructArray(callFrame, reinterpret_cast<JSValue*>(&callFrame->registers()[firstArg]), argCount));
-
- vPC += OPCODE_LENGTH(op_new_array);
- NEXT_INSTRUCTION();
- }
- DEFINE_OPCODE(op_new_array_buffer) {
- /* new_array_buffer dst(r) index(n) argCount(n)
-
- Constructs a new Array instance using the original
- constructor, and puts the result in register dst.
- The array be initialized with the values from constantBuffer[index]
- */
- int dst = vPC[1].u.operand;
- int firstArg = vPC[2].u.operand;
- int argCount = vPC[3].u.operand;
- callFrame->uncheckedR(dst) = JSValue(constructArray(callFrame, codeBlock->constantBuffer(firstArg), argCount));
-
- vPC += OPCODE_LENGTH(op_new_array);
- NEXT_INSTRUCTION();
- }
- DEFINE_OPCODE(op_new_regexp) {
- /* new_regexp dst(r) regExp(re)
-
- Constructs a new RegExp instance using the original
- constructor from regexp regExp, and puts the result in
- register dst.
- */
- int dst = vPC[1].u.operand;
- RegExp* regExp = codeBlock->regexp(vPC[2].u.operand);
- if (!regExp->isValid()) {
- exceptionValue = createSyntaxError(callFrame, "Invalid flags supplied to RegExp constructor.");
- goto vm_throw;
- }
- callFrame->uncheckedR(dst) = JSValue(RegExpObject::create(*globalData, callFrame->lexicalGlobalObject(), callFrame->scope()->globalObject()->regExpStructure(), regExp));
-
- vPC += OPCODE_LENGTH(op_new_regexp);
- NEXT_INSTRUCTION();
- }
- DEFINE_OPCODE(op_mov) {
- /* mov dst(r) src(r)
-
- Copies register src to register dst.
- */
- int dst = vPC[1].u.operand;
- int src = vPC[2].u.operand;
-
- callFrame->uncheckedR(dst) = callFrame->r(src);
-
- vPC += OPCODE_LENGTH(op_mov);
- NEXT_INSTRUCTION();
- }
- DEFINE_OPCODE(op_eq) {
- /* eq dst(r) src1(r) src2(r)
-
- Checks whether register src1 and register src2 are equal,
- as with the ECMAScript '==' operator, and puts the result
- as a boolean in register dst.
- */
- int dst = vPC[1].u.operand;
- JSValue src1 = callFrame->r(vPC[2].u.operand).jsValue();
- JSValue src2 = callFrame->r(vPC[3].u.operand).jsValue();
- if (src1.isInt32() && src2.isInt32())
- callFrame->uncheckedR(dst) = jsBoolean(src1.asInt32() == src2.asInt32());
- else {
- JSValue result = jsBoolean(JSValue::equalSlowCase(callFrame, src1, src2));
- CHECK_FOR_EXCEPTION();
- callFrame->uncheckedR(dst) = result;
- }
-
- vPC += OPCODE_LENGTH(op_eq);
- NEXT_INSTRUCTION();
- }
- DEFINE_OPCODE(op_eq_null) {
- /* eq_null dst(r) src(r)
-
- Checks whether register src is null, as with the ECMAScript '!='
- operator, and puts the result as a boolean in register dst.
- */
- int dst = vPC[1].u.operand;
- JSValue src = callFrame->r(vPC[2].u.operand).jsValue();
-
- if (src.isUndefinedOrNull()) {
- callFrame->uncheckedR(dst) = jsBoolean(true);
- vPC += OPCODE_LENGTH(op_eq_null);
- NEXT_INSTRUCTION();
- }
-
- callFrame->uncheckedR(dst) = jsBoolean(src.isCell() && src.asCell()->structure()->masqueradesAsUndefined(callFrame->lexicalGlobalObject()));
- vPC += OPCODE_LENGTH(op_eq_null);
- NEXT_INSTRUCTION();
- }
- DEFINE_OPCODE(op_neq) {
- /* neq dst(r) src1(r) src2(r)
-
- Checks whether register src1 and register src2 are not
- equal, as with the ECMAScript '!=' operator, and puts the
- result as a boolean in register dst.
- */
- int dst = vPC[1].u.operand;
- JSValue src1 = callFrame->r(vPC[2].u.operand).jsValue();
- JSValue src2 = callFrame->r(vPC[3].u.operand).jsValue();
- if (src1.isInt32() && src2.isInt32())
- callFrame->uncheckedR(dst) = jsBoolean(src1.asInt32() != src2.asInt32());
- else {
- JSValue result = jsBoolean(!JSValue::equalSlowCase(callFrame, src1, src2));
- CHECK_FOR_EXCEPTION();
- callFrame->uncheckedR(dst) = result;
- }
-
- vPC += OPCODE_LENGTH(op_neq);
- NEXT_INSTRUCTION();
- }
- DEFINE_OPCODE(op_neq_null) {
- /* neq_null dst(r) src(r)
-
- Checks whether register src is not null, as with the ECMAScript '!='
- operator, and puts the result as a boolean in register dst.
- */
- int dst = vPC[1].u.operand;
- JSValue src = callFrame->r(vPC[2].u.operand).jsValue();
-
- if (src.isUndefinedOrNull()) {
- callFrame->uncheckedR(dst) = jsBoolean(false);
- vPC += OPCODE_LENGTH(op_neq_null);
- NEXT_INSTRUCTION();
- }
-
- callFrame->uncheckedR(dst) = jsBoolean(!src.isCell() || !src.asCell()->structure()->masqueradesAsUndefined(callFrame->lexicalGlobalObject()));
- vPC += OPCODE_LENGTH(op_neq_null);
- NEXT_INSTRUCTION();
- }
- DEFINE_OPCODE(op_stricteq) {
- /* stricteq dst(r) src1(r) src2(r)
-
- Checks whether register src1 and register src2 are strictly
- equal, as with the ECMAScript '===' operator, and puts the
- result as a boolean in register dst.
- */
- int dst = vPC[1].u.operand;
- JSValue src1 = callFrame->r(vPC[2].u.operand).jsValue();
- JSValue src2 = callFrame->r(vPC[3].u.operand).jsValue();
- bool result = JSValue::strictEqual(callFrame, src1, src2);
- CHECK_FOR_EXCEPTION();
- callFrame->uncheckedR(dst) = jsBoolean(result);
-
- vPC += OPCODE_LENGTH(op_stricteq);
- NEXT_INSTRUCTION();
- }
- DEFINE_OPCODE(op_nstricteq) {
- /* nstricteq dst(r) src1(r) src2(r)
-
- Checks whether register src1 and register src2 are not
- strictly equal, as with the ECMAScript '!==' operator, and
- puts the result as a boolean in register dst.
- */
- int dst = vPC[1].u.operand;
- JSValue src1 = callFrame->r(vPC[2].u.operand).jsValue();
- JSValue src2 = callFrame->r(vPC[3].u.operand).jsValue();
- bool result = !JSValue::strictEqual(callFrame, src1, src2);
- CHECK_FOR_EXCEPTION();
- callFrame->uncheckedR(dst) = jsBoolean(result);
-
- vPC += OPCODE_LENGTH(op_nstricteq);
- NEXT_INSTRUCTION();
- }
- DEFINE_OPCODE(op_less) {
- /* less dst(r) src1(r) src2(r)
-
- Checks whether register src1 is less than register src2, as
- with the ECMAScript '<' operator, and puts the result as
- a boolean in register dst.
- */
- int dst = vPC[1].u.operand;
- JSValue src1 = callFrame->r(vPC[2].u.operand).jsValue();
- JSValue src2 = callFrame->r(vPC[3].u.operand).jsValue();
- JSValue result = jsBoolean(jsLess<true>(callFrame, src1, src2));
- CHECK_FOR_EXCEPTION();
- callFrame->uncheckedR(dst) = result;
-
- vPC += OPCODE_LENGTH(op_less);
- NEXT_INSTRUCTION();
- }
- DEFINE_OPCODE(op_lesseq) {
- /* lesseq dst(r) src1(r) src2(r)
-
- Checks whether register src1 is less than or equal to
- register src2, as with the ECMAScript '<=' operator, and
- puts the result as a boolean in register dst.
- */
- int dst = vPC[1].u.operand;
- JSValue src1 = callFrame->r(vPC[2].u.operand).jsValue();
- JSValue src2 = callFrame->r(vPC[3].u.operand).jsValue();
- JSValue result = jsBoolean(jsLessEq<true>(callFrame, src1, src2));
- CHECK_FOR_EXCEPTION();
- callFrame->uncheckedR(dst) = result;
-
- vPC += OPCODE_LENGTH(op_lesseq);
- NEXT_INSTRUCTION();
- }
- DEFINE_OPCODE(op_greater) {
- /* greater dst(r) src1(r) src2(r)
-
- Checks whether register src1 is greater than register src2, as
- with the ECMAScript '>' operator, and puts the result as
- a boolean in register dst.
- */
- int dst = vPC[1].u.operand;
- JSValue src1 = callFrame->r(vPC[2].u.operand).jsValue();
- JSValue src2 = callFrame->r(vPC[3].u.operand).jsValue();
- JSValue result = jsBoolean(jsLess<false>(callFrame, src2, src1));
- CHECK_FOR_EXCEPTION();
- callFrame->uncheckedR(dst) = result;
-
- vPC += OPCODE_LENGTH(op_greater);
- NEXT_INSTRUCTION();
- }
- DEFINE_OPCODE(op_greatereq) {
- /* greatereq dst(r) src1(r) src2(r)
-
- Checks whether register src1 is greater than or equal to
- register src2, as with the ECMAScript '>=' operator, and
- puts the result as a boolean in register dst.
- */
- int dst = vPC[1].u.operand;
- JSValue src1 = callFrame->r(vPC[2].u.operand).jsValue();
- JSValue src2 = callFrame->r(vPC[3].u.operand).jsValue();
- JSValue result = jsBoolean(jsLessEq<false>(callFrame, src2, src1));
- CHECK_FOR_EXCEPTION();
- callFrame->uncheckedR(dst) = result;
-
- vPC += OPCODE_LENGTH(op_greatereq);
- NEXT_INSTRUCTION();
- }
- DEFINE_OPCODE(op_pre_inc) {
- /* pre_inc srcDst(r)
-
- Converts register srcDst to number, adds one, and puts the result
- back in register srcDst.
- */
- int srcDst = vPC[1].u.operand;
- JSValue v = callFrame->r(srcDst).jsValue();
- if (v.isInt32() && v.asInt32() < INT_MAX)
- callFrame->uncheckedR(srcDst) = jsNumber(v.asInt32() + 1);
- else {
- JSValue result = jsNumber(v.toNumber(callFrame) + 1);
- CHECK_FOR_EXCEPTION();
- callFrame->uncheckedR(srcDst) = result;
- }
-
- vPC += OPCODE_LENGTH(op_pre_inc);
- NEXT_INSTRUCTION();
- }
- DEFINE_OPCODE(op_pre_dec) {
- /* pre_dec srcDst(r)
-
- Converts register srcDst to number, subtracts one, and puts the result
- back in register srcDst.
- */
- int srcDst = vPC[1].u.operand;
- JSValue v = callFrame->r(srcDst).jsValue();
- if (v.isInt32() && v.asInt32() > INT_MIN)
- callFrame->uncheckedR(srcDst) = jsNumber(v.asInt32() - 1);
- else {
- JSValue result = jsNumber(v.toNumber(callFrame) - 1);
- CHECK_FOR_EXCEPTION();
- callFrame->uncheckedR(srcDst) = result;
- }
-
- vPC += OPCODE_LENGTH(op_pre_dec);
- NEXT_INSTRUCTION();
- }
- DEFINE_OPCODE(op_post_inc) {
- /* post_inc dst(r) srcDst(r)
-
- Converts register srcDst to number. The number itself is
- written to register dst, and the number plus one is written
- back to register srcDst.
- */
- int dst = vPC[1].u.operand;
- int srcDst = vPC[2].u.operand;
- JSValue v = callFrame->r(srcDst).jsValue();
- if (v.isInt32() && v.asInt32() < INT_MAX) {
- callFrame->uncheckedR(srcDst) = jsNumber(v.asInt32() + 1);
- callFrame->uncheckedR(dst) = v;
- } else {
- double number = callFrame->r(srcDst).jsValue().toNumber(callFrame);
- CHECK_FOR_EXCEPTION();
- callFrame->uncheckedR(srcDst) = jsNumber(number + 1);
- callFrame->uncheckedR(dst) = jsNumber(number);
- }
-
- vPC += OPCODE_LENGTH(op_post_inc);
- NEXT_INSTRUCTION();
- }
- DEFINE_OPCODE(op_post_dec) {
- /* post_dec dst(r) srcDst(r)
-
- Converts register srcDst to number. The number itself is
- written to register dst, and the number minus one is written
- back to register srcDst.
- */
- int dst = vPC[1].u.operand;
- int srcDst = vPC[2].u.operand;
- JSValue v = callFrame->r(srcDst).jsValue();
- if (v.isInt32() && v.asInt32() > INT_MIN) {
- callFrame->uncheckedR(srcDst) = jsNumber(v.asInt32() - 1);
- callFrame->uncheckedR(dst) = v;
- } else {
- double number = callFrame->r(srcDst).jsValue().toNumber(callFrame);
- CHECK_FOR_EXCEPTION();
- callFrame->uncheckedR(srcDst) = jsNumber(number - 1);
- callFrame->uncheckedR(dst) = jsNumber(number);
- }
-
- vPC += OPCODE_LENGTH(op_post_dec);
- NEXT_INSTRUCTION();
- }
- DEFINE_OPCODE(op_to_jsnumber) {
- /* to_jsnumber dst(r) src(r)
-
- Converts register src to number, and puts the result
- in register dst.
- */
- int dst = vPC[1].u.operand;
- int src = vPC[2].u.operand;
-
- JSValue srcVal = callFrame->r(src).jsValue();
-
- if (LIKELY(srcVal.isNumber()))
- callFrame->uncheckedR(dst) = callFrame->r(src);
- else {
- double number = srcVal.toNumber(callFrame);
- CHECK_FOR_EXCEPTION();
- callFrame->uncheckedR(dst) = jsNumber(number);
- }
-
- vPC += OPCODE_LENGTH(op_to_jsnumber);
- NEXT_INSTRUCTION();
- }
- DEFINE_OPCODE(op_negate) {
- /* negate dst(r) src(r)
-
- Converts register src to number, negates it, and puts the
- result in register dst.
- */
- int dst = vPC[1].u.operand;
- JSValue src = callFrame->r(vPC[2].u.operand).jsValue();
- if (src.isInt32() && (src.asInt32() & 0x7fffffff)) // non-zero and no overflow
- callFrame->uncheckedR(dst) = jsNumber(-src.asInt32());
- else {
- JSValue result = jsNumber(-src.toNumber(callFrame));
- CHECK_FOR_EXCEPTION();
- callFrame->uncheckedR(dst) = result;
- }
-
- vPC += OPCODE_LENGTH(op_negate);
- NEXT_INSTRUCTION();
- }
- DEFINE_OPCODE(op_add) {
- /* add dst(r) src1(r) src2(r)
-
- Adds register src1 and register src2, and puts the result
- in register dst. (JS add may be string concatenation or
- numeric add, depending on the types of the operands.)
- */
- int dst = vPC[1].u.operand;
- JSValue src1 = callFrame->r(vPC[2].u.operand).jsValue();
- JSValue src2 = callFrame->r(vPC[3].u.operand).jsValue();
- if (src1.isInt32() && src2.isInt32() && !((src1.asInt32() | src2.asInt32()) & 0xc0000000)) // no overflow
- callFrame->uncheckedR(dst) = jsNumber(src1.asInt32() + src2.asInt32());
- else {
- JSValue result = jsAdd(callFrame, src1, src2);
- CHECK_FOR_EXCEPTION();
- callFrame->uncheckedR(dst) = result;
- }
- vPC += OPCODE_LENGTH(op_add);
- NEXT_INSTRUCTION();
- }
- DEFINE_OPCODE(op_mul) {
- /* mul dst(r) src1(r) src2(r)
-
- Multiplies register src1 and register src2 (converted to
- numbers), and puts the product in register dst.
- */
- int dst = vPC[1].u.operand;
- JSValue src1 = callFrame->r(vPC[2].u.operand).jsValue();
- JSValue src2 = callFrame->r(vPC[3].u.operand).jsValue();
- if (src1.isInt32() && src2.isInt32() && !(src1.asInt32() | src2.asInt32()) >> 15) // no overflow
- callFrame->uncheckedR(dst) = jsNumber(src1.asInt32() * src2.asInt32());
- else {
- JSValue result = jsNumber(src1.toNumber(callFrame) * src2.toNumber(callFrame));
- CHECK_FOR_EXCEPTION();
- callFrame->uncheckedR(dst) = result;
- }
-
- vPC += OPCODE_LENGTH(op_mul);
- NEXT_INSTRUCTION();
- }
- DEFINE_OPCODE(op_div) {
- /* div dst(r) dividend(r) divisor(r)
-
- Divides register dividend (converted to number) by the
- register divisor (converted to number), and puts the
- quotient in register dst.
- */
- int dst = vPC[1].u.operand;
- JSValue dividend = callFrame->r(vPC[2].u.operand).jsValue();
- JSValue divisor = callFrame->r(vPC[3].u.operand).jsValue();
-
- JSValue result = jsNumber(dividend.toNumber(callFrame) / divisor.toNumber(callFrame));
- CHECK_FOR_EXCEPTION();
- callFrame->uncheckedR(dst) = result;
-
- vPC += OPCODE_LENGTH(op_div);
- NEXT_INSTRUCTION();
- }
- DEFINE_OPCODE(op_mod) {
- /* mod dst(r) dividend(r) divisor(r)
-
- Divides register dividend (converted to number) by
- register divisor (converted to number), and puts the
- remainder in register dst.
- */
- int dst = vPC[1].u.operand;
- JSValue dividend = callFrame->r(vPC[2].u.operand).jsValue();
- JSValue divisor = callFrame->r(vPC[3].u.operand).jsValue();
-
- if (dividend.isInt32() && divisor.isInt32() && divisor.asInt32() != 0 && divisor.asInt32() != -1) {
- JSValue result = jsNumber(dividend.asInt32() % divisor.asInt32());
- ASSERT(result);
- callFrame->uncheckedR(dst) = result;
- vPC += OPCODE_LENGTH(op_mod);
- NEXT_INSTRUCTION();
- }
-
- // Conversion to double must happen outside the call to fmod since the
- // order of argument evaluation is not guaranteed.
- double d1 = dividend.toNumber(callFrame);
- double d2 = divisor.toNumber(callFrame);
- JSValue result = jsNumber(fmod(d1, d2));
- CHECK_FOR_EXCEPTION();
- callFrame->uncheckedR(dst) = result;
- vPC += OPCODE_LENGTH(op_mod);
- NEXT_INSTRUCTION();
- }
- DEFINE_OPCODE(op_sub) {
- /* sub dst(r) src1(r) src2(r)
-
- Subtracts register src2 (converted to number) from register
- src1 (converted to number), and puts the difference in
- register dst.
- */
- int dst = vPC[1].u.operand;
- JSValue src1 = callFrame->r(vPC[2].u.operand).jsValue();
- JSValue src2 = callFrame->r(vPC[3].u.operand).jsValue();
- if (src1.isInt32() && src2.isInt32() && !((src1.asInt32() | src2.asInt32()) & 0xc0000000)) // no overflow
- callFrame->uncheckedR(dst) = jsNumber(src1.asInt32() - src2.asInt32());
- else {
- JSValue result = jsNumber(src1.toNumber(callFrame) - src2.toNumber(callFrame));
- CHECK_FOR_EXCEPTION();
- callFrame->uncheckedR(dst) = result;
- }
- vPC += OPCODE_LENGTH(op_sub);
- NEXT_INSTRUCTION();
- }
- DEFINE_OPCODE(op_lshift) {
- /* lshift dst(r) val(r) shift(r)
-
- Performs left shift of register val (converted to int32) by
- register shift (converted to uint32), and puts the result
- in register dst.
- */
- int dst = vPC[1].u.operand;
- JSValue val = callFrame->r(vPC[2].u.operand).jsValue();
- JSValue shift = callFrame->r(vPC[3].u.operand).jsValue();
-
- if (val.isInt32() && shift.isInt32())
- callFrame->uncheckedR(dst) = jsNumber(val.asInt32() << (shift.asInt32() & 0x1f));
- else {
- JSValue result = jsNumber((val.toInt32(callFrame)) << (shift.toUInt32(callFrame) & 0x1f));
- CHECK_FOR_EXCEPTION();
- callFrame->uncheckedR(dst) = result;
- }
-
- vPC += OPCODE_LENGTH(op_lshift);
- NEXT_INSTRUCTION();
- }
- DEFINE_OPCODE(op_rshift) {
- /* rshift dst(r) val(r) shift(r)
-
- Performs arithmetic right shift of register val (converted
- to int32) by register shift (converted to
- uint32), and puts the result in register dst.
- */
- int dst = vPC[1].u.operand;
- JSValue val = callFrame->r(vPC[2].u.operand).jsValue();
- JSValue shift = callFrame->r(vPC[3].u.operand).jsValue();
-
- if (val.isInt32() && shift.isInt32())
- callFrame->uncheckedR(dst) = jsNumber(val.asInt32() >> (shift.asInt32() & 0x1f));
- else {
- JSValue result = jsNumber((val.toInt32(callFrame)) >> (shift.toUInt32(callFrame) & 0x1f));
- CHECK_FOR_EXCEPTION();
- callFrame->uncheckedR(dst) = result;
- }
-
- vPC += OPCODE_LENGTH(op_rshift);
- NEXT_INSTRUCTION();
- }
- DEFINE_OPCODE(op_urshift) {
- /* rshift dst(r) val(r) shift(r)
-
- Performs logical right shift of register val (converted
- to uint32) by register shift (converted to
- uint32), and puts the result in register dst.
- */
- int dst = vPC[1].u.operand;
- JSValue val = callFrame->r(vPC[2].u.operand).jsValue();
- JSValue shift = callFrame->r(vPC[3].u.operand).jsValue();
- if (val.isUInt32() && shift.isInt32())
- callFrame->uncheckedR(dst) = jsNumber(val.asInt32() >> (shift.asInt32() & 0x1f));
- else {
- JSValue result = jsNumber((val.toUInt32(callFrame)) >> (shift.toUInt32(callFrame) & 0x1f));
- CHECK_FOR_EXCEPTION();
- callFrame->uncheckedR(dst) = result;
- }
-
- vPC += OPCODE_LENGTH(op_urshift);
- NEXT_INSTRUCTION();
- }
- DEFINE_OPCODE(op_bitand) {
- /* bitand dst(r) src1(r) src2(r)
-
- Computes bitwise AND of register src1 (converted to int32)
- and register src2 (converted to int32), and puts the result
- in register dst.
- */
- int dst = vPC[1].u.operand;
- JSValue src1 = callFrame->r(vPC[2].u.operand).jsValue();
- JSValue src2 = callFrame->r(vPC[3].u.operand).jsValue();
- if (src1.isInt32() && src2.isInt32())
- callFrame->uncheckedR(dst) = jsNumber(src1.asInt32() & src2.asInt32());
- else {
- JSValue result = jsNumber(src1.toInt32(callFrame) & src2.toInt32(callFrame));
- CHECK_FOR_EXCEPTION();
- callFrame->uncheckedR(dst) = result;
- }
-
- vPC += OPCODE_LENGTH(op_bitand);
- NEXT_INSTRUCTION();
- }
- DEFINE_OPCODE(op_bitxor) {
- /* bitxor dst(r) src1(r) src2(r)
-
- Computes bitwise XOR of register src1 (converted to int32)
- and register src2 (converted to int32), and puts the result
- in register dst.
- */
- int dst = vPC[1].u.operand;
- JSValue src1 = callFrame->r(vPC[2].u.operand).jsValue();
- JSValue src2 = callFrame->r(vPC[3].u.operand).jsValue();
- if (src1.isInt32() && src2.isInt32())
- callFrame->uncheckedR(dst) = jsNumber(src1.asInt32() ^ src2.asInt32());
- else {
- JSValue result = jsNumber(src1.toInt32(callFrame) ^ src2.toInt32(callFrame));
- CHECK_FOR_EXCEPTION();
- callFrame->uncheckedR(dst) = result;
- }
-
- vPC += OPCODE_LENGTH(op_bitxor);
- NEXT_INSTRUCTION();
- }
- DEFINE_OPCODE(op_bitor) {
- /* bitor dst(r) src1(r) src2(r)
-
- Computes bitwise OR of register src1 (converted to int32)
- and register src2 (converted to int32), and puts the
- result in register dst.
- */
- int dst = vPC[1].u.operand;
- JSValue src1 = callFrame->r(vPC[2].u.operand).jsValue();
- JSValue src2 = callFrame->r(vPC[3].u.operand).jsValue();
- if (src1.isInt32() && src2.isInt32())
- callFrame->uncheckedR(dst) = jsNumber(src1.asInt32() | src2.asInt32());
- else {
- JSValue result = jsNumber(src1.toInt32(callFrame) | src2.toInt32(callFrame));
- CHECK_FOR_EXCEPTION();
- callFrame->uncheckedR(dst) = result;
- }
-
- vPC += OPCODE_LENGTH(op_bitor);
- NEXT_INSTRUCTION();
- }
- DEFINE_OPCODE(op_not) {
- /* not dst(r) src(r)
-
- Computes logical NOT of register src (converted to
- boolean), and puts the result in register dst.
- */
- int dst = vPC[1].u.operand;
- int src = vPC[2].u.operand;
- JSValue result = jsBoolean(!callFrame->r(src).jsValue().toBoolean(callFrame));
- CHECK_FOR_EXCEPTION();
- callFrame->uncheckedR(dst) = result;
-
- vPC += OPCODE_LENGTH(op_not);
- NEXT_INSTRUCTION();
- }
- DEFINE_OPCODE(op_check_has_instance) {
- /* check_has_instance constructor(r)
-
- Check 'constructor' is an object with the internal property
- [HasInstance] (i.e. is a function ... *shakes head sadly at
- JSC API*). Raises an exception if register constructor is not
- an valid parameter for instanceof.
- */
- int dst = vPC[1].u.operand;
- int value = vPC[2].u.operand;
- int base = vPC[3].u.operand;
- int target = vPC[4].u.operand;
-
- JSValue baseVal = callFrame->r(base).jsValue();
-
- if (baseVal.isObject()) {
- TypeInfo info = asObject(baseVal)->structure()->typeInfo();
- if (info.implementsDefaultHasInstance()) {
- vPC += OPCODE_LENGTH(op_check_has_instance);
- NEXT_INSTRUCTION();
- }
- if (info.implementsHasInstance()) {
- JSValue baseVal = callFrame->r(base).jsValue();
- bool result = asObject(baseVal)->methodTable()->customHasInstance(asObject(baseVal), callFrame, callFrame->r(value).jsValue());
- CHECK_FOR_EXCEPTION();
- callFrame->uncheckedR(dst) = jsBoolean(result);
-
- vPC += target;
- NEXT_INSTRUCTION();
- }
- }
-
- exceptionValue = createInvalidParamError(callFrame, "instanceof" , baseVal);
- goto vm_throw;
- }
- DEFINE_OPCODE(op_instanceof) {
- /* instanceof dst(r) value(r) constructor(r) constructorProto(r)
-
- Tests whether register value is an instance of register
- constructor, and puts the boolean result in register
- dst. Register constructorProto must contain the "prototype"
- property (not the actual prototype) of the object in
- register constructor. This lookup is separated so that
- polymorphic inline caching can apply.
-
- Raises an exception if register constructor is not an
- object.
- */
- int dst = vPC[1].u.operand;
- int value = vPC[2].u.operand;
- int baseProto = vPC[3].u.operand;
-
- bool result = JSObject::defaultHasInstance(callFrame, callFrame->r(value).jsValue(), callFrame->r(baseProto).jsValue());
- CHECK_FOR_EXCEPTION();
- callFrame->uncheckedR(dst) = jsBoolean(result);
-
- vPC += OPCODE_LENGTH(op_instanceof);
- NEXT_INSTRUCTION();
- }
- DEFINE_OPCODE(op_typeof) {
- /* typeof dst(r) src(r)
-
- Determines the type string for src according to ECMAScript
- rules, and puts the result in register dst.
- */
- int dst = vPC[1].u.operand;
- int src = vPC[2].u.operand;
- callFrame->uncheckedR(dst) = JSValue(jsTypeStringForValue(callFrame, callFrame->r(src).jsValue()));
-
- vPC += OPCODE_LENGTH(op_typeof);
- NEXT_INSTRUCTION();
- }
- DEFINE_OPCODE(op_is_undefined) {
- /* is_undefined dst(r) src(r)
-
- Determines whether the type string for src according to
- the ECMAScript rules is "undefined", and puts the result
- in register dst.
- */
- int dst = vPC[1].u.operand;
- int src = vPC[2].u.operand;
- JSValue v = callFrame->r(src).jsValue();
- callFrame->uncheckedR(dst) = jsBoolean(v.isCell() ? v.asCell()->structure()->masqueradesAsUndefined(callFrame->lexicalGlobalObject()) : v.isUndefined());
-
- vPC += OPCODE_LENGTH(op_is_undefined);
- NEXT_INSTRUCTION();
- }
- DEFINE_OPCODE(op_is_boolean) {
- /* is_boolean dst(r) src(r)
-
- Determines whether the type string for src according to
- the ECMAScript rules is "boolean", and puts the result
- in register dst.
- */
- int dst = vPC[1].u.operand;
- int src = vPC[2].u.operand;
- callFrame->uncheckedR(dst) = jsBoolean(callFrame->r(src).jsValue().isBoolean());
-
- vPC += OPCODE_LENGTH(op_is_boolean);
- NEXT_INSTRUCTION();
- }
- DEFINE_OPCODE(op_is_number) {
- /* is_number dst(r) src(r)
-
- Determines whether the type string for src according to
- the ECMAScript rules is "number", and puts the result
- in register dst.
- */
- int dst = vPC[1].u.operand;
- int src = vPC[2].u.operand;
- callFrame->uncheckedR(dst) = jsBoolean(callFrame->r(src).jsValue().isNumber());
-
- vPC += OPCODE_LENGTH(op_is_number);
- NEXT_INSTRUCTION();
- }
- DEFINE_OPCODE(op_is_string) {
- /* is_string dst(r) src(r)
-
- Determines whether the type string for src according to
- the ECMAScript rules is "string", and puts the result
- in register dst.
- */
- int dst = vPC[1].u.operand;
- int src = vPC[2].u.operand;
- callFrame->uncheckedR(dst) = jsBoolean(callFrame->r(src).jsValue().isString());
-
- vPC += OPCODE_LENGTH(op_is_string);
- NEXT_INSTRUCTION();
- }
- DEFINE_OPCODE(op_is_object) {
- /* is_object dst(r) src(r)
-
- Determines whether the type string for src according to
- the ECMAScript rules is "object", and puts the result
- in register dst.
- */
- int dst = vPC[1].u.operand;
- int src = vPC[2].u.operand;
- callFrame->uncheckedR(dst) = jsBoolean(jsIsObjectType(callFrame, callFrame->r(src).jsValue()));
-
- vPC += OPCODE_LENGTH(op_is_object);
- NEXT_INSTRUCTION();
- }
- DEFINE_OPCODE(op_is_function) {
- /* is_function dst(r) src(r)
-
- Determines whether the type string for src according to
- the ECMAScript rules is "function", and puts the result
- in register dst.
- */
- int dst = vPC[1].u.operand;
- int src = vPC[2].u.operand;
- callFrame->uncheckedR(dst) = jsBoolean(jsIsFunctionType(callFrame->r(src).jsValue()));
-
- vPC += OPCODE_LENGTH(op_is_function);
- NEXT_INSTRUCTION();
- }
- DEFINE_OPCODE(op_in) {
- /* in dst(r) property(r) base(r)
-
- Tests whether register base has a property named register
- property, and puts the boolean result in register dst.
-
- Raises an exception if register constructor is not an
- object.
- */
- int dst = vPC[1].u.operand;
- int property = vPC[2].u.operand;
- int base = vPC[3].u.operand;
-
- JSValue baseVal = callFrame->r(base).jsValue();
- if (isInvalidParamForIn(callFrame, baseVal, exceptionValue))
- goto vm_throw;
-
- JSObject* baseObj = asObject(baseVal);
-
- JSValue propName = callFrame->r(property).jsValue();
-
- uint32_t i;
- if (propName.getUInt32(i))
- callFrame->uncheckedR(dst) = jsBoolean(baseObj->hasProperty(callFrame, i));
- else if (isName(propName))
- callFrame->uncheckedR(dst) = jsBoolean(baseObj->hasProperty(callFrame, jsCast<NameInstance*>(propName.asCell())->privateName()));
- else {
- Identifier property(callFrame, propName.toString(callFrame)->value(callFrame));
- CHECK_FOR_EXCEPTION();
- callFrame->uncheckedR(dst) = jsBoolean(baseObj->hasProperty(callFrame, property));
- }
-
- vPC += OPCODE_LENGTH(op_in);
- NEXT_INSTRUCTION();
- }
- DEFINE_OPCODE(op_resolve) {
- /* resolve dst(r) property(id)
-
- Looks up the property named by identifier property in the
- scope chain, and writes the resulting value to register
- dst. If the property is not found, raises an exception.
- */
- int dst = vPC[1].u.operand;
- int property = vPC[2].u.operand;
- Identifier& ident = callFrame->codeBlock()->identifier(property);
-
- JSValue result = JSScope::resolve(callFrame, ident);
- CHECK_FOR_EXCEPTION();
- callFrame->uncheckedR(dst) = result;
-
- vPC += OPCODE_LENGTH(op_resolve);
- NEXT_INSTRUCTION();
- }
- DEFINE_OPCODE(op_resolve_skip) {
- /* resolve_skip dst(r) property(id) skip(n)
-
- Looks up the property named by identifier property in the
- scope chain skipping the top 'skip' levels, and writes the resulting
- value to register dst. If the property is not found, raises an exception.
- */
- int dst = vPC[1].u.operand;
- int property = vPC[2].u.operand;
- int skip = vPC[3].u.operand;
- Identifier& ident = callFrame->codeBlock()->identifier(property);
-
- JSValue result = JSScope::resolveSkip(callFrame, ident, skip);
- CHECK_FOR_EXCEPTION();
- callFrame->uncheckedR(dst) = result;
-
- vPC += OPCODE_LENGTH(op_resolve_skip);
- NEXT_INSTRUCTION();
- }
- DEFINE_OPCODE(op_resolve_global) {
- /* resolve_skip dst(r) globalObject(c) property(id) structure(sID) offset(n)
-
- Performs a dynamic property lookup for the given property, on the provided
- global object. If structure matches the Structure of the global then perform
- a fast lookup using the case offset, otherwise fall back to a full resolve and
- cache the new structure and offset
- */
- int dst = vPC[1].u.operand;
- int property = vPC[2].u.operand;
- Identifier& ident = callFrame->codeBlock()->identifier(property);
-
- JSValue result = JSScope::resolveGlobal(
- callFrame,
- ident,
- callFrame->lexicalGlobalObject(),
- &vPC[3].u.structure,
- &vPC[4].u.operand
- );
- CHECK_FOR_EXCEPTION();
- callFrame->uncheckedR(dst) = result;
-
- vPC += OPCODE_LENGTH(op_resolve_global);
- NEXT_INSTRUCTION();
- }
- DEFINE_OPCODE(op_resolve_global_dynamic) {
- /* resolve_skip dst(r) globalObject(c) property(id) structure(sID) offset(n), depth(n)
-
- Performs a dynamic property lookup for the given property, on the provided
- global object. If structure matches the Structure of the global then perform
- a fast lookup using the case offset, otherwise fall back to a full resolve and
- cache the new structure and offset.
-
- This walks through n levels of the scope chain to verify that none of those levels
- in the scope chain include dynamically added properties.
- */
- int dst = vPC[1].u.operand;
- int property = vPC[2].u.operand;
- int skip = vPC[5].u.operand;
- Identifier& ident = callFrame->codeBlock()->identifier(property);
-
- JSValue result = JSScope::resolveGlobalDynamic(callFrame, ident, skip, &vPC[3].u.structure, &vPC[4].u.operand);
- CHECK_FOR_EXCEPTION();
- callFrame->uncheckedR(dst) = result;
-
- vPC += OPCODE_LENGTH(op_resolve_global_dynamic);
- NEXT_INSTRUCTION();
- }
- DEFINE_OPCODE(op_get_global_var) {
- /* get_global_var dst(r) globalObject(c) registerPointer(n)
-
- Gets the global var at global slot index and places it in register dst.
- */
- int dst = vPC[1].u.operand;
- WriteBarrier<Unknown>* registerPointer = vPC[2].u.registerPointer;
-
- callFrame->uncheckedR(dst) = registerPointer->get();
- vPC += OPCODE_LENGTH(op_get_global_var);
- NEXT_INSTRUCTION();
- }
- DEFINE_OPCODE(op_get_global_var_watchable) {
- /* get_global_var_watchable dst(r) globalObject(c) registerPointer(n)
-
- Gets the global var at global slot index and places it in register dst.
- */
- int dst = vPC[1].u.operand;
- WriteBarrier<Unknown>* registerPointer = vPC[2].u.registerPointer;
-
- callFrame->uncheckedR(dst) = registerPointer->get();
- vPC += OPCODE_LENGTH(op_get_global_var_watchable);
- NEXT_INSTRUCTION();
- }
- DEFINE_OPCODE(op_init_global_const)
- DEFINE_OPCODE(op_put_global_var) {
- /* put_global_var globalObject(c) registerPointer(n) value(r)
-
- Puts value into global slot index.
- */
- JSGlobalObject* scope = codeBlock->globalObject();
- ASSERT(scope->isGlobalObject());
- WriteBarrier<Unknown>* registerPointer = vPC[1].u.registerPointer;
- int value = vPC[2].u.operand;
-
- registerPointer->set(*globalData, scope, callFrame->r(value).jsValue());
- vPC += OPCODE_LENGTH(op_put_global_var);
- NEXT_INSTRUCTION();
- }
- DEFINE_OPCODE(op_init_global_const_check)
- DEFINE_OPCODE(op_put_global_var_check) {
- /* put_global_var_check globalObject(c) registerPointer(n) value(r)
-
- Puts value into global slot index. In JIT configurations this will
- perform a watchpoint check. If we're running with the old interpreter,
- this is not necessary; the interpreter never uses these watchpoints.
- */
- JSGlobalObject* scope = codeBlock->globalObject();
- ASSERT(scope->isGlobalObject());
- WriteBarrier<Unknown>* registerPointer = vPC[1].u.registerPointer;
- int value = vPC[2].u.operand;
-
- registerPointer->set(*globalData, scope, callFrame->r(value).jsValue());
- vPC += OPCODE_LENGTH(op_put_global_var_check);
- NEXT_INSTRUCTION();
- }
- DEFINE_OPCODE(op_get_scoped_var) {
- /* get_scoped_var dst(r) index(n) skip(n)
-
- Loads the contents of the index-th local from the scope skip nodes from
- the top of the scope chain, and places it in register dst.
- */
- int dst = vPC[1].u.operand;
- int index = vPC[2].u.operand;
- int skip = vPC[3].u.operand;
-
- JSScope* scope = callFrame->scope();
- ScopeChainIterator iter = scope->begin();
- ScopeChainIterator end = scope->end();
- ASSERT_UNUSED(end, iter != end);
- ASSERT(codeBlock == callFrame->codeBlock());
- bool checkTopLevel = codeBlock->codeType() == FunctionCode && codeBlock->needsFullScopeChain();
- ASSERT(skip || !checkTopLevel);
- if (checkTopLevel && skip--) {
- if (callFrame->r(codeBlock->activationRegister()).jsValue())
- ++iter;
- }
- while (skip--) {
- ++iter;
- ASSERT_UNUSED(end, iter != end);
- }
- ASSERT(iter->isVariableObject());
- JSVariableObject* variableObject = jsCast<JSVariableObject*>(iter.get());
- callFrame->uncheckedR(dst) = variableObject->registerAt(index).get();
- ASSERT(callFrame->r(dst).jsValue());
- vPC += OPCODE_LENGTH(op_get_scoped_var);
- NEXT_INSTRUCTION();
- }
- DEFINE_OPCODE(op_put_scoped_var) {
- /* put_scoped_var index(n) skip(n) value(r)
-
- */
- int index = vPC[1].u.operand;
- int skip = vPC[2].u.operand;
- int value = vPC[3].u.operand;
-
- JSScope* scope = callFrame->scope();
- ScopeChainIterator iter = scope->begin();
- ScopeChainIterator end = scope->end();
- ASSERT(codeBlock == callFrame->codeBlock());
- ASSERT_UNUSED(end, iter != end);
- bool checkTopLevel = codeBlock->codeType() == FunctionCode && codeBlock->needsFullScopeChain();
- ASSERT(skip || !checkTopLevel);
- if (checkTopLevel && skip--) {
- if (callFrame->r(codeBlock->activationRegister()).jsValue())
- ++iter;
- }
- while (skip--) {
- ++iter;
- ASSERT_UNUSED(end, iter != end);
- }
-
- ASSERT(iter->isVariableObject());
- JSVariableObject* variableObject = jsCast<JSVariableObject*>(iter.get());
- ASSERT(callFrame->r(value).jsValue());
- variableObject->registerAt(index).set(*globalData, variableObject, callFrame->r(value).jsValue());
- vPC += OPCODE_LENGTH(op_put_scoped_var);
- NEXT_INSTRUCTION();
- }
- DEFINE_OPCODE(op_resolve_base) {
- /* resolve_base dst(r) property(id) isStrict(bool)
-
- Searches the scope chain for an object containing
- identifier property, and if one is found, writes it to
- register dst. If none is found and isStrict is false, the
- outermost scope (which will be the global object) is
- stored in register dst.
- */
- int dst = vPC[1].u.operand;
- int property = vPC[2].u.operand;
- bool isStrict = vPC[3].u.operand;
- Identifier& ident = callFrame->codeBlock()->identifier(property);
-
- JSValue result = JSScope::resolveBase(callFrame, ident, isStrict);
- CHECK_FOR_EXCEPTION();
- callFrame->uncheckedR(dst) = result;
-
- vPC += OPCODE_LENGTH(op_resolve_base);
- NEXT_INSTRUCTION();
- }
- DEFINE_OPCODE(op_ensure_property_exists) {
- /* ensure_property_exists base(r) property(id)
-
- Throws an exception if property does not exist on base
- */
- int base = vPC[1].u.operand;
- int property = vPC[2].u.operand;
- Identifier& ident = codeBlock->identifier(property);
-
- JSValue baseVal = callFrame->r(base).jsValue();
- JSObject* baseObject = asObject(baseVal);
- PropertySlot slot(baseVal);
- if (!baseObject->getPropertySlot(callFrame, ident, slot)) {
- exceptionValue = createErrorForInvalidGlobalAssignment(callFrame, ident.string());
- goto vm_throw;
- }
-
- vPC += OPCODE_LENGTH(op_ensure_property_exists);
- NEXT_INSTRUCTION();
- }
- DEFINE_OPCODE(op_resolve_with_base) {
- /* resolve_with_base baseDst(r) propDst(r) property(id)
-
- Searches the scope chain for an object containing
- identifier property, and if one is found, writes it to
- register srcDst, and the retrieved property value to register
- propDst. If the property is not found, raises an exception.
-
- This is more efficient than doing resolve_base followed by
- resolve, or resolve_base followed by get_by_id, as it
- avoids duplicate hash lookups.
- */
- int baseDst = vPC[1].u.operand;
- int propDst = vPC[2].u.operand;
- int property = vPC[3].u.operand;
- Identifier& ident = codeBlock->identifier(property);
-
- JSValue prop = JSScope::resolveWithBase(callFrame, ident, &callFrame->uncheckedR(baseDst));
- CHECK_FOR_EXCEPTION();
- callFrame->uncheckedR(propDst) = prop;
-
- vPC += OPCODE_LENGTH(op_resolve_with_base);
- NEXT_INSTRUCTION();
- }
- DEFINE_OPCODE(op_resolve_with_this) {
- /* resolve_with_this thisDst(r) propDst(r) property(id)
-
- Searches the scope chain for an object containing
- identifier property, and if one is found, writes the
- retrieved property value to register propDst, and the
- this object to pass in a call to thisDst.
-
- If the property is not found, raises an exception.
- */
- int thisDst = vPC[1].u.operand;
- int propDst = vPC[2].u.operand;
- int property = vPC[3].u.operand;
- Identifier& ident = codeBlock->identifier(property);
-
- JSValue prop = JSScope::resolveWithThis(callFrame, ident, &callFrame->uncheckedR(thisDst));
- CHECK_FOR_EXCEPTION();
- callFrame->uncheckedR(propDst) = prop;
-
- vPC += OPCODE_LENGTH(op_resolve_with_this);
- NEXT_INSTRUCTION();
- }
- DEFINE_OPCODE(op_get_by_id_out_of_line)
- DEFINE_OPCODE(op_get_by_id) {
- /* get_by_id dst(r) base(r) property(id) structure(sID) nop(n) nop(n) nop(n)
-
- Generic property access: Gets the property named by identifier
- property from the value base, and puts the result in register dst.
- */
- int dst = vPC[1].u.operand;
- int base = vPC[2].u.operand;
- int property = vPC[3].u.operand;
-
- Identifier& ident = codeBlock->identifier(property);
- JSValue baseValue = callFrame->r(base).jsValue();
- PropertySlot slot(baseValue);
- JSValue result = baseValue.get(callFrame, ident, slot);
- CHECK_FOR_EXCEPTION();
-
- tryCacheGetByID(callFrame, codeBlock, vPC, baseValue, ident, slot);
-
- callFrame->uncheckedR(dst) = result;
- vPC += OPCODE_LENGTH(op_get_by_id);
- NEXT_INSTRUCTION();
- }
- DEFINE_OPCODE(op_get_by_id_self) {
- /* op_get_by_id_self dst(r) base(r) property(id) structure(sID) offset(n) nop(n) nop(n)
-
- Cached property access: Attempts to get a cached property from the
- value base. If the cache misses, op_get_by_id_self reverts to
- op_get_by_id.
- */
- int base = vPC[2].u.operand;
- JSValue baseValue = callFrame->r(base).jsValue();
-
- if (LIKELY(baseValue.isCell())) {
- JSCell* baseCell = baseValue.asCell();
- Structure* structure = vPC[4].u.structure.get();
-
- if (LIKELY(baseCell->structure() == structure)) {
- ASSERT(baseCell->isObject());
- JSObject* baseObject = asObject(baseCell);
- int dst = vPC[1].u.operand;
- int offset = vPC[5].u.operand;
-
- ASSERT(baseObject->get(callFrame, codeBlock->identifier(vPC[3].u.operand)) == baseObject->getDirectOffset(offset));
- callFrame->uncheckedR(dst) = JSValue(baseObject->getDirectOffset(offset));
-
- vPC += OPCODE_LENGTH(op_get_by_id_self);
- NEXT_INSTRUCTION();
- }
- }
-
- uncacheGetByID(codeBlock, vPC);
- NEXT_INSTRUCTION();
- }
- DEFINE_OPCODE(op_get_by_id_proto) {
- /* op_get_by_id_proto dst(r) base(r) property(id) structure(sID) prototypeStructure(sID) offset(n) nop(n)
-
- Cached property access: Attempts to get a cached property from the
- value base's prototype. If the cache misses, op_get_by_id_proto
- reverts to op_get_by_id.
- */
- int base = vPC[2].u.operand;
- JSValue baseValue = callFrame->r(base).jsValue();
-
- if (LIKELY(baseValue.isCell())) {
- JSCell* baseCell = baseValue.asCell();
- Structure* structure = vPC[4].u.structure.get();
-
- if (LIKELY(baseCell->structure() == structure)) {
- ASSERT(structure->prototypeForLookup(callFrame).isObject());
- JSObject* protoObject = asObject(structure->prototypeForLookup(callFrame));
- Structure* prototypeStructure = vPC[5].u.structure.get();
-
- if (LIKELY(protoObject->structure() == prototypeStructure)) {
- int dst = vPC[1].u.operand;
- int offset = vPC[6].u.operand;
-
- ASSERT(protoObject->get(callFrame, codeBlock->identifier(vPC[3].u.operand)) == protoObject->getDirectOffset(offset));
- ASSERT(baseValue.get(callFrame, codeBlock->identifier(vPC[3].u.operand)) == protoObject->getDirectOffset(offset));
- callFrame->uncheckedR(dst) = JSValue(protoObject->getDirectOffset(offset));
-
- vPC += OPCODE_LENGTH(op_get_by_id_proto);
- NEXT_INSTRUCTION();
- }
- }
- }
-
- uncacheGetByID(codeBlock, vPC);
- NEXT_INSTRUCTION();
- }
-#if USE(GCC_COMPUTED_GOTO_WORKAROUND)
- goto *(&&skip_id_getter_proto);
-#endif
- DEFINE_OPCODE(op_get_by_id_getter_proto) {
- /* op_get_by_id_getter_proto dst(r) base(r) property(id) structure(sID) prototypeStructure(sID) offset(n) nop(n)
-
- Cached property access: Attempts to get a cached getter property from the
- value base's prototype. If the cache misses, op_get_by_id_getter_proto
- reverts to op_get_by_id.
- */
- int base = vPC[2].u.operand;
- JSValue baseValue = callFrame->r(base).jsValue();
-
- if (LIKELY(baseValue.isCell())) {
- JSCell* baseCell = baseValue.asCell();
- Structure* structure = vPC[4].u.structure.get();
-
- if (LIKELY(baseCell->structure() == structure)) {
- ASSERT(structure->prototypeForLookup(callFrame).isObject());
- JSObject* protoObject = asObject(structure->prototypeForLookup(callFrame));
- Structure* prototypeStructure = vPC[5].u.structure.get();
-
- if (LIKELY(protoObject->structure() == prototypeStructure)) {
- int dst = vPC[1].u.operand;
- int offset = vPC[6].u.operand;
- if (GetterSetter* getterSetter = asGetterSetter(protoObject->getDirectOffset(offset).asCell())) {
- JSObject* getter = getterSetter->getter();
- CallData callData;
- CallType callType = getter->methodTable()->getCallData(getter, callData);
- JSValue result = call(callFrame, getter, callType, callData, asObject(baseCell), ArgList());
- CHECK_FOR_EXCEPTION();
- callFrame->uncheckedR(dst) = result;
- } else
- callFrame->uncheckedR(dst) = jsUndefined();
- vPC += OPCODE_LENGTH(op_get_by_id_getter_proto);
- NEXT_INSTRUCTION();
- }
- }
- }
- uncacheGetByID(codeBlock, vPC);
- NEXT_INSTRUCTION();
- }
-#if USE(GCC_COMPUTED_GOTO_WORKAROUND)
- skip_id_getter_proto:
-#endif
-#if USE(GCC_COMPUTED_GOTO_WORKAROUND)
- goto *(&&skip_id_custom_proto);
-#endif
- DEFINE_OPCODE(op_get_by_id_custom_proto) {
- /* op_get_by_id_custom_proto dst(r) base(r) property(id) structure(sID) prototypeStructure(sID) offset(n) nop(n)
-
- Cached property access: Attempts to use a cached named property getter
- from the value base's prototype. If the cache misses, op_get_by_id_custom_proto
- reverts to op_get_by_id.
- */
- int base = vPC[2].u.operand;
- JSValue baseValue = callFrame->r(base).jsValue();
-
- if (LIKELY(baseValue.isCell())) {
- JSCell* baseCell = baseValue.asCell();
- Structure* structure = vPC[4].u.structure.get();
-
- if (LIKELY(baseCell->structure() == structure)) {
- ASSERT(structure->prototypeForLookup(callFrame).isObject());
- JSObject* protoObject = asObject(structure->prototypeForLookup(callFrame));
- Structure* prototypeStructure = vPC[5].u.structure.get();
-
- if (LIKELY(protoObject->structure() == prototypeStructure)) {
- int dst = vPC[1].u.operand;
- int property = vPC[3].u.operand;
- Identifier& ident = codeBlock->identifier(property);
-
- PropertySlot::GetValueFunc getter = vPC[6].u.getterFunc;
- JSValue result = getter(callFrame, protoObject, ident);
- CHECK_FOR_EXCEPTION();
- callFrame->uncheckedR(dst) = result;
- vPC += OPCODE_LENGTH(op_get_by_id_custom_proto);
- NEXT_INSTRUCTION();
- }
- }
- }
- uncacheGetByID(codeBlock, vPC);
- NEXT_INSTRUCTION();
- }
-#if USE(GCC_COMPUTED_GOTO_WORKAROUND)
- skip_id_custom_proto:
-#endif
-#if USE(GCC_COMPUTED_GOTO_WORKAROUND)
- goto *(&&skip_get_by_id_chain);
-#endif
- DEFINE_OPCODE(op_get_by_id_chain) {
- /* op_get_by_id_chain dst(r) base(r) property(id) structure(sID) structureChain(chain) count(n) offset(n)
-
- Cached property access: Attempts to get a cached property from the
- value base's prototype chain. If the cache misses, op_get_by_id_chain
- reverts to op_get_by_id.
- */
- int base = vPC[2].u.operand;
- JSValue baseValue = callFrame->r(base).jsValue();
-
- if (LIKELY(baseValue.isCell())) {
- JSCell* baseCell = baseValue.asCell();
- Structure* structure = vPC[4].u.structure.get();
-
- if (LIKELY(baseCell->structure() == structure)) {
- WriteBarrier<Structure>* it = vPC[5].u.structureChain->head();
- size_t count = vPC[6].u.operand;
- WriteBarrier<Structure>* end = it + count;
-
- while (true) {
- JSObject* baseObject = asObject(baseCell->structure()->prototypeForLookup(callFrame));
-
- if (UNLIKELY(baseObject->structure() != (*it).get()))
- break;
-
- if (++it == end) {
- int dst = vPC[1].u.operand;
- int offset = vPC[7].u.operand;
-
- ASSERT(baseObject->get(callFrame, codeBlock->identifier(vPC[3].u.operand)) == baseObject->getDirectOffset(offset));
- ASSERT(baseValue.get(callFrame, codeBlock->identifier(vPC[3].u.operand)) == baseObject->getDirectOffset(offset));
- callFrame->uncheckedR(dst) = JSValue(baseObject->getDirectOffset(offset));
-
- vPC += OPCODE_LENGTH(op_get_by_id_chain);
- NEXT_INSTRUCTION();
- }
-
- // Update baseCell, so that next time around the loop we'll pick up the prototype's prototype.
- baseCell = baseObject;
- }
- }
- }
-
- uncacheGetByID(codeBlock, vPC);
- NEXT_INSTRUCTION();
- }
-#if USE(GCC_COMPUTED_GOTO_WORKAROUND)
- skip_get_by_id_chain:
- goto *(&&skip_id_getter_self);
-#endif
- DEFINE_OPCODE(op_get_by_id_getter_self) {
- /* op_get_by_id_self dst(r) base(r) property(id) structure(sID) offset(n) nop(n) nop(n)
-
- Cached property access: Attempts to get a cached property from the
- value base. If the cache misses, op_get_by_id_getter_self reverts to
- op_get_by_id.
- */
- int base = vPC[2].u.operand;
- JSValue baseValue = callFrame->r(base).jsValue();
-
- if (LIKELY(baseValue.isCell())) {
- JSCell* baseCell = baseValue.asCell();
- Structure* structure = vPC[4].u.structure.get();
-
- if (LIKELY(baseCell->structure() == structure)) {
- ASSERT(baseCell->isObject());
- JSObject* baseObject = asObject(baseCell);
- int dst = vPC[1].u.operand;
- int offset = vPC[5].u.operand;
-
- if (GetterSetter* getterSetter = asGetterSetter(baseObject->getDirectOffset(offset).asCell())) {
- JSObject* getter = getterSetter->getter();
- CallData callData;
- CallType callType = getter->methodTable()->getCallData(getter, callData);
- JSValue result = call(callFrame, getter, callType, callData, baseObject, ArgList());
- CHECK_FOR_EXCEPTION();
- callFrame->uncheckedR(dst) = result;
- } else
- callFrame->uncheckedR(dst) = jsUndefined();
-
- vPC += OPCODE_LENGTH(op_get_by_id_getter_self);
- NEXT_INSTRUCTION();
- }
- }
- uncacheGetByID(codeBlock, vPC);
- NEXT_INSTRUCTION();
- }
-#if USE(GCC_COMPUTED_GOTO_WORKAROUND)
- skip_id_getter_self:
-#endif
-#if USE(GCC_COMPUTED_GOTO_WORKAROUND)
- goto *(&&skip_id_custom_self);
-#endif
- DEFINE_OPCODE(op_get_by_id_custom_self) {
- /* op_get_by_id_custom_self dst(r) base(r) property(id) structure(sID) offset(n) nop(n) nop(n)
-
- Cached property access: Attempts to use a cached named property getter
- from the value base. If the cache misses, op_get_by_id_custom_self reverts to
- op_get_by_id.
- */
- int base = vPC[2].u.operand;
- JSValue baseValue = callFrame->r(base).jsValue();
-
- if (LIKELY(baseValue.isCell())) {
- JSCell* baseCell = baseValue.asCell();
- Structure* structure = vPC[4].u.structure.get();
-
- if (LIKELY(baseCell->structure() == structure)) {
- ASSERT(baseCell->isObject());
- int dst = vPC[1].u.operand;
- int property = vPC[3].u.operand;
- Identifier& ident = codeBlock->identifier(property);
-
- PropertySlot::GetValueFunc getter = vPC[5].u.getterFunc;
- JSValue result = getter(callFrame, baseValue, ident);
- CHECK_FOR_EXCEPTION();
- callFrame->uncheckedR(dst) = result;
- vPC += OPCODE_LENGTH(op_get_by_id_custom_self);
- NEXT_INSTRUCTION();
- }
- }
- uncacheGetByID(codeBlock, vPC);
- NEXT_INSTRUCTION();
- }
-#if USE(GCC_COMPUTED_GOTO_WORKAROUND)
-skip_id_custom_self:
-#endif
- DEFINE_OPCODE(op_get_by_id_generic) {
- /* op_get_by_id_generic dst(r) base(r) property(id) nop(sID) nop(n) nop(n) nop(n)
-
- Generic property access: Gets the property named by identifier
- property from the value base, and puts the result in register dst.
- */
- int dst = vPC[1].u.operand;
- int base = vPC[2].u.operand;
- int property = vPC[3].u.operand;
-
- Identifier& ident = codeBlock->identifier(property);
- JSValue baseValue = callFrame->r(base).jsValue();
- PropertySlot slot(baseValue);
- JSValue result = baseValue.get(callFrame, ident, slot);
- CHECK_FOR_EXCEPTION();
-
- callFrame->uncheckedR(dst) = result;
- vPC += OPCODE_LENGTH(op_get_by_id_generic);
- NEXT_INSTRUCTION();
- }
-#if USE(GCC_COMPUTED_GOTO_WORKAROUND)
- goto *(&&skip_id_getter_chain);
-#endif
- DEFINE_OPCODE(op_get_by_id_getter_chain) {
- /* op_get_by_id_getter_chain dst(r) base(r) property(id) structure(sID) structureChain(chain) count(n) offset(n)
-
- Cached property access: Attempts to get a cached property from the
- value base's prototype chain. If the cache misses, op_get_by_id_getter_chain
- reverts to op_get_by_id.
- */
- int base = vPC[2].u.operand;
- JSValue baseValue = callFrame->r(base).jsValue();
-
- if (LIKELY(baseValue.isCell())) {
- JSCell* baseCell = baseValue.asCell();
- Structure* structure = vPC[4].u.structure.get();
-
- if (LIKELY(baseCell->structure() == structure)) {
- WriteBarrier<Structure>* it = vPC[5].u.structureChain->head();
- size_t count = vPC[6].u.operand;
- WriteBarrier<Structure>* end = it + count;
-
- while (true) {
- JSObject* baseObject = asObject(baseCell->structure()->prototypeForLookup(callFrame));
-
- if (UNLIKELY(baseObject->structure() != (*it).get()))
- break;
-
- if (++it == end) {
- int dst = vPC[1].u.operand;
- int offset = vPC[7].u.operand;
- if (GetterSetter* getterSetter = asGetterSetter(baseObject->getDirectOffset(offset).asCell())) {
- JSObject* getter = getterSetter->getter();
- CallData callData;
- CallType callType = getter->methodTable()->getCallData(getter, callData);
- JSValue result = call(callFrame, getter, callType, callData, baseValue, ArgList());
- CHECK_FOR_EXCEPTION();
- callFrame->uncheckedR(dst) = result;
- } else
- callFrame->uncheckedR(dst) = jsUndefined();
- vPC += OPCODE_LENGTH(op_get_by_id_getter_chain);
- NEXT_INSTRUCTION();
- }
-
- // Update baseCell, so that next time around the loop we'll pick up the prototype's prototype.
- baseCell = baseObject;
- }
- }
- }
- uncacheGetByID(codeBlock, vPC);
- NEXT_INSTRUCTION();
- }
-#if USE(GCC_COMPUTED_GOTO_WORKAROUND)
- skip_id_getter_chain:
-#endif
-#if USE(GCC_COMPUTED_GOTO_WORKAROUND)
- goto *(&&skip_id_custom_chain);
-#endif
- DEFINE_OPCODE(op_get_by_id_custom_chain) {
- /* op_get_by_id_custom_chain dst(r) base(r) property(id) structure(sID) structureChain(chain) count(n) offset(n)
-
- Cached property access: Attempts to use a cached named property getter on the
- value base's prototype chain. If the cache misses, op_get_by_id_custom_chain
- reverts to op_get_by_id.
- */
- int base = vPC[2].u.operand;
- JSValue baseValue = callFrame->r(base).jsValue();
-
- if (LIKELY(baseValue.isCell())) {
- JSCell* baseCell = baseValue.asCell();
- Structure* structure = vPC[4].u.structure.get();
-
- if (LIKELY(baseCell->structure() == structure)) {
- WriteBarrier<Structure>* it = vPC[5].u.structureChain->head();
- size_t count = vPC[6].u.operand;
- WriteBarrier<Structure>* end = it + count;
-
- while (true) {
- JSObject* baseObject = asObject(baseCell->structure()->prototypeForLookup(callFrame));
-
- if (UNLIKELY(baseObject->structure() != (*it).get()))
- break;
-
- if (++it == end) {
- int dst = vPC[1].u.operand;
- int property = vPC[3].u.operand;
- Identifier& ident = codeBlock->identifier(property);
-
- PropertySlot::GetValueFunc getter = vPC[7].u.getterFunc;
- JSValue result = getter(callFrame, baseObject, ident);
- CHECK_FOR_EXCEPTION();
- callFrame->uncheckedR(dst) = result;
- vPC += OPCODE_LENGTH(op_get_by_id_custom_chain);
- NEXT_INSTRUCTION();
- }
-
- // Update baseCell, so that next time around the loop we'll pick up the prototype's prototype.
- baseCell = baseObject;
- }
- }
- }
- uncacheGetByID(codeBlock, vPC);
- NEXT_INSTRUCTION();
- }
-#if USE(GCC_COMPUTED_GOTO_WORKAROUND)
- skip_id_custom_chain:
- goto *(&&skip_get_array_length);
-#endif
- DEFINE_OPCODE(op_get_array_length) {
- /* op_get_array_length dst(r) base(r) property(id) nop(sID) nop(n) nop(n) nop(n)
-
- Cached property access: Gets the length of the array in register base,
- and puts the result in register dst. If register base does not hold
- an array, op_get_array_length reverts to op_get_by_id.
- */
-
- int base = vPC[2].u.operand;
- JSValue baseValue = callFrame->r(base).jsValue();
- if (LIKELY(isJSArray(baseValue))) {
- int dst = vPC[1].u.operand;
- callFrame->uncheckedR(dst) = jsNumber(asArray(baseValue)->length());
- vPC += OPCODE_LENGTH(op_get_array_length);
- NEXT_INSTRUCTION();
- }
-
- uncacheGetByID(codeBlock, vPC);
- NEXT_INSTRUCTION();
- }
-#if USE(GCC_COMPUTED_GOTO_WORKAROUND)
- skip_get_array_length:
- goto *(&&skip_get_string_length);
-#endif
- DEFINE_OPCODE(op_get_string_length) {
- /* op_get_string_length dst(r) base(r) property(id) nop(sID) nop(n) nop(n) nop(n)
-
- Cached property access: Gets the length of the string in register base,
- and puts the result in register dst. If register base does not hold
- a string, op_get_string_length reverts to op_get_by_id.
- */
-
- int base = vPC[2].u.operand;
- JSValue baseValue = callFrame->r(base).jsValue();
- if (LIKELY(isJSString(baseValue))) {
- int dst = vPC[1].u.operand;
- callFrame->uncheckedR(dst) = jsNumber(asString(baseValue)->length());
- vPC += OPCODE_LENGTH(op_get_string_length);
- NEXT_INSTRUCTION();
- }
-
- uncacheGetByID(codeBlock, vPC);
- NEXT_INSTRUCTION();
- }
-#if USE(GCC_COMPUTED_GOTO_WORKAROUND)
- skip_get_string_length:
- goto *(&&skip_put_by_id);
-#endif
- DEFINE_OPCODE(op_put_by_id_out_of_line)
- DEFINE_OPCODE(op_put_by_id) {
- /* put_by_id base(r) property(id) value(r) nop(n) nop(n) nop(n) nop(n) direct(b)
-
- Generic property access: Sets the property named by identifier
- property, belonging to register base, to register value.
-
- Unlike many opcodes, this one does not write any output to
- the register file.
-
- The "direct" flag should only be set this put_by_id is to initialize
- an object literal.
- */
-
- int base = vPC[1].u.operand;
- int property = vPC[2].u.operand;
- int value = vPC[3].u.operand;
- int direct = vPC[8].u.operand;
-
- JSValue baseValue = callFrame->r(base).jsValue();
- Identifier& ident = codeBlock->identifier(property);
- PutPropertySlot slot(codeBlock->isStrictMode());
- if (direct) {
- ASSERT(baseValue.isObject());
- asObject(baseValue)->putDirect(*globalData, ident, callFrame->r(value).jsValue(), slot);
- } else
- baseValue.put(callFrame, ident, callFrame->r(value).jsValue(), slot);
- CHECK_FOR_EXCEPTION();
-
- tryCachePutByID(callFrame, codeBlock, vPC, baseValue, slot);
-
- vPC += OPCODE_LENGTH(op_put_by_id);
- NEXT_INSTRUCTION();
- }
-#if USE(GCC_COMPUTED_GOTO_WORKAROUND)
- skip_put_by_id:
-#endif
- DEFINE_OPCODE(op_put_by_id_transition_direct)
- DEFINE_OPCODE(op_put_by_id_transition_normal)
- DEFINE_OPCODE(op_put_by_id_transition_direct_out_of_line)
- DEFINE_OPCODE(op_put_by_id_transition_normal_out_of_line)
- DEFINE_OPCODE(op_put_by_id_transition) {
- /* op_put_by_id_transition base(r) property(id) value(r) oldStructure(sID) newStructure(sID) structureChain(chain) offset(n) direct(b)
-
- Cached property access: Attempts to set a new property with a cached transition
- property named by identifier property, belonging to register base,
- to register value. If the cache misses, op_put_by_id_transition
- reverts to op_put_by_id_generic.
-
- Unlike many opcodes, this one does not write any output to
- the register file.
- */
- int base = vPC[1].u.operand;
- JSValue baseValue = callFrame->r(base).jsValue();
-
- if (LIKELY(baseValue.isCell())) {
- JSCell* baseCell = baseValue.asCell();
- Structure* oldStructure = vPC[4].u.structure.get();
- Structure* newStructure = vPC[5].u.structure.get();
-
- if (LIKELY(baseCell->structure() == oldStructure)) {
- ASSERT(baseCell->isObject());
- JSObject* baseObject = asObject(baseCell);
- int direct = vPC[8].u.operand;
-
- if (!direct) {
- WriteBarrier<Structure>* it = vPC[6].u.structureChain->head();
-
- JSValue proto = baseObject->structure()->prototypeForLookup(callFrame);
- while (!proto.isNull()) {
- if (UNLIKELY(asObject(proto)->structure() != (*it).get())) {
- uncachePutByID(codeBlock, vPC);
- NEXT_INSTRUCTION();
- }
- ++it;
- proto = asObject(proto)->structure()->prototypeForLookup(callFrame);
- }
- }
- baseObject->setStructureAndReallocateStorageIfNecessary(*globalData, newStructure);
-
- int value = vPC[3].u.operand;
- int offset = vPC[7].u.operand;
- ASSERT(baseObject->offsetForLocation(baseObject->getDirectLocation(*globalData, codeBlock->identifier(vPC[2].u.operand))) == offset);
- baseObject->putDirectOffset(callFrame->globalData(), offset, callFrame->r(value).jsValue());
-
- vPC += OPCODE_LENGTH(op_put_by_id_transition);
- NEXT_INSTRUCTION();
- }
- }
-
- uncachePutByID(codeBlock, vPC);
- NEXT_INSTRUCTION();
- }
- DEFINE_OPCODE(op_put_by_id_replace) {
- /* op_put_by_id_replace base(r) property(id) value(r) structure(sID) offset(n) nop(n) nop(n) direct(b)
-
- Cached property access: Attempts to set a pre-existing, cached
- property named by identifier property, belonging to register base,
- to register value. If the cache misses, op_put_by_id_replace
- reverts to op_put_by_id.
-
- Unlike many opcodes, this one does not write any output to
- the register file.
- */
- int base = vPC[1].u.operand;
- JSValue baseValue = callFrame->r(base).jsValue();
-
- if (LIKELY(baseValue.isCell())) {
- JSCell* baseCell = baseValue.asCell();
- Structure* structure = vPC[4].u.structure.get();
-
- if (LIKELY(baseCell->structure() == structure)) {
- ASSERT(baseCell->isObject());
- JSObject* baseObject = asObject(baseCell);
- int value = vPC[3].u.operand;
- int offset = vPC[5].u.operand;
-
- ASSERT(baseObject->offsetForLocation(baseObject->getDirectLocation(*globalData, codeBlock->identifier(vPC[2].u.operand))) == offset);
- baseObject->putDirectOffset(callFrame->globalData(), offset, callFrame->r(value).jsValue());
-
- vPC += OPCODE_LENGTH(op_put_by_id_replace);
- NEXT_INSTRUCTION();
- }
- }
-
- uncachePutByID(codeBlock, vPC);
- NEXT_INSTRUCTION();
- }
- DEFINE_OPCODE(op_put_by_id_generic) {
- /* op_put_by_id_generic base(r) property(id) value(r) nop(n) nop(n) nop(n) nop(n) direct(b)
-
- Generic property access: Sets the property named by identifier
- property, belonging to register base, to register value.
-
- Unlike many opcodes, this one does not write any output to
- the register file.
- */
- int base = vPC[1].u.operand;
- int property = vPC[2].u.operand;
- int value = vPC[3].u.operand;
- int direct = vPC[8].u.operand;
-
- JSValue baseValue = callFrame->r(base).jsValue();
- Identifier& ident = codeBlock->identifier(property);
- PutPropertySlot slot(codeBlock->isStrictMode());
- if (direct) {
- ASSERT(baseValue.isObject());
- asObject(baseValue)->putDirect(*globalData, ident, callFrame->r(value).jsValue(), slot);
- } else
- baseValue.put(callFrame, ident, callFrame->r(value).jsValue(), slot);
- CHECK_FOR_EXCEPTION();
-
- vPC += OPCODE_LENGTH(op_put_by_id_generic);
- NEXT_INSTRUCTION();
- }
- DEFINE_OPCODE(op_del_by_id) {
- /* del_by_id dst(r) base(r) property(id)
-
- Converts register base to Object, deletes the property
- named by identifier property from the object, and writes a
- boolean indicating success (if true) or failure (if false)
- to register dst.
- */
- int dst = vPC[1].u.operand;
- int base = vPC[2].u.operand;
- int property = vPC[3].u.operand;
-
- JSObject* baseObj = callFrame->r(base).jsValue().toObject(callFrame);
- Identifier& ident = codeBlock->identifier(property);
- bool result = baseObj->methodTable()->deleteProperty(baseObj, callFrame, ident);
- if (!result && codeBlock->isStrictMode()) {
- exceptionValue = createTypeError(callFrame, "Unable to delete property.");
- goto vm_throw;
- }
- CHECK_FOR_EXCEPTION();
- callFrame->uncheckedR(dst) = jsBoolean(result);
- vPC += OPCODE_LENGTH(op_del_by_id);
- NEXT_INSTRUCTION();
- }
- DEFINE_OPCODE(op_get_by_pname) {
- int dst = vPC[1].u.operand;
- int base = vPC[2].u.operand;
- int property = vPC[3].u.operand;
- int expected = vPC[4].u.operand;
- int iter = vPC[5].u.operand;
- int i = vPC[6].u.operand;
-
- JSValue baseValue = callFrame->r(base).jsValue();
- JSPropertyNameIterator* it = callFrame->r(iter).propertyNameIterator();
- JSValue subscript = callFrame->r(property).jsValue();
- JSValue expectedSubscript = callFrame->r(expected).jsValue();
- int index = callFrame->r(i).i() - 1;
- JSValue result;
- PropertyOffset offset = 0;
- if (subscript == expectedSubscript && baseValue.isCell() && (baseValue.asCell()->structure() == it->cachedStructure()) && it->getOffset(index, offset)) {
- callFrame->uncheckedR(dst) = JSValue(asObject(baseValue)->getDirectOffset(offset));
- vPC += OPCODE_LENGTH(op_get_by_pname);
- NEXT_INSTRUCTION();
- }
- {
- Identifier propertyName(callFrame, subscript.toString(callFrame)->value(callFrame));
- result = baseValue.get(callFrame, propertyName);
- }
- CHECK_FOR_EXCEPTION();
- callFrame->uncheckedR(dst) = result;
- vPC += OPCODE_LENGTH(op_get_by_pname);
- NEXT_INSTRUCTION();
- }
- DEFINE_OPCODE(op_get_arguments_length) {
- int dst = vPC[1].u.operand;
- int argumentsRegister = vPC[2].u.operand;
- int property = vPC[3].u.operand;
- JSValue arguments = callFrame->r(argumentsRegister).jsValue();
- if (arguments) {
- Identifier& ident = codeBlock->identifier(property);
- PropertySlot slot(arguments);
- JSValue result = arguments.get(callFrame, ident, slot);
- CHECK_FOR_EXCEPTION();
- callFrame->uncheckedR(dst) = result;
- } else
- callFrame->uncheckedR(dst) = jsNumber(callFrame->argumentCount());
-
- vPC += OPCODE_LENGTH(op_get_arguments_length);
- NEXT_INSTRUCTION();
- }
- DEFINE_OPCODE(op_get_argument_by_val) {
- int dst = vPC[1].u.operand;
- int argumentsRegister = vPC[2].u.operand;
- int property = vPC[3].u.operand;
- JSValue arguments = callFrame->r(argumentsRegister).jsValue();
- JSValue subscript = callFrame->r(property).jsValue();
- if (!arguments && subscript.isUInt32() && subscript.asUInt32() < callFrame->argumentCount()) {
- callFrame->uncheckedR(dst) = callFrame->argument(subscript.asUInt32());
- vPC += OPCODE_LENGTH(op_get_argument_by_val);
- NEXT_INSTRUCTION();
- }
- if (!arguments) {
- Arguments* arguments = Arguments::create(*globalData, callFrame);
- callFrame->uncheckedR(argumentsRegister) = JSValue(arguments);
- callFrame->uncheckedR(unmodifiedArgumentsRegister(argumentsRegister)) = JSValue(arguments);
- }
- // fallthrough
- }
- DEFINE_OPCODE(op_get_by_val) {
- /* get_by_val dst(r) base(r) property(r)
-
- Converts register base to Object, gets the property named
- by register property from the object, and puts the result
- in register dst. property is nominally converted to string
- but numbers are treated more efficiently.
- */
- int dst = vPC[1].u.operand;
- int base = vPC[2].u.operand;
- int property = vPC[3].u.operand;
-
- JSValue baseValue = callFrame->r(base).jsValue();
- JSValue subscript = callFrame->r(property).jsValue();
-
- JSValue result;
-
- if (LIKELY(subscript.isUInt32())) {
- uint32_t i = subscript.asUInt32();
- if (isJSArray(baseValue)) {
- JSArray* jsArray = asArray(baseValue);
- if (jsArray->canGetIndexQuickly(i))
- result = jsArray->getIndexQuickly(i);
- else
- result = jsArray->JSArray::get(callFrame, i);
- } else if (isJSString(baseValue) && asString(baseValue)->canGetIndex(i))
- result = asString(baseValue)->getIndex(callFrame, i);
- else
- result = baseValue.get(callFrame, i);
- } else if (isName(subscript))
- result = baseValue.get(callFrame, jsCast<NameInstance*>(subscript.asCell())->privateName());
- else {
- Identifier property(callFrame, subscript.toString(callFrame)->value(callFrame));
- result = baseValue.get(callFrame, property);
- }
-
- CHECK_FOR_EXCEPTION();
- callFrame->uncheckedR(dst) = result;
- vPC += OPCODE_LENGTH(op_get_by_val);
- NEXT_INSTRUCTION();
- }
- DEFINE_OPCODE(op_put_by_val) {
- /* put_by_val base(r) property(r) value(r)
-
- Sets register value on register base as the property named
- by register property. Base is converted to object
- first. register property is nominally converted to string
- but numbers are treated more efficiently.
-
- Unlike many opcodes, this one does not write any output to
- the register file.
- */
- int base = vPC[1].u.operand;
- int property = vPC[2].u.operand;
- int value = vPC[3].u.operand;
-
- JSValue baseValue = callFrame->r(base).jsValue();
- JSValue subscript = callFrame->r(property).jsValue();
-
- if (LIKELY(subscript.isUInt32())) {
- uint32_t i = subscript.asUInt32();
- if (isJSArray(baseValue)) {
- JSArray* jsArray = asArray(baseValue);
- if (jsArray->canSetIndexQuickly(i))
- jsArray->setIndexQuickly(*globalData, i, callFrame->r(value).jsValue());
- else
- jsArray->JSArray::putByIndex(jsArray, callFrame, i, callFrame->r(value).jsValue(), codeBlock->isStrictMode());
- } else
- baseValue.putByIndex(callFrame, i, callFrame->r(value).jsValue(), codeBlock->isStrictMode());
- } else if (isName(subscript)) {
- PutPropertySlot slot(codeBlock->isStrictMode());
- baseValue.put(callFrame, jsCast<NameInstance*>(subscript.asCell())->privateName(), callFrame->r(value).jsValue(), slot);
- } else {
- Identifier property(callFrame, subscript.toString(callFrame)->value(callFrame));
- if (!globalData->exception) { // Don't put to an object if toString threw an exception.
- PutPropertySlot slot(codeBlock->isStrictMode());
- baseValue.put(callFrame, property, callFrame->r(value).jsValue(), slot);
- }
- }
-
- CHECK_FOR_EXCEPTION();
- vPC += OPCODE_LENGTH(op_put_by_val);
- NEXT_INSTRUCTION();
- }
- DEFINE_OPCODE(op_del_by_val) {
- /* del_by_val dst(r) base(r) property(r)
-
- Converts register base to Object, deletes the property
- named by register property from the object, and writes a
- boolean indicating success (if true) or failure (if false)
- to register dst.
- */
- int dst = vPC[1].u.operand;
- int base = vPC[2].u.operand;
- int property = vPC[3].u.operand;
-
- JSObject* baseObj = callFrame->r(base).jsValue().toObject(callFrame); // may throw
-
- JSValue subscript = callFrame->r(property).jsValue();
- bool result;
- uint32_t i;
- if (subscript.getUInt32(i))
- result = baseObj->methodTable()->deletePropertyByIndex(baseObj, callFrame, i);
- else if (isName(subscript))
- result = baseObj->methodTable()->deleteProperty(baseObj, callFrame, jsCast<NameInstance*>(subscript.asCell())->privateName());
- else {
- CHECK_FOR_EXCEPTION();
- Identifier property(callFrame, subscript.toString(callFrame)->value(callFrame));
- CHECK_FOR_EXCEPTION();
- result = baseObj->methodTable()->deleteProperty(baseObj, callFrame, property);
- }
- if (!result && codeBlock->isStrictMode()) {
- exceptionValue = createTypeError(callFrame, "Unable to delete property.");
- goto vm_throw;
- }
- CHECK_FOR_EXCEPTION();
- callFrame->uncheckedR(dst) = jsBoolean(result);
- vPC += OPCODE_LENGTH(op_del_by_val);
- NEXT_INSTRUCTION();
- }
- DEFINE_OPCODE(op_put_by_index) {
- /* put_by_index base(r) property(n) value(r)
-
- Sets register value on register base as the property named
- by the immediate number property. Base is converted to
- object first.
-
- Unlike many opcodes, this one does not write any output to
- the register file.
-
- This opcode is mainly used to initialize array literals.
- */
- int base = vPC[1].u.operand;
- unsigned property = vPC[2].u.operand;
- int value = vPC[3].u.operand;
-
- JSValue arrayValue = callFrame->r(base).jsValue();
- ASSERT(isJSArray(arrayValue));
- asArray(arrayValue)->putDirectIndex(callFrame, property, callFrame->r(value).jsValue());
-
- vPC += OPCODE_LENGTH(op_put_by_index);
- NEXT_INSTRUCTION();
- }
- DEFINE_OPCODE(op_loop) {
- /* loop target(offset)
-
- Jumps unconditionally to offset target from the current
- instruction.
-
- Additionally this loop instruction may terminate JS execution is
- the JS timeout is reached.
- */
-#if ENABLE(OPCODE_STATS)
- OpcodeStats::resetLastInstruction();
-#endif
- int target = vPC[1].u.operand;
- CHECK_FOR_TIMEOUT();
- vPC += target;
- NEXT_INSTRUCTION();
- }
- DEFINE_OPCODE(op_jmp) {
- /* jmp target(offset)
-
- Jumps unconditionally to offset target from the current
- instruction.
- */
-#if ENABLE(OPCODE_STATS)
- OpcodeStats::resetLastInstruction();
-#endif
- int target = vPC[1].u.operand;
-
- vPC += target;
- NEXT_INSTRUCTION();
- }
- DEFINE_OPCODE(op_loop_hint) {
- // This is a no-op unless we intend on doing OSR from the interpreter.
- vPC += OPCODE_LENGTH(op_loop_hint);
- NEXT_INSTRUCTION();
- }
- DEFINE_OPCODE(op_loop_if_true) {
- /* loop_if_true cond(r) target(offset)
-
- Jumps to offset target from the current instruction, if and
- only if register cond converts to boolean as true.
-
- Additionally this loop instruction may terminate JS execution is
- the JS timeout is reached.
- */
- int cond = vPC[1].u.operand;
- int target = vPC[2].u.operand;
- if (callFrame->r(cond).jsValue().toBoolean(callFrame)) {
- vPC += target;
- CHECK_FOR_TIMEOUT();
- NEXT_INSTRUCTION();
- }
-
- vPC += OPCODE_LENGTH(op_loop_if_true);
- NEXT_INSTRUCTION();
- }
- DEFINE_OPCODE(op_loop_if_false) {
- /* loop_if_true cond(r) target(offset)
-
- Jumps to offset target from the current instruction, if and
- only if register cond converts to boolean as false.
-
- Additionally this loop instruction may terminate JS execution is
- the JS timeout is reached.
- */
- int cond = vPC[1].u.operand;
- int target = vPC[2].u.operand;
- if (!callFrame->r(cond).jsValue().toBoolean(callFrame)) {
- vPC += target;
- CHECK_FOR_TIMEOUT();
- NEXT_INSTRUCTION();
- }
-
- vPC += OPCODE_LENGTH(op_loop_if_true);
- NEXT_INSTRUCTION();
- }
- DEFINE_OPCODE(op_jtrue) {
- /* jtrue cond(r) target(offset)
-
- Jumps to offset target from the current instruction, if and
- only if register cond converts to boolean as true.
- */
- int cond = vPC[1].u.operand;
- int target = vPC[2].u.operand;
- if (callFrame->r(cond).jsValue().toBoolean(callFrame)) {
- vPC += target;
- NEXT_INSTRUCTION();
- }
-
- vPC += OPCODE_LENGTH(op_jtrue);
- NEXT_INSTRUCTION();
- }
- DEFINE_OPCODE(op_jfalse) {
- /* jfalse cond(r) target(offset)
-
- Jumps to offset target from the current instruction, if and
- only if register cond converts to boolean as false.
- */
- int cond = vPC[1].u.operand;
- int target = vPC[2].u.operand;
- if (!callFrame->r(cond).jsValue().toBoolean(callFrame)) {
- vPC += target;
- NEXT_INSTRUCTION();
- }
-
- vPC += OPCODE_LENGTH(op_jfalse);
- NEXT_INSTRUCTION();
- }
- DEFINE_OPCODE(op_jeq_null) {
- /* jeq_null src(r) target(offset)
-
- Jumps to offset target from the current instruction, if and
- only if register src is null.
- */
- int src = vPC[1].u.operand;
- int target = vPC[2].u.operand;
- JSValue srcValue = callFrame->r(src).jsValue();
-
- if (srcValue.isUndefinedOrNull() || (srcValue.isCell() && srcValue.asCell()->structure()->masqueradesAsUndefined(callFrame->lexicalGlobalObject()))) {
- vPC += target;
- NEXT_INSTRUCTION();
- }
-
- vPC += OPCODE_LENGTH(op_jeq_null);
- NEXT_INSTRUCTION();
- }
- DEFINE_OPCODE(op_jneq_null) {
- /* jneq_null src(r) target(offset)
-
- Jumps to offset target from the current instruction, if and
- only if register src is not null.
- */
- int src = vPC[1].u.operand;
- int target = vPC[2].u.operand;
- JSValue srcValue = callFrame->r(src).jsValue();
-
- if (!srcValue.isUndefinedOrNull() && (!srcValue.isCell() || !(srcValue.asCell()->structure()->masqueradesAsUndefined(callFrame->lexicalGlobalObject())))) {
- vPC += target;
- NEXT_INSTRUCTION();
- }
-
- vPC += OPCODE_LENGTH(op_jneq_null);
- NEXT_INSTRUCTION();
- }
- DEFINE_OPCODE(op_jneq_ptr) {
- /* jneq_ptr src(r) ptr(jsCell) target(offset)
-
- Jumps to offset target from the current instruction, if the value r is equal
- to ptr, using pointer equality.
- */
- int src = vPC[1].u.operand;
- int target = vPC[3].u.operand;
- JSValue srcValue = callFrame->r(src).jsValue();
- if (srcValue != vPC[2].u.jsCell.get()) {
- vPC += target;
- NEXT_INSTRUCTION();
- }
-
- vPC += OPCODE_LENGTH(op_jneq_ptr);
- NEXT_INSTRUCTION();
- }
- DEFINE_OPCODE(op_loop_if_less) {
- /* loop_if_less src1(r) src2(r) target(offset)
-
- Checks whether register src1 is less than register src2, as
- with the ECMAScript '<' operator, and then jumps to offset
- target from the current instruction, if and only if the
- result of the comparison is true.
-
- Additionally this loop instruction may terminate JS execution is
- the JS timeout is reached.
- */
- JSValue src1 = callFrame->r(vPC[1].u.operand).jsValue();
- JSValue src2 = callFrame->r(vPC[2].u.operand).jsValue();
- int target = vPC[3].u.operand;
-
- bool result = jsLess<true>(callFrame, src1, src2);
- CHECK_FOR_EXCEPTION();
-
- if (result) {
- vPC += target;
- CHECK_FOR_TIMEOUT();
- NEXT_INSTRUCTION();
- }
-
- vPC += OPCODE_LENGTH(op_loop_if_less);
- NEXT_INSTRUCTION();
- }
- DEFINE_OPCODE(op_loop_if_lesseq) {
- /* loop_if_lesseq src1(r) src2(r) target(offset)
-
- Checks whether register src1 is less than or equal to register
- src2, as with the ECMAScript '<=' operator, and then jumps to
- offset target from the current instruction, if and only if the
- result of the comparison is true.
-
- Additionally this loop instruction may terminate JS execution is
- the JS timeout is reached.
- */
- JSValue src1 = callFrame->r(vPC[1].u.operand).jsValue();
- JSValue src2 = callFrame->r(vPC[2].u.operand).jsValue();
- int target = vPC[3].u.operand;
-
- bool result = jsLessEq<true>(callFrame, src1, src2);
- CHECK_FOR_EXCEPTION();
-
- if (result) {
- vPC += target;
- CHECK_FOR_TIMEOUT();
- NEXT_INSTRUCTION();
- }
-
- vPC += OPCODE_LENGTH(op_loop_if_lesseq);
- NEXT_INSTRUCTION();
- }
- DEFINE_OPCODE(op_loop_if_greater) {
- /* loop_if_greater src1(r) src2(r) target(offset)
-
- Checks whether register src1 is greater than register src2, as
- with the ECMAScript '>' operator, and then jumps to offset
- target from the current instruction, if and only if the
- result of the comparison is true.
-
- Additionally this loop instruction may terminate JS execution is
- the JS timeout is reached.
- */
- JSValue src1 = callFrame->r(vPC[1].u.operand).jsValue();
- JSValue src2 = callFrame->r(vPC[2].u.operand).jsValue();
- int target = vPC[3].u.operand;
-
- bool result = jsLess<false>(callFrame, src2, src1);
- CHECK_FOR_EXCEPTION();
-
- if (result) {
- vPC += target;
- CHECK_FOR_TIMEOUT();
- NEXT_INSTRUCTION();
- }
-
- vPC += OPCODE_LENGTH(op_loop_if_greater);
- NEXT_INSTRUCTION();
- }
- DEFINE_OPCODE(op_loop_if_greatereq) {
- /* loop_if_greatereq src1(r) src2(r) target(offset)
-
- Checks whether register src1 is greater than or equal to register
- src2, as with the ECMAScript '>=' operator, and then jumps to
- offset target from the current instruction, if and only if the
- result of the comparison is true.
-
- Additionally this loop instruction may terminate JS execution is
- the JS timeout is reached.
- */
- JSValue src1 = callFrame->r(vPC[1].u.operand).jsValue();
- JSValue src2 = callFrame->r(vPC[2].u.operand).jsValue();
- int target = vPC[3].u.operand;
-
- bool result = jsLessEq<false>(callFrame, src2, src1);
- CHECK_FOR_EXCEPTION();
-
- if (result) {
- vPC += target;
- CHECK_FOR_TIMEOUT();
- NEXT_INSTRUCTION();
- }
-
- vPC += OPCODE_LENGTH(op_loop_if_greatereq);
- NEXT_INSTRUCTION();
- }
- DEFINE_OPCODE(op_jless) {
- /* jless src1(r) src2(r) target(offset)
-
- Checks whether register src1 is less than register src2, as
- with the ECMAScript '<' operator, and then jumps to offset
- target from the current instruction, if and only if the
- result of the comparison is true.
- */
- JSValue src1 = callFrame->r(vPC[1].u.operand).jsValue();
- JSValue src2 = callFrame->r(vPC[2].u.operand).jsValue();
- int target = vPC[3].u.operand;
-
- bool result = jsLess<true>(callFrame, src1, src2);
- CHECK_FOR_EXCEPTION();
-
- if (result) {
- vPC += target;
- NEXT_INSTRUCTION();
- }
-
- vPC += OPCODE_LENGTH(op_jless);
- NEXT_INSTRUCTION();
- }
- DEFINE_OPCODE(op_jlesseq) {
- /* jlesseq src1(r) src2(r) target(offset)
-
- Checks whether register src1 is less than or equal to
- register src2, as with the ECMAScript '<=' operator,
- and then jumps to offset target from the current instruction,
- if and only if the result of the comparison is true.
- */
- JSValue src1 = callFrame->r(vPC[1].u.operand).jsValue();
- JSValue src2 = callFrame->r(vPC[2].u.operand).jsValue();
- int target = vPC[3].u.operand;
-
- bool result = jsLessEq<true>(callFrame, src1, src2);
- CHECK_FOR_EXCEPTION();
-
- if (result) {
- vPC += target;
- NEXT_INSTRUCTION();
- }
-
- vPC += OPCODE_LENGTH(op_jlesseq);
- NEXT_INSTRUCTION();
- }
- DEFINE_OPCODE(op_jgreater) {
- /* jgreater src1(r) src2(r) target(offset)
-
- Checks whether register src1 is greater than register src2, as
- with the ECMAScript '>' operator, and then jumps to offset
- target from the current instruction, if and only if the
- result of the comparison is true.
- */
- JSValue src1 = callFrame->r(vPC[1].u.operand).jsValue();
- JSValue src2 = callFrame->r(vPC[2].u.operand).jsValue();
- int target = vPC[3].u.operand;
-
- bool result = jsLess<false>(callFrame, src2, src1);
- CHECK_FOR_EXCEPTION();
-
- if (result) {
- vPC += target;
- NEXT_INSTRUCTION();
- }
-
- vPC += OPCODE_LENGTH(op_jgreater);
- NEXT_INSTRUCTION();
- }
- DEFINE_OPCODE(op_jgreatereq) {
- /* jgreatereq src1(r) src2(r) target(offset)
-
- Checks whether register src1 is greater than or equal to
- register src2, as with the ECMAScript '>=' operator,
- and then jumps to offset target from the current instruction,
- if and only if the result of the comparison is true.
- */
- JSValue src1 = callFrame->r(vPC[1].u.operand).jsValue();
- JSValue src2 = callFrame->r(vPC[2].u.operand).jsValue();
- int target = vPC[3].u.operand;
-
- bool result = jsLessEq<false>(callFrame, src2, src1);
- CHECK_FOR_EXCEPTION();
-
- if (result) {
- vPC += target;
- NEXT_INSTRUCTION();
- }
-
- vPC += OPCODE_LENGTH(op_jgreatereq);
- NEXT_INSTRUCTION();
- }
- DEFINE_OPCODE(op_jnless) {
- /* jnless src1(r) src2(r) target(offset)
-
- Checks whether register src1 is less than register src2, as
- with the ECMAScript '<' operator, and then jumps to offset
- target from the current instruction, if and only if the
- result of the comparison is false.
- */
- JSValue src1 = callFrame->r(vPC[1].u.operand).jsValue();
- JSValue src2 = callFrame->r(vPC[2].u.operand).jsValue();
- int target = vPC[3].u.operand;
-
- bool result = jsLess<true>(callFrame, src1, src2);
- CHECK_FOR_EXCEPTION();
-
- if (!result) {
- vPC += target;
- NEXT_INSTRUCTION();
- }
-
- vPC += OPCODE_LENGTH(op_jnless);
- NEXT_INSTRUCTION();
- }
- DEFINE_OPCODE(op_jnlesseq) {
- /* jnlesseq src1(r) src2(r) target(offset)
-
- Checks whether register src1 is less than or equal to
- register src2, as with the ECMAScript '<=' operator,
- and then jumps to offset target from the current instruction,
- if and only if theresult of the comparison is false.
- */
- JSValue src1 = callFrame->r(vPC[1].u.operand).jsValue();
- JSValue src2 = callFrame->r(vPC[2].u.operand).jsValue();
- int target = vPC[3].u.operand;
-
- bool result = jsLessEq<true>(callFrame, src1, src2);
- CHECK_FOR_EXCEPTION();
-
- if (!result) {
- vPC += target;
- NEXT_INSTRUCTION();
- }
-
- vPC += OPCODE_LENGTH(op_jnlesseq);
- NEXT_INSTRUCTION();
- }
- DEFINE_OPCODE(op_jngreater) {
- /* jngreater src1(r) src2(r) target(offset)
-
- Checks whether register src1 is greater than register src2, as
- with the ECMAScript '>' operator, and then jumps to offset
- target from the current instruction, if and only if the
- result of the comparison is false.
- */
- JSValue src1 = callFrame->r(vPC[1].u.operand).jsValue();
- JSValue src2 = callFrame->r(vPC[2].u.operand).jsValue();
- int target = vPC[3].u.operand;
-
- bool result = jsLess<false>(callFrame, src2, src1);
- CHECK_FOR_EXCEPTION();
-
- if (!result) {
- vPC += target;
- NEXT_INSTRUCTION();
- }
-
- vPC += OPCODE_LENGTH(op_jngreater);
- NEXT_INSTRUCTION();
- }
- DEFINE_OPCODE(op_jngreatereq) {
- /* jngreatereq src1(r) src2(r) target(offset)
-
- Checks whether register src1 is greater than or equal to
- register src2, as with the ECMAScript '>=' operator,
- and then jumps to offset target from the current instruction,
- if and only if theresult of the comparison is false.
- */
- JSValue src1 = callFrame->r(vPC[1].u.operand).jsValue();
- JSValue src2 = callFrame->r(vPC[2].u.operand).jsValue();
- int target = vPC[3].u.operand;
-
- bool result = jsLessEq<false>(callFrame, src2, src1);
- CHECK_FOR_EXCEPTION();
-
- if (!result) {
- vPC += target;
- NEXT_INSTRUCTION();
- }
-
- vPC += OPCODE_LENGTH(op_jngreatereq);
- NEXT_INSTRUCTION();
- }
- DEFINE_OPCODE(op_switch_imm) {
- /* switch_imm tableIndex(n) defaultOffset(offset) scrutinee(r)
-
- Performs a range checked switch on the scrutinee value, using
- the tableIndex-th immediate switch jump table. If the scrutinee value
- is an immediate number in the range covered by the referenced jump
- table, and the value at jumpTable[scrutinee value] is non-zero, then
- that value is used as the jump offset, otherwise defaultOffset is used.
- */
- int tableIndex = vPC[1].u.operand;
- int defaultOffset = vPC[2].u.operand;
- JSValue scrutinee = callFrame->r(vPC[3].u.operand).jsValue();
- if (scrutinee.isInt32())
- vPC += codeBlock->immediateSwitchJumpTable(tableIndex).offsetForValue(scrutinee.asInt32(), defaultOffset);
- else if (scrutinee.isDouble() && scrutinee.asDouble() == static_cast<int32_t>(scrutinee.asDouble()))
- vPC += codeBlock->immediateSwitchJumpTable(tableIndex).offsetForValue(static_cast<int32_t>(scrutinee.asDouble()), defaultOffset);
- else
- vPC += defaultOffset;
- NEXT_INSTRUCTION();
- }
- DEFINE_OPCODE(op_switch_char) {
- /* switch_char tableIndex(n) defaultOffset(offset) scrutinee(r)
-
- Performs a range checked switch on the scrutinee value, using
- the tableIndex-th character switch jump table. If the scrutinee value
- is a single character string in the range covered by the referenced jump
- table, and the value at jumpTable[scrutinee value] is non-zero, then
- that value is used as the jump offset, otherwise defaultOffset is used.
- */
- int tableIndex = vPC[1].u.operand;
- int defaultOffset = vPC[2].u.operand;
- JSValue scrutinee = callFrame->r(vPC[3].u.operand).jsValue();
- if (!scrutinee.isString())
- vPC += defaultOffset;
- else {
- StringImpl* value = asString(scrutinee)->value(callFrame).impl();
- if (value->length() != 1)
- vPC += defaultOffset;
- else
- vPC += codeBlock->characterSwitchJumpTable(tableIndex).offsetForValue((*value)[0], defaultOffset);
- }
- NEXT_INSTRUCTION();
- }
- DEFINE_OPCODE(op_switch_string) {
- /* switch_string tableIndex(n) defaultOffset(offset) scrutinee(r)
-
- Performs a sparse hashmap based switch on the value in the scrutinee
- register, using the tableIndex-th string switch jump table. If the
- scrutinee value is a string that exists as a key in the referenced
- jump table, then the value associated with the string is used as the
- jump offset, otherwise defaultOffset is used.
- */
- int tableIndex = vPC[1].u.operand;
- int defaultOffset = vPC[2].u.operand;
- JSValue scrutinee = callFrame->r(vPC[3].u.operand).jsValue();
- if (!scrutinee.isString())
- vPC += defaultOffset;
- else
- vPC += codeBlock->stringSwitchJumpTable(tableIndex).offsetForValue(asString(scrutinee)->value(callFrame).impl(), defaultOffset);
- NEXT_INSTRUCTION();
- }
- DEFINE_OPCODE(op_new_func) {
- /* new_func dst(r) func(f)
-
- Constructs a new Function instance from function func and
- the current scope chain using the original Function
- constructor, using the rules for function declarations, and
- puts the result in register dst.
- */
- int dst = vPC[1].u.operand;
- int func = vPC[2].u.operand;
- int shouldCheck = vPC[3].u.operand;
- ASSERT(codeBlock->codeType() != FunctionCode || !codeBlock->needsFullScopeChain() || callFrame->r(codeBlock->activationRegister()).jsValue());
- if (!shouldCheck || !callFrame->r(dst).jsValue())
- callFrame->uncheckedR(dst) = JSValue(JSFunction::create(callFrame, codeBlock->functionDecl(func), callFrame->scope()));
-
- vPC += OPCODE_LENGTH(op_new_func);
- NEXT_INSTRUCTION();
- }
- DEFINE_OPCODE(op_new_func_exp) {
- /* new_func_exp dst(r) func(f)
-
- Constructs a new Function instance from function func and
- the current scope chain using the original Function
- constructor, using the rules for function expressions, and
- puts the result in register dst.
- */
- int dst = vPC[1].u.operand;
- int funcIndex = vPC[2].u.operand;
-
- ASSERT(codeBlock->codeType() != FunctionCode || !codeBlock->needsFullScopeChain() || callFrame->r(codeBlock->activationRegister()).jsValue());
- FunctionExecutable* function = codeBlock->functionExpr(funcIndex);
- JSFunction* func = JSFunction::create(callFrame, function, callFrame->scope());
-
- callFrame->uncheckedR(dst) = JSValue(func);
-
- vPC += OPCODE_LENGTH(op_new_func_exp);
- NEXT_INSTRUCTION();
- }
- DEFINE_OPCODE(op_call_eval) {
- /* call_eval func(r) argCount(n) registerOffset(n)
-
- Call a function named "eval" with no explicit "this" value
- (which may therefore be the eval operator). If register
- thisVal is the global object, and register func contains
- that global object's original global eval function, then
- perform the eval operator in local scope (interpreting
- the argument registers as for the "call"
- opcode). Otherwise, act exactly as the "call" opcode would.
- */
-
- int func = vPC[1].u.operand;
- int argCount = vPC[2].u.operand;
- int registerOffset = vPC[3].u.operand;
-
- ASSERT(codeBlock->codeType() != FunctionCode || !codeBlock->needsFullScopeChain() || callFrame->r(codeBlock->activationRegister()).jsValue());
- JSValue funcVal = callFrame->r(func).jsValue();
-
- if (isHostFunction(funcVal, globalFuncEval)) {
- CallFrame* newCallFrame = CallFrame::create(callFrame->registers() + registerOffset);
- newCallFrame->init(0, vPC + OPCODE_LENGTH(op_call_eval), callFrame->scope(), callFrame, argCount, jsCast<JSFunction*>(funcVal));
-
- JSValue result = eval(newCallFrame);
- if ((exceptionValue = globalData->exception))
- goto vm_throw;
- functionReturnValue = result;
-
- vPC += OPCODE_LENGTH(op_call_eval);
- NEXT_INSTRUCTION();
- }
-
- // We didn't find the blessed version of eval, so process this
- // instruction as a normal function call.
- // fall through to op_call
- }
- DEFINE_OPCODE(op_call) {
- /* call func(r) argCount(n) registerOffset(n)
-
- Perform a function call.
-
- registerOffset is the distance the callFrame pointer should move
- before the VM initializes the new call frame's header.
-
- dst is where op_ret should store its result.
- */
-
- int func = vPC[1].u.operand;
- int argCount = vPC[2].u.operand;
- int registerOffset = vPC[3].u.operand;
-
- JSValue v = callFrame->r(func).jsValue();
-
- CallData callData;
- CallType callType = getCallData(v, callData);
-
- if (callType == CallTypeJS) {
- JSScope* callDataScope = callData.js.scope;
-
- JSObject* error = callData.js.functionExecutable->compileForCall(callFrame, callDataScope);
- if (UNLIKELY(!!error)) {
- exceptionValue = error;
- goto vm_throw;
- }
-
- CallFrame* previousCallFrame = callFrame;
- CodeBlock* newCodeBlock = &callData.js.functionExecutable->generatedBytecodeForCall();
- callFrame = slideRegisterWindowForCall(newCodeBlock, registerFile, callFrame, registerOffset, argCount);
- if (UNLIKELY(!callFrame)) {
- callFrame = previousCallFrame;
- exceptionValue = createStackOverflowError(callFrame);
- goto vm_throw;
- }
-
- callFrame->init(newCodeBlock, vPC + OPCODE_LENGTH(op_call), callDataScope, previousCallFrame, argCount, jsCast<JSFunction*>(v));
- codeBlock = newCodeBlock;
- ASSERT(codeBlock == callFrame->codeBlock());
- *topCallFrameSlot = callFrame;
- vPC = newCodeBlock->instructions().begin();
-
-#if ENABLE(OPCODE_STATS)
- OpcodeStats::resetLastInstruction();
-#endif
-
- NEXT_INSTRUCTION();
- }
-
- if (callType == CallTypeHost) {
- JSScope* scope = callFrame->scope();
- CallFrame* newCallFrame = CallFrame::create(callFrame->registers() + registerOffset);
- newCallFrame->init(0, vPC + OPCODE_LENGTH(op_call), scope, callFrame, argCount, asObject(v));
- JSValue returnValue;
- {
- *topCallFrameSlot = newCallFrame;
- SamplingTool::HostCallRecord callRecord(m_sampler.get());
- returnValue = JSValue::decode(callData.native.function(newCallFrame));
- *topCallFrameSlot = callFrame;
- }
- CHECK_FOR_EXCEPTION();
-
- functionReturnValue = returnValue;
-
- vPC += OPCODE_LENGTH(op_call);
- NEXT_INSTRUCTION();
- }
-
- ASSERT(callType == CallTypeNone);
-
- exceptionValue = createNotAFunctionError(callFrame, v);
- goto vm_throw;
- }
- DEFINE_OPCODE(op_call_varargs) {
- /* call_varargs callee(r) thisValue(r) arguments(r) firstFreeRegister(n)
-
- Perform a function call with a dynamic set of arguments.
-
- registerOffset is the distance the callFrame pointer should move
- before the VM initializes the new call frame's header, excluding
- space for arguments.
-
- dst is where op_ret should store its result.
- */
-
- JSValue v = callFrame->r(vPC[1].u.operand).jsValue();
- JSValue thisValue = callFrame->r(vPC[2].u.operand).jsValue();
- JSValue arguments = callFrame->r(vPC[3].u.operand).jsValue();
- int firstFreeRegister = vPC[4].u.operand;
-
- CallFrame* newCallFrame = loadVarargs(callFrame, registerFile, thisValue, arguments, firstFreeRegister);
- if ((exceptionValue = globalData->exception))
- goto vm_throw;
- int argCount = newCallFrame->argumentCountIncludingThis();
-
- CallData callData;
- CallType callType = getCallData(v, callData);
-
- if (callType == CallTypeJS) {
- JSScope* callDataScope = callData.js.scope;
-
- JSObject* error = callData.js.functionExecutable->compileForCall(callFrame, callDataScope);
- if (UNLIKELY(!!error)) {
- exceptionValue = error;
- goto vm_throw;
- }
-
- CodeBlock* newCodeBlock = &callData.js.functionExecutable->generatedBytecodeForCall();
- newCallFrame = slideRegisterWindowForCall(newCodeBlock, registerFile, newCallFrame, 0, argCount);
- if (UNLIKELY(!newCallFrame)) {
- exceptionValue = createStackOverflowError(callFrame);
- goto vm_throw;
- }
-
- newCallFrame->init(newCodeBlock, vPC + OPCODE_LENGTH(op_call_varargs), callDataScope, callFrame, argCount, jsCast<JSFunction*>(v));
- codeBlock = newCodeBlock;
- callFrame = newCallFrame;
- ASSERT(codeBlock == callFrame->codeBlock());
- *topCallFrameSlot = callFrame;
- vPC = newCodeBlock->instructions().begin();
-
-#if ENABLE(OPCODE_STATS)
- OpcodeStats::resetLastInstruction();
-#endif
-
- NEXT_INSTRUCTION();
- }
-
- if (callType == CallTypeHost) {
- JSScope* scope = callFrame->scope();
- newCallFrame->init(0, vPC + OPCODE_LENGTH(op_call_varargs), scope, callFrame, argCount, asObject(v));
-
- JSValue returnValue;
- {
- *topCallFrameSlot = newCallFrame;
- SamplingTool::HostCallRecord callRecord(m_sampler.get());
- returnValue = JSValue::decode(callData.native.function(newCallFrame));
- *topCallFrameSlot = callFrame;
- }
- CHECK_FOR_EXCEPTION();
-
- functionReturnValue = returnValue;
-
- vPC += OPCODE_LENGTH(op_call_varargs);
- NEXT_INSTRUCTION();
- }
-
- ASSERT(callType == CallTypeNone);
-
- exceptionValue = createNotAFunctionError(callFrame, v);
- goto vm_throw;
- }
- DEFINE_OPCODE(op_tear_off_activation) {
- /* tear_off_activation activation(r)
-
- Copy locals and named parameters from the register file to the heap.
- Point the bindings in 'activation' to this new backing store.
-
- This opcode appears before op_ret in functions that require full scope chains.
- */
-
- int activation = vPC[1].u.operand;
- ASSERT(codeBlock->needsFullScopeChain());
- JSValue activationValue = callFrame->r(activation).jsValue();
- if (activationValue)
- asActivation(activationValue)->tearOff(*globalData);
-
- vPC += OPCODE_LENGTH(op_tear_off_activation);
- NEXT_INSTRUCTION();
- }
- DEFINE_OPCODE(op_tear_off_arguments) {
- /* tear_off_arguments arguments(r) activation(r)
-
- Copy named parameters from the register file to the heap. Point the
- bindings in 'arguments' to this new backing store. (If 'activation'
- was also copied to the heap, 'arguments' will point to its storage.)
-
- This opcode appears before op_ret in functions that don't require full
- scope chains, but do use 'arguments'.
- */
-
- int arguments = vPC[1].u.operand;
- int activation = vPC[2].u.operand;
- ASSERT(codeBlock->usesArguments());
- if (JSValue argumentsValue = callFrame->r(unmodifiedArgumentsRegister(arguments)).jsValue()) {
- if (JSValue activationValue = callFrame->r(activation).jsValue())
- asArguments(argumentsValue)->didTearOffActivation(callFrame, asActivation(activationValue));
- else
- asArguments(argumentsValue)->tearOff(callFrame);
- }
-
- vPC += OPCODE_LENGTH(op_tear_off_arguments);
- NEXT_INSTRUCTION();
- }
- DEFINE_OPCODE(op_ret) {
- /* ret result(r)
-
- Return register result as the return value of the current
- function call, writing it into functionReturnValue.
- In addition, unwind one call frame and restore the scope
- chain, code block instruction pointer and register base
- to those of the calling function.
- */
-
- int result = vPC[1].u.operand;
-
- JSValue returnValue = callFrame->r(result).jsValue();
-
- vPC = callFrame->returnVPC();
- callFrame = callFrame->callerFrame();
-
- if (callFrame->hasHostCallFrameFlag())
- return returnValue;
-
- *topCallFrameSlot = callFrame;
- functionReturnValue = returnValue;
- codeBlock = callFrame->codeBlock();
- ASSERT(codeBlock == callFrame->codeBlock());
-
- NEXT_INSTRUCTION();
- }
- DEFINE_OPCODE(op_call_put_result) {
- /* op_call_put_result result(r)
-
- Move call result from functionReturnValue to caller's
- expected return value register.
- */
-
- callFrame->uncheckedR(vPC[1].u.operand) = functionReturnValue;
-
- vPC += OPCODE_LENGTH(op_call_put_result);
- NEXT_INSTRUCTION();
- }
- DEFINE_OPCODE(op_ret_object_or_this) {
- /* ret result(r)
-
- Return register result as the return value of the current
- function call, writing it into the caller's expected return
- value register. In addition, unwind one call frame and
- restore the scope chain, code block instruction pointer and
- register base to those of the calling function.
- */
-
- int result = vPC[1].u.operand;
-
- JSValue returnValue = callFrame->r(result).jsValue();
-
- if (UNLIKELY(!returnValue.isObject()))
- returnValue = callFrame->r(vPC[2].u.operand).jsValue();
-
- vPC = callFrame->returnVPC();
- callFrame = callFrame->callerFrame();
-
- if (callFrame->hasHostCallFrameFlag())
- return returnValue;
-
- *topCallFrameSlot = callFrame;
- functionReturnValue = returnValue;
- codeBlock = callFrame->codeBlock();
- ASSERT(codeBlock == callFrame->codeBlock());
-
- NEXT_INSTRUCTION();
- }
- DEFINE_OPCODE(op_enter) {
- /* enter
-
- Initializes local variables to undefined. If the code block requires
- an activation, enter_with_activation is used instead.
-
- This opcode appears only at the beginning of a code block.
- */
-
- size_t i = 0;
- for (size_t count = codeBlock->m_numVars; i < count; ++i)
- callFrame->uncheckedR(i) = jsUndefined();
-
- vPC += OPCODE_LENGTH(op_enter);
- NEXT_INSTRUCTION();
- }
- DEFINE_OPCODE(op_create_activation) {
- /* create_activation dst(r)
-
- If the activation object for this callframe has not yet been created,
- this creates it and writes it back to dst.
- */
-
- int activationReg = vPC[1].u.operand;
- if (!callFrame->r(activationReg).jsValue()) {
- JSActivation* activation = JSActivation::create(*globalData, callFrame, static_cast<FunctionExecutable*>(codeBlock->ownerExecutable()));
- callFrame->r(activationReg) = JSValue(activation);
- callFrame->setScope(activation);
- }
- vPC += OPCODE_LENGTH(op_create_activation);
- NEXT_INSTRUCTION();
- }
- DEFINE_OPCODE(op_create_this) {
- /* op_create_this this(r) proto(r)
-
- Allocate an object as 'this', fr use in construction.
-
- This opcode should only be used at the beginning of a code
- block.
- */
-
- int thisRegister = vPC[1].u.operand;
-
- JSFunction* constructor = jsCast<JSFunction*>(callFrame->callee());
-#if !ASSERT_DISABLED
- ConstructData constructData;
- ASSERT(constructor->methodTable()->getConstructData(constructor, constructData) == ConstructTypeJS);
-#endif
-
- Structure* structure = constructor->cachedInheritorID(callFrame);
- callFrame->uncheckedR(thisRegister) = constructEmptyObject(callFrame, structure);
-
- vPC += OPCODE_LENGTH(op_create_this);
- NEXT_INSTRUCTION();
- }
- DEFINE_OPCODE(op_convert_this) {
- /* convert_this this(r)
-
- Takes the value in the 'this' register, converts it to a
- value that is suitable for use as the 'this' value, and
- stores it in the 'this' register. This opcode is emitted
- to avoid doing the conversion in the caller unnecessarily.
-
- This opcode should only be used at the beginning of a code
- block.
- */
-
- int thisRegister = vPC[1].u.operand;
- JSValue thisVal = callFrame->r(thisRegister).jsValue();
- if (thisVal.isPrimitive())
- callFrame->uncheckedR(thisRegister) = JSValue(thisVal.toThisObject(callFrame));
-
- vPC += OPCODE_LENGTH(op_convert_this);
- NEXT_INSTRUCTION();
- }
- DEFINE_OPCODE(op_init_lazy_reg) {
- /* init_lazy_reg dst(r)
-
- Initialises dst(r) to JSValue().
-
- This opcode appears only at the beginning of a code block.
- */
- int dst = vPC[1].u.operand;
-
- callFrame->uncheckedR(dst) = JSValue();
- vPC += OPCODE_LENGTH(op_init_lazy_reg);
- NEXT_INSTRUCTION();
- }
- DEFINE_OPCODE(op_create_arguments) {
- /* create_arguments dst(r)
-
- Creates the 'arguments' object and places it in both the
- 'arguments' call frame slot and the local 'arguments'
- register, if it has not already been initialised.
- */
-
- int dst = vPC[1].u.operand;
-
- if (!callFrame->r(dst).jsValue()) {
- Arguments* arguments = Arguments::create(*globalData, callFrame);
- callFrame->uncheckedR(dst) = JSValue(arguments);
- callFrame->uncheckedR(unmodifiedArgumentsRegister(dst)) = JSValue(arguments);
- }
- vPC += OPCODE_LENGTH(op_create_arguments);
- NEXT_INSTRUCTION();
- }
- DEFINE_OPCODE(op_construct) {
- /* construct func(r) argCount(n) registerOffset(n) proto(r) thisRegister(r)
-
- Invoke register "func" as a constructor. For JS
- functions, the calling convention is exactly as for the
- "call" opcode, except that the "this" value is a newly
- created Object. For native constructors, no "this"
- value is passed. In either case, the argCount and registerOffset
- registers are interpreted as for the "call" opcode.
-
- Register proto must contain the prototype property of
- register func. This is to enable polymorphic inline
- caching of this lookup.
- */
-
- int func = vPC[1].u.operand;
- int argCount = vPC[2].u.operand;
- int registerOffset = vPC[3].u.operand;
-
- JSValue v = callFrame->r(func).jsValue();
-
- ConstructData constructData;
- ConstructType constructType = getConstructData(v, constructData);
-
- if (constructType == ConstructTypeJS) {
- JSScope* callDataScope = constructData.js.scope;
-
- JSObject* error = constructData.js.functionExecutable->compileForConstruct(callFrame, callDataScope);
- if (UNLIKELY(!!error)) {
- exceptionValue = error;
- goto vm_throw;
- }
-
- CallFrame* previousCallFrame = callFrame;
- CodeBlock* newCodeBlock = &constructData.js.functionExecutable->generatedBytecodeForConstruct();
- callFrame = slideRegisterWindowForCall(newCodeBlock, registerFile, callFrame, registerOffset, argCount);
- if (UNLIKELY(!callFrame)) {
- callFrame = previousCallFrame;
- exceptionValue = createStackOverflowError(callFrame);
- goto vm_throw;
- }
-
- callFrame->init(newCodeBlock, vPC + OPCODE_LENGTH(op_construct), callDataScope, previousCallFrame, argCount, jsCast<JSFunction*>(v));
- codeBlock = newCodeBlock;
- *topCallFrameSlot = callFrame;
- vPC = newCodeBlock->instructions().begin();
-#if ENABLE(OPCODE_STATS)
- OpcodeStats::resetLastInstruction();
-#endif
-
- NEXT_INSTRUCTION();
- }
-
- if (constructType == ConstructTypeHost) {
- JSScope* scope = callFrame->scope();
- CallFrame* newCallFrame = CallFrame::create(callFrame->registers() + registerOffset);
- newCallFrame->init(0, vPC + OPCODE_LENGTH(op_construct), scope, callFrame, argCount, asObject(v));
-
- JSValue returnValue;
- {
- *topCallFrameSlot = newCallFrame;
- SamplingTool::HostCallRecord callRecord(m_sampler.get());
- returnValue = JSValue::decode(constructData.native.function(newCallFrame));
- *topCallFrameSlot = callFrame;
- }
- CHECK_FOR_EXCEPTION();
- functionReturnValue = returnValue;
-
- vPC += OPCODE_LENGTH(op_construct);
- NEXT_INSTRUCTION();
- }
-
- ASSERT(constructType == ConstructTypeNone);
-
- exceptionValue = createNotAConstructorError(callFrame, v);
- goto vm_throw;
- }
- DEFINE_OPCODE(op_strcat) {
- /* strcat dst(r) src(r) count(n)
-
- Construct a new String instance using the original
- constructor, and puts the result in register dst.
- The string will be the result of concatenating count
- strings with values taken from registers starting at
- register src.
- */
- int dst = vPC[1].u.operand;
- int src = vPC[2].u.operand;
- int count = vPC[3].u.operand;
-
- callFrame->uncheckedR(dst) = concatenateStrings(callFrame, &callFrame->registers()[src], count);
- CHECK_FOR_EXCEPTION();
- vPC += OPCODE_LENGTH(op_strcat);
-
- NEXT_INSTRUCTION();
- }
- DEFINE_OPCODE(op_to_primitive) {
- int dst = vPC[1].u.operand;
- int src = vPC[2].u.operand;
-
- callFrame->uncheckedR(dst) = callFrame->r(src).jsValue().toPrimitive(callFrame);
- vPC += OPCODE_LENGTH(op_to_primitive);
-
- NEXT_INSTRUCTION();
- }
- DEFINE_OPCODE(op_push_with_scope) {
- /* push_with_scope scope(r)
-
- Converts register scope to object, and pushes it onto the top
- of the scope chain.
- */
- int scope = vPC[1].u.operand;
- JSValue v = callFrame->r(scope).jsValue();
- JSObject* o = v.toObject(callFrame);
- CHECK_FOR_EXCEPTION();
-
- callFrame->setScope(JSWithScope::create(callFrame, o));
-
- vPC += OPCODE_LENGTH(op_push_with_scope);
- NEXT_INSTRUCTION();
- }
- DEFINE_OPCODE(op_pop_scope) {
- /* pop_scope
-
- Removes the top item from the current scope chain.
- */
- callFrame->setScope(callFrame->scope()->next());
-
- vPC += OPCODE_LENGTH(op_pop_scope);
- NEXT_INSTRUCTION();
- }
- DEFINE_OPCODE(op_get_pnames) {
- /* get_pnames dst(r) base(r) i(n) size(n) breakTarget(offset)
-
- Creates a property name list for register base and puts it
- in register dst, initializing i and size for iteration. If
- base is undefined or null, jumps to breakTarget.
- */
- int dst = vPC[1].u.operand;
- int base = vPC[2].u.operand;
- int i = vPC[3].u.operand;
- int size = vPC[4].u.operand;
- int breakTarget = vPC[5].u.operand;
-
- JSValue v = callFrame->r(base).jsValue();
- if (v.isUndefinedOrNull()) {
- vPC += breakTarget;
- NEXT_INSTRUCTION();
- }
-
- JSObject* o = v.toObject(callFrame);
- Structure* structure = o->structure();
- JSPropertyNameIterator* jsPropertyNameIterator = structure->enumerationCache();
- if (!jsPropertyNameIterator || jsPropertyNameIterator->cachedPrototypeChain() != structure->prototypeChain(callFrame))
- jsPropertyNameIterator = JSPropertyNameIterator::create(callFrame, o);
-
- callFrame->uncheckedR(dst) = jsPropertyNameIterator;
- callFrame->uncheckedR(base) = JSValue(o);
- callFrame->uncheckedR(i) = Register::withInt(0);
- callFrame->uncheckedR(size) = Register::withInt(jsPropertyNameIterator->size());
- vPC += OPCODE_LENGTH(op_get_pnames);
- NEXT_INSTRUCTION();
- }
- DEFINE_OPCODE(op_next_pname) {
- /* next_pname dst(r) base(r) i(n) size(n) iter(r) target(offset)
-
- Copies the next name from the property name list in
- register iter to dst, then jumps to offset target. If there are no
- names left, invalidates the iterator and continues to the next
- instruction.
- */
- int dst = vPC[1].u.operand;
- int base = vPC[2].u.operand;
- int i = vPC[3].u.operand;
- int size = vPC[4].u.operand;
- int iter = vPC[5].u.operand;
- int target = vPC[6].u.operand;
-
- JSPropertyNameIterator* it = callFrame->r(iter).propertyNameIterator();
- while (callFrame->r(i).i() != callFrame->r(size).i()) {
- JSValue key = it->get(callFrame, asObject(callFrame->r(base).jsValue()), callFrame->r(i).i());
- CHECK_FOR_EXCEPTION();
- callFrame->uncheckedR(i) = Register::withInt(callFrame->r(i).i() + 1);
- if (key) {
- CHECK_FOR_TIMEOUT();
- callFrame->uncheckedR(dst) = key;
- vPC += target;
- NEXT_INSTRUCTION();
- }
- }
-
- vPC += OPCODE_LENGTH(op_next_pname);
- NEXT_INSTRUCTION();
- }
- DEFINE_OPCODE(op_jmp_scopes) {
- /* jmp_scopes count(n) target(offset)
-
- Removes the a number of items from the current scope chain
- specified by immediate number count, then jumps to offset
- target.
- */
- int count = vPC[1].u.operand;
- int target = vPC[2].u.operand;
-
- JSScope* tmp = callFrame->scope();
- while (count--)
- tmp = tmp->next();
- callFrame->setScope(tmp);
-
- vPC += target;
- NEXT_INSTRUCTION();
- }
-#if ENABLE(COMPUTED_GOTO_CLASSIC_INTERPRETER)
- // Appease GCC
- goto *(&&skip_new_scope);
-#endif
- DEFINE_OPCODE(op_push_name_scope) {
- /* new_scope property(id) value(r) attributes(unsigned)
-
- Constructs a name scope of the form { property<attributes>: value },
- and pushes it onto the scope chain.
- */
- callFrame->setScope(createNameScope(callFrame, vPC));
-
- vPC += OPCODE_LENGTH(op_push_name_scope);
- NEXT_INSTRUCTION();
- }
-#if ENABLE(COMPUTED_GOTO_CLASSIC_INTERPRETER)
- skip_new_scope:
-#endif
- DEFINE_OPCODE(op_catch) {
- /* catch ex(r)
-
- Retrieves the VM's current exception and puts it in register
- ex. This is only valid after an exception has been raised,
- and usually forms the beginning of an exception handler.
- */
- ASSERT(exceptionValue);
- ASSERT(!globalData->exception);
- int ex = vPC[1].u.operand;
- callFrame->uncheckedR(ex) = exceptionValue;
- exceptionValue = JSValue();
-
- vPC += OPCODE_LENGTH(op_catch);
- NEXT_INSTRUCTION();
- }
- DEFINE_OPCODE(op_throw) {
- /* throw ex(r)
-
- Throws register ex as an exception. This involves three
- steps: first, it is set as the current exception in the
- VM's internal state, then the stack is unwound until an
- exception handler or a native code boundary is found, and
- then control resumes at the exception handler if any or
- else the script returns control to the nearest native caller.
- */
-
- int ex = vPC[1].u.operand;
- exceptionValue = callFrame->r(ex).jsValue();
-
- handler = throwException(callFrame, exceptionValue, vPC - codeBlock->instructions().begin());
- if (!handler)
- return throwError(callFrame, exceptionValue);
-
- codeBlock = callFrame->codeBlock();
- vPC = codeBlock->instructions().begin() + handler->target;
- NEXT_INSTRUCTION();
- }
- DEFINE_OPCODE(op_throw_reference_error) {
- /* op_throw_reference_error message(k)
-
- Constructs a new reference Error instance using the
- original constructor, using constant message as the
- message string. The result is thrown.
- */
- String message = callFrame->r(vPC[1].u.operand).jsValue().toString(callFrame)->value(callFrame);
- exceptionValue = JSValue(createReferenceError(callFrame, message));
- goto vm_throw;
- }
- DEFINE_OPCODE(op_end) {
- /* end result(r)
-
- Return register result as the value of a global or eval
- program. Return control to the calling native code.
- */
-
- int result = vPC[1].u.operand;
- return callFrame->r(result).jsValue();
- }
- DEFINE_OPCODE(op_put_getter_setter) {
- /* put_getter_setter base(r) property(id) getter(r) setter(r)
-
- Puts accessor descriptor to register base as the named
- identifier property. Base and function may be objects
- or undefined, this op should only be used for accessors
- defined in object literal form.
-
- Unlike many opcodes, this one does not write any output to
- the register file.
- */
- int base = vPC[1].u.operand;
- int property = vPC[2].u.operand;
- int getterReg = vPC[3].u.operand;
- int setterReg = vPC[4].u.operand;
-
- ASSERT(callFrame->r(base).jsValue().isObject());
- JSObject* baseObj = asObject(callFrame->r(base).jsValue());
- Identifier& ident = codeBlock->identifier(property);
-
- GetterSetter* accessor = GetterSetter::create(callFrame);
-
- JSValue getter = callFrame->r(getterReg).jsValue();
- JSValue setter = callFrame->r(setterReg).jsValue();
- ASSERT(getter.isObject() || getter.isUndefined());
- ASSERT(setter.isObject() || setter.isUndefined());
- ASSERT(getter.isObject() || setter.isObject());
-
- if (!getter.isUndefined())
- accessor->setGetter(callFrame->globalData(), asObject(getter));
- if (!setter.isUndefined())
- accessor->setSetter(callFrame->globalData(), asObject(setter));
- baseObj->putDirectAccessor(callFrame, ident, accessor, Accessor);
-
- vPC += OPCODE_LENGTH(op_put_getter_setter);
- NEXT_INSTRUCTION();
- }
- DEFINE_OPCODE(op_method_check) {
- vPC++;
- NEXT_INSTRUCTION();
- }
- DEFINE_OPCODE(op_debug) {
- /* debug debugHookID(n) firstLine(n) lastLine(n) column(n)
-
- Notifies the debugger of the current state of execution. This opcode
- is only generated while the debugger is attached.
- */
- int debugHookID = vPC[1].u.operand;
- int firstLine = vPC[2].u.operand;
- int lastLine = vPC[3].u.operand;
- int column = vPC[4].u.operand;
-
-
- debug(callFrame, static_cast<DebugHookID>(debugHookID), firstLine, lastLine, column);
-
- vPC += OPCODE_LENGTH(op_debug);
- NEXT_INSTRUCTION();
- }
- DEFINE_OPCODE(op_profile_will_call) {
- /* op_profile_will_call function(r)
-
- Notifies the profiler of the beginning of a function call. This opcode
- is only generated if developer tools are enabled.
- */
- int function = vPC[1].u.operand;
-
- if (Profiler* profiler = globalData->enabledProfiler())
- profiler->willExecute(callFrame, callFrame->r(function).jsValue());
-
- vPC += OPCODE_LENGTH(op_profile_will_call);
- NEXT_INSTRUCTION();
- }
- DEFINE_OPCODE(op_profile_did_call) {
- /* op_profile_did_call function(r)
-
- Notifies the profiler of the end of a function call. This opcode
- is only generated if developer tools are enabled.
- */
- int function = vPC[1].u.operand;
-
- if (Profiler* profiler = globalData->enabledProfiler())
- profiler->didExecute(callFrame, callFrame->r(function).jsValue());
-
- vPC += OPCODE_LENGTH(op_profile_did_call);
- NEXT_INSTRUCTION();
- }
- vm_throw: {
- globalData->exception = JSValue();
- if (!tickCount) {
- // The exceptionValue is a lie! (GCC produces bad code for reasons I
- // cannot fathom if we don't assign to the exceptionValue before branching)
- exceptionValue = createInterruptedExecutionException(globalData);
- }
- JSGlobalObject* globalObject = callFrame->lexicalGlobalObject();
- handler = throwException(callFrame, exceptionValue, vPC - codeBlock->instructions().begin());
- if (!handler) {
- // Can't use the callframe at this point as the scopechain, etc have
- // been released.
- return throwError(globalObject->globalExec(), exceptionValue);
- }
-
- codeBlock = callFrame->codeBlock();
- vPC = codeBlock->instructions().begin() + handler->target;
- NEXT_INSTRUCTION();
- }
- }
-#if !ENABLE(COMPUTED_GOTO_CLASSIC_INTERPRETER)
- } // iterator loop ends
-#endif
- #undef NEXT_INSTRUCTION
- #undef DEFINE_OPCODE
- #undef CHECK_FOR_EXCEPTION
- #undef CHECK_FOR_TIMEOUT
-#endif // ENABLE(CLASSIC_INTERPRETER)
-}
-
-#endif // !ENABLE(LLINT_C_LOOP)
-
-
JSValue Interpreter::retrieveArgumentsFromVMCode(CallFrame* callFrame, JSFunction* function) const
{
CallFrame* functionCallFrame = findFunctionCallFrameFromVMCode(callFrame, function);
@@ -5159,16 +1342,7 @@ void Interpreter::retrieveLastCaller(CallFrame* callFrame, int& lineNumber, intp
if (!callerCodeBlock)
return;
unsigned bytecodeOffset = 0;
-#if ENABLE(CLASSIC_INTERPRETER)
- if (!callerFrame->globalData().canUseJIT())
- bytecodeOffset = callerCodeBlock->bytecodeOffset(callFrame->returnVPC());
-#if ENABLE(JIT)
- else
- bytecodeOffset = callerCodeBlock->bytecodeOffset(callerFrame, callFrame->returnPC());
-#endif
-#else
bytecodeOffset = callerCodeBlock->bytecodeOffset(callerFrame, callFrame->returnPC());
-#endif
lineNumber = callerCodeBlock->lineNumberForBytecodeOffset(bytecodeOffset - 1);
sourceID = callerCodeBlock->ownerExecutable()->sourceID();
sourceURL = callerCodeBlock->ownerExecutable()->sourceURL();
diff --git a/Source/JavaScriptCore/interpreter/Interpreter.h b/Source/JavaScriptCore/interpreter/Interpreter.h
index 464056bc1..f27ae8206 100644
--- a/Source/JavaScriptCore/interpreter/Interpreter.h
+++ b/Source/JavaScriptCore/interpreter/Interpreter.h
@@ -204,27 +204,14 @@ namespace JSC {
OpcodeID getOpcodeID(Opcode opcode)
{
ASSERT(m_initialized);
-#if ENABLE(COMPUTED_GOTO_OPCODES)
-#if ENABLE(LLINT)
- ASSERT(isOpcode(opcode));
- return m_opcodeIDTable.get(opcode);
-#elif ENABLE(COMPUTED_GOTO_CLASSIC_INTERPRETER)
+#if ENABLE(COMPUTED_GOTO_OPCODES) && ENABLE(LLINT)
ASSERT(isOpcode(opcode));
- if (!m_classicEnabled)
- return static_cast<OpcodeID>(bitwise_cast<uintptr_t>(opcode));
-
return m_opcodeIDTable.get(opcode);
-#endif // ENABLE(COMPUTED_GOTO_CLASSIC_INTERPRETER)
-#else // !ENABLE(COMPUTED_GOTO_OPCODES)
+#else
return opcode;
-#endif // !ENABLE(COMPUTED_GOTO_OPCODES)
+#endif
}
- bool classicEnabled()
- {
- return m_classicEnabled;
- }
-
bool isOpcode(Opcode);
JSValue execute(ProgramExecutable*, CallFrame*, JSObject* thisObj);
@@ -260,15 +247,6 @@ namespace JSC {
void endRepeatCall(CallFrameClosure&);
JSValue execute(CallFrameClosure&);
-#if ENABLE(CLASSIC_INTERPRETER)
- NEVER_INLINE JSScope* createNameScope(CallFrame*, const Instruction* vPC);
-
- void tryCacheGetByID(CallFrame*, CodeBlock*, Instruction*, JSValue baseValue, const Identifier& propertyName, const PropertySlot&);
- void uncacheGetByID(CodeBlock*, Instruction* vPC);
- void tryCachePutByID(CallFrame*, CodeBlock*, Instruction*, JSValue baseValue, const PutPropertySlot&);
- void uncachePutByID(CodeBlock*, Instruction* vPC);
-#endif // ENABLE(CLASSIC_INTERPRETER)
-
NEVER_INLINE bool unwindCallFrame(CallFrame*&, JSValue, unsigned& bytecodeOffset, CodeBlock*&);
static ALWAYS_INLINE CallFrame* slideRegisterWindowForCall(CodeBlock*, RegisterFile*, CallFrame*, size_t registerOffset, int argc);
@@ -291,20 +269,14 @@ namespace JSC {
RegisterFile m_registerFile;
-#if ENABLE(COMPUTED_GOTO_OPCODES)
-#if ENABLE(LLINT)
+#if ENABLE(COMPUTED_GOTO_OPCODES) && ENABLE(LLINT)
Opcode* m_opcodeTable; // Maps OpcodeID => Opcode for compiling
HashMap<Opcode, OpcodeID> m_opcodeIDTable; // Maps Opcode => OpcodeID for decompiling
-#elif ENABLE(COMPUTED_GOTO_CLASSIC_INTERPRETER)
- Opcode m_opcodeTable[numOpcodeIDs]; // Maps OpcodeID => Opcode for compiling
- HashMap<Opcode, OpcodeID> m_opcodeIDTable; // Maps Opcode => OpcodeID for decompiling
#endif
-#endif // ENABLE(COMPUTED_GOTO_OPCODES)
#if !ASSERT_DISABLED
bool m_initialized;
#endif
- bool m_classicEnabled;
};
// This value must not be an object that would require this conversion (WebCore's global object).
diff --git a/Source/JavaScriptCore/jit/ExecutableAllocatorFixedVMPool.cpp b/Source/JavaScriptCore/jit/ExecutableAllocatorFixedVMPool.cpp
index 7a53b8e2e..2123f5a67 100644
--- a/Source/JavaScriptCore/jit/ExecutableAllocatorFixedVMPool.cpp
+++ b/Source/JavaScriptCore/jit/ExecutableAllocatorFixedVMPool.cpp
@@ -54,7 +54,7 @@ public:
: MetaAllocator(jitAllocationGranule) // round up all allocations to 32 bytes
{
m_reservation = PageReservation::reserveWithGuardPages(fixedExecutableMemoryPoolSize, OSAllocator::JSJITCodePages, EXECUTABLE_POOL_WRITABLE, true);
-#if !(ENABLE(CLASSIC_INTERPRETER) || ENABLE(LLINT))
+#if !ENABLE(LLINT)
if (!m_reservation)
CRASH();
#endif
diff --git a/Source/JavaScriptCore/llint/LowLevelInterpreter32_64.asm b/Source/JavaScriptCore/llint/LowLevelInterpreter32_64.asm
index 53da6424b..83abf380c 100644
--- a/Source/JavaScriptCore/llint/LowLevelInterpreter32_64.asm
+++ b/Source/JavaScriptCore/llint/LowLevelInterpreter32_64.asm
@@ -1398,7 +1398,9 @@ _llint_op_put_by_val:
dispatch(5)
.opPutByValEmpty:
- storeb 1, ArrayProfile::m_mayStoreToHole[t3]
+ if VALUE_PROFILER
+ storeb 1, ArrayProfile::m_mayStoreToHole[t3]
+ end
addi 1, ArrayStorage::m_numValuesInVector[t0]
bib t2, -sizeof IndexingHeader + IndexingHeader::m_publicLength[t0], .opPutByValStoreResult
addi 1, t2, t1
diff --git a/Source/JavaScriptCore/llint/LowLevelInterpreter64.asm b/Source/JavaScriptCore/llint/LowLevelInterpreter64.asm
index f4ff5c464..4d614f51f 100644
--- a/Source/JavaScriptCore/llint/LowLevelInterpreter64.asm
+++ b/Source/JavaScriptCore/llint/LowLevelInterpreter64.asm
@@ -1241,7 +1241,9 @@ _llint_op_put_by_val:
dispatch(5)
.opPutByValEmpty:
- storeb 1, ArrayProfile::m_mayStoreToHole[t3]
+ if VALUE_PROFILER
+ storeb 1, ArrayProfile::m_mayStoreToHole[t3]
+ end
addi 1, ArrayStorage::m_numValuesInVector[t0]
bib t2, -sizeof IndexingHeader + IndexingHeader::m_publicLength[t0], .opPutByValStoreResult
addi 1, t2, t1
diff --git a/Source/JavaScriptCore/offlineasm/asm.rb b/Source/JavaScriptCore/offlineasm/asm.rb
index 14d616442..4d44c5e91 100644
--- a/Source/JavaScriptCore/offlineasm/asm.rb
+++ b/Source/JavaScriptCore/offlineasm/asm.rb
@@ -225,7 +225,7 @@ $stderr.puts "offlineasm: Parsing #{asmFile} and #{offsetsFile} and creating ass
begin
configurationList = offsetsAndConfigurationIndex(offsetsFile)
rescue MissingMagicValuesException
- $stderr.puts "offlineasm: No magic values found. Skipping assembly file generation assuming the classic interpreter is enabled."
+ $stderr.puts "offlineasm: No magic values found. Skipping assembly file generation."
exit 0
end
diff --git a/Source/JavaScriptCore/offlineasm/cloop.rb b/Source/JavaScriptCore/offlineasm/cloop.rb
index 9975e0767..b3e319c4d 100644
--- a/Source/JavaScriptCore/offlineasm/cloop.rb
+++ b/Source/JavaScriptCore/offlineasm/cloop.rb
@@ -507,7 +507,7 @@ end
class Instruction
def lowerC_LOOP
$asm.codeOrigin codeOriginString if $enableCodeOriginComments
- $asm.annotation annotation if $enableInstrAnnotations
+ $asm.annotation annotation if $enableInstrAnnotations && (opcode != "cloopDo")
case opcode
when "addi"
@@ -981,6 +981,12 @@ class Instruction
when "cloopCallSlowPath"
cloopEmitCallSlowPath(operands)
+ # For debugging only. This is used to insert instrumentation into the
+ # generated LLIntAssembly.h during llint development only. Do not use
+ # for production code.
+ when "cloopDo"
+ $asm.putc "#{annotation}"
+
else
lowerDefault
end
diff --git a/Source/JavaScriptCore/offlineasm/instructions.rb b/Source/JavaScriptCore/offlineasm/instructions.rb
index d046bee6f..ddb1bb90f 100644
--- a/Source/JavaScriptCore/offlineasm/instructions.rb
+++ b/Source/JavaScriptCore/offlineasm/instructions.rb
@@ -227,6 +227,14 @@ CXX_INSTRUCTIONS =
"cloopCallJSFunction", # operands: callee
"cloopCallNative", # operands: callee
"cloopCallSlowPath", # operands: callTarget, currentFrame, currentPC
+
+ # For debugging only:
+ # Takes no operands but simply emits whatever follows in // comments as
+ # a line of C++ code in the generated LLIntAssembly.h file. This can be
+ # used to insert instrumentation into the interpreter loop to inspect
+ # variables of interest. Do not leave these instructions in production
+ # code.
+ "cloopDo", # no operands
]
INSTRUCTIONS = MACRO_INSTRUCTIONS + X86_INSTRUCTIONS + ARMv7_INSTRUCTIONS + CXX_INSTRUCTIONS
diff --git a/Source/JavaScriptCore/offlineasm/offsets.rb b/Source/JavaScriptCore/offlineasm/offsets.rb
index 627183dc8..d9266d9a3 100644
--- a/Source/JavaScriptCore/offlineasm/offsets.rb
+++ b/Source/JavaScriptCore/offlineasm/offsets.rb
@@ -38,7 +38,6 @@ OFFSET_MAGIC_NUMBERS = [ to32Bit(0xec577ac7), to32Bit(0x0ff5e755) ]
# MissingMagicValuesException
#
# Thrown when magic values are missing from the binary.
-# This is usually an indication that the classic interpreter is enabled.
#
class MissingMagicValuesException < Exception
diff --git a/Source/JavaScriptCore/offlineasm/parser.rb b/Source/JavaScriptCore/offlineasm/parser.rb
index 70b03cf70..76eea522f 100644
--- a/Source/JavaScriptCore/offlineasm/parser.rb
+++ b/Source/JavaScriptCore/offlineasm/parser.rb
@@ -103,7 +103,11 @@ def lex(str, fileName)
annotationType = whitespaceFound ? :local : :global
when /\A\n/
# We've found a '\n'. Emit the last comment recorded if appropriate:
- if $enableInstrAnnotations and annotation
+ # We need to parse annotations regardless of whether the backend does
+ # anything with them or not. This is because the C++ backend may make
+ # use of this for its cloopDo debugging utility even if
+ # enableInstrAnnotations is not enabled.
+ if annotation
result << Annotation.new(CodeOrigin.new(fileName, lineNumber),
annotationType, annotation)
annotation = nil
diff --git a/Source/JavaScriptCore/runtime/Executable.cpp b/Source/JavaScriptCore/runtime/Executable.cpp
index d7327d564..0a453eea0 100644
--- a/Source/JavaScriptCore/runtime/Executable.cpp
+++ b/Source/JavaScriptCore/runtime/Executable.cpp
@@ -231,11 +231,6 @@ JSObject* EvalExecutable::compileInternal(ExecState* exec, JSScope* scope, JITCo
#endif
#if ENABLE(JIT)
-#if ENABLE(CLASSIC_INTERPRETER)
- if (!m_jitCodeForCall)
- Heap::heap(this)->reportExtraMemoryCost(sizeof(*m_evalCodeBlock));
- else
-#endif
Heap::heap(this)->reportExtraMemoryCost(sizeof(*m_evalCodeBlock) + m_jitCodeForCall.size());
#else
Heap::heap(this)->reportExtraMemoryCost(sizeof(*m_evalCodeBlock));
@@ -356,12 +351,7 @@ JSObject* ProgramExecutable::compileInternal(ExecState* exec, JSScope* scope, JI
#endif
#if ENABLE(JIT)
-#if ENABLE(CLASSIC_INTERPRETER)
- if (!m_jitCodeForCall)
- Heap::heap(this)->reportExtraMemoryCost(sizeof(*m_programCodeBlock));
- else
-#endif
- Heap::heap(this)->reportExtraMemoryCost(sizeof(*m_programCodeBlock) + m_jitCodeForCall.size());
+ Heap::heap(this)->reportExtraMemoryCost(sizeof(*m_programCodeBlock) + m_jitCodeForCall.size());
#else
Heap::heap(this)->reportExtraMemoryCost(sizeof(*m_programCodeBlock));
#endif
@@ -534,12 +524,7 @@ JSObject* FunctionExecutable::compileForCallInternal(ExecState* exec, JSScope* s
#endif
#if ENABLE(JIT)
-#if ENABLE(CLASSIC_INTERPRETER)
- if (!m_jitCodeForCall)
- Heap::heap(this)->reportExtraMemoryCost(sizeof(*m_codeBlockForCall));
- else
-#endif
- Heap::heap(this)->reportExtraMemoryCost(sizeof(*m_codeBlockForCall) + m_jitCodeForCall.size());
+ Heap::heap(this)->reportExtraMemoryCost(sizeof(*m_codeBlockForCall) + m_jitCodeForCall.size());
#else
Heap::heap(this)->reportExtraMemoryCost(sizeof(*m_codeBlockForCall));
#endif
@@ -576,11 +561,6 @@ JSObject* FunctionExecutable::compileForConstructInternal(ExecState* exec, JSSco
#endif
#if ENABLE(JIT)
-#if ENABLE(CLASSIC_INTERPRETER)
- if (!m_jitCodeForConstruct)
- Heap::heap(this)->reportExtraMemoryCost(sizeof(*m_codeBlockForConstruct));
- else
-#endif
Heap::heap(this)->reportExtraMemoryCost(sizeof(*m_codeBlockForConstruct) + m_jitCodeForConstruct.size());
#else
Heap::heap(this)->reportExtraMemoryCost(sizeof(*m_codeBlockForConstruct));
diff --git a/Source/JavaScriptCore/runtime/Executable.h b/Source/JavaScriptCore/runtime/Executable.h
index 808c78fba..6eeda3a82 100644
--- a/Source/JavaScriptCore/runtime/Executable.h
+++ b/Source/JavaScriptCore/runtime/Executable.h
@@ -266,7 +266,6 @@ namespace JSC {
#if ENABLE(JIT)
static NativeExecutable* create(JSGlobalData& globalData, MacroAssemblerCodeRef callThunk, NativeFunction function, MacroAssemblerCodeRef constructThunk, NativeFunction constructor, Intrinsic intrinsic)
{
- ASSERT(!globalData.interpreter->classicEnabled());
NativeExecutable* executable;
if (!callThunk) {
executable = new (NotNull, allocateCell<NativeExecutable>(globalData.heap)) NativeExecutable(globalData, function, constructor);
@@ -279,7 +278,7 @@ namespace JSC {
}
#endif
-#if ENABLE(CLASSIC_INTERPRETER) || ENABLE(LLINT_C_LOOP)
+#if ENABLE(LLINT_C_LOOP)
static NativeExecutable* create(JSGlobalData& globalData, NativeFunction function, NativeFunction constructor)
{
ASSERT(!globalData.canUseJIT());
@@ -306,7 +305,6 @@ namespace JSC {
#if ENABLE(JIT)
void finishCreation(JSGlobalData& globalData, JITCode callThunk, JITCode constructThunk, Intrinsic intrinsic)
{
- ASSERT(!globalData.interpreter->classicEnabled());
Base::finishCreation(globalData);
m_jitCodeForCall = callThunk;
m_jitCodeForConstruct = constructThunk;
@@ -316,15 +314,6 @@ namespace JSC {
}
#endif
-#if ENABLE(CLASSIC_INTERPRETER)
- void finishCreation(JSGlobalData& globalData)
- {
- ASSERT(!globalData.canUseJIT());
- Base::finishCreation(globalData);
- m_intrinsic = NoIntrinsic;
- }
-#endif
-
private:
NativeExecutable(JSGlobalData& globalData, NativeFunction function, NativeFunction constructor)
: ExecutableBase(globalData, globalData.nativeExecutableStructure.get(), NUM_PARAMETERS_IS_HOST)
diff --git a/Source/JavaScriptCore/runtime/JSActivation.h b/Source/JavaScriptCore/runtime/JSActivation.h
index 442941335..fa2291813 100644
--- a/Source/JavaScriptCore/runtime/JSActivation.h
+++ b/Source/JavaScriptCore/runtime/JSActivation.h
@@ -84,6 +84,8 @@ namespace JSC {
bool isValidIndex(int) const;
bool isValid(const SymbolTableEntry&) const;
bool isTornOff();
+ int registersOffset();
+ static int registersOffset(SharedSymbolTable*);
protected:
static const unsigned StructureFlags = OverridesGetOwnPropertySlot | OverridesVisitChildren | OverridesGetPropertyNames | Base::StructureFlags;
@@ -99,8 +101,8 @@ namespace JSC {
NEVER_INLINE PropertySlot::GetValueFunc getArgumentsGetter();
static size_t allocationSize(SharedSymbolTable*);
+ static size_t storageOffset();
- int registerOffset();
WriteBarrier<Unknown>* storage(); // captureCount() number of registers.
};
@@ -141,17 +143,17 @@ namespace JSC {
return false;
}
- inline int JSActivation::registerOffset()
+ inline int JSActivation::registersOffset(SharedSymbolTable* symbolTable)
{
- return -symbolTable()->captureStart();
+ return storageOffset() - (symbolTable->captureStart() * sizeof(WriteBarrier<Unknown>));
}
inline void JSActivation::tearOff(JSGlobalData& globalData)
{
ASSERT(!isTornOff());
- int registerOffset = this->registerOffset();
- WriteBarrierBase<Unknown>* dst = storage() + registerOffset;
+ WriteBarrierBase<Unknown>* dst = reinterpret_cast<WriteBarrierBase<Unknown>*>(
+ reinterpret_cast<char*>(this) + registersOffset(symbolTable()));
WriteBarrierBase<Unknown>* src = m_registers;
int captureEnd = symbolTable()->captureEnd();
@@ -164,15 +166,19 @@ namespace JSC {
inline bool JSActivation::isTornOff()
{
- return m_registers == storage() + registerOffset();
+ return m_registers == reinterpret_cast<WriteBarrierBase<Unknown>*>(
+ reinterpret_cast<char*>(this) + registersOffset(symbolTable()));
+ }
+
+ inline size_t JSActivation::storageOffset()
+ {
+ return WTF::roundUpToMultipleOf<sizeof(WriteBarrier<Unknown>)>(sizeof(JSActivation));
}
inline WriteBarrier<Unknown>* JSActivation::storage()
{
return reinterpret_cast<WriteBarrier<Unknown>*>(
- reinterpret_cast<char*>(this) +
- WTF::roundUpToMultipleOf<sizeof(WriteBarrier<Unknown>)>(sizeof(JSActivation))
- );
+ reinterpret_cast<char*>(this) + storageOffset());
}
inline size_t JSActivation::allocationSize(SharedSymbolTable* symbolTable)
diff --git a/Source/JavaScriptCore/runtime/JSGlobalData.cpp b/Source/JavaScriptCore/runtime/JSGlobalData.cpp
index 26f2b8616..e30a7913d 100644
--- a/Source/JavaScriptCore/runtime/JSGlobalData.cpp
+++ b/Source/JavaScriptCore/runtime/JSGlobalData.cpp
@@ -97,7 +97,11 @@ extern const HashTable regExpPrototypeTable;
extern const HashTable stringTable;
extern const HashTable stringConstructorTable;
-#if ENABLE(ASSEMBLER) && (ENABLE(CLASSIC_INTERPRETER) || ENABLE(LLINT))
+// Note: Platform.h will enforce that ENABLE(ASSEMBLER) is true if either
+// ENABLE(JIT) or ENABLE(YARR_JIT) or both are enabled. The code below
+// just checks for ENABLE(JIT) or ENABLE(YARR_JIT) with this premise in mind.
+
+#if ENABLE(ASSEMBLER)
static bool enableAssembler(ExecutableAllocator& executableAllocator)
{
if (!executableAllocator.isValid() || (!Options::useJIT() && !Options::useRegExpJIT()))
@@ -124,7 +128,7 @@ static bool enableAssembler(ExecutableAllocator& executableAllocator)
return true;
#endif
}
-#endif
+#endif // ENABLE(!ASSEMBLER)
JSGlobalData::JSGlobalData(GlobalDataType globalDataType, ThreadStackType threadStackType, HeapType heapType)
:
@@ -180,9 +184,13 @@ JSGlobalData::JSGlobalData(GlobalDataType globalDataType, ThreadStackType thread
, m_timeoutCount(512)
#endif
, m_newStringsSinceLastHashConst(0)
-#if ENABLE(ASSEMBLER) && (ENABLE(CLASSIC_INTERPRETER) || ENABLE(LLINT))
+#if ENABLE(ASSEMBLER)
, m_canUseAssembler(enableAssembler(executableAllocator))
+#endif
+#if ENABLE(JIT)
, m_canUseJIT(m_canUseAssembler && Options::useJIT())
+#endif
+#if ENABLE(YARR_JIT)
, m_canUseRegExpJIT(m_canUseAssembler && Options::useRegExpJIT())
#endif
#if ENABLE(GC_VALIDATION)
@@ -370,10 +378,6 @@ static ThunkGenerator thunkGeneratorForIntrinsic(Intrinsic intrinsic)
NativeExecutable* JSGlobalData::getHostFunction(NativeFunction function, NativeFunction constructor)
{
-#if ENABLE(CLASSIC_INTERPRETER)
- if (!canUseJIT())
- return NativeExecutable::create(*this, function, constructor);
-#endif
return jitStubs->hostFunctionStub(this, function, constructor);
}
NativeExecutable* JSGlobalData::getHostFunction(NativeFunction function, Intrinsic intrinsic)
diff --git a/Source/JavaScriptCore/runtime/JSGlobalData.h b/Source/JavaScriptCore/runtime/JSGlobalData.h
index 68e0e25d1..603f9f82a 100644
--- a/Source/JavaScriptCore/runtime/JSGlobalData.h
+++ b/Source/JavaScriptCore/runtime/JSGlobalData.h
@@ -280,20 +280,18 @@ namespace JSC {
return m_enabledProfiler;
}
-#if !ENABLE(JIT)
- bool canUseJIT() { return false; } // interpreter only
-#elif !ENABLE(CLASSIC_INTERPRETER) && !ENABLE(LLINT)
+#if ENABLE(JIT) && ENABLE(LLINT)
+ bool canUseJIT() { return m_canUseJIT; }
+#elif ENABLE(JIT)
bool canUseJIT() { return true; } // jit only
#else
- bool canUseJIT() { return m_canUseJIT; }
+ bool canUseJIT() { return false; } // interpreter only
#endif
-#if !ENABLE(YARR_JIT)
- bool canUseRegExpJIT() { return false; } // interpreter only
-#elif !ENABLE(CLASSIC_INTERPRETER) && !ENABLE(LLINT)
- bool canUseRegExpJIT() { return true; } // jit only
-#else
+#if ENABLE(YARR_JIT)
bool canUseRegExpJIT() { return m_canUseRegExpJIT; }
+#else
+ bool canUseRegExpJIT() { return false; } // interpreter only
#endif
PrivateName m_inheritorIDKey;
@@ -440,9 +438,13 @@ namespace JSC {
JSGlobalData(GlobalDataType, ThreadStackType, HeapType);
static JSGlobalData*& sharedInstanceInternal();
void createNativeThunk();
-#if ENABLE(ASSEMBLER) && (ENABLE(CLASSIC_INTERPRETER) || ENABLE(LLINT))
+#if ENABLE(ASSEMBLER)
bool m_canUseAssembler;
+#endif
+#if ENABLE(JIT)
bool m_canUseJIT;
+#endif
+#if ENABLE(YARR_JIT)
bool m_canUseRegExpJIT;
#endif
#if ENABLE(GC_VALIDATION)
diff --git a/Source/JavaScriptCore/runtime/JSGlobalObject.cpp b/Source/JavaScriptCore/runtime/JSGlobalObject.cpp
index 3d643a266..b0a0e8122 100644
--- a/Source/JavaScriptCore/runtime/JSGlobalObject.cpp
+++ b/Source/JavaScriptCore/runtime/JSGlobalObject.cpp
@@ -373,7 +373,7 @@ void ObjectsWithBrokenIndexingFinder::operator()(JSCell* cell)
// a different global object that have prototypes from our global object.
bool foundGlobalObject = false;
for (JSObject* current = object; ;) {
- if (current->unwrappedGlobalObject() == m_globalObject) {
+ if (current->globalObject() == m_globalObject) {
foundGlobalObject = true;
break;
}
diff --git a/Source/JavaScriptCore/runtime/JSGlobalObjectFunctions.cpp b/Source/JavaScriptCore/runtime/JSGlobalObjectFunctions.cpp
index e9a3e2836..c85965060 100644
--- a/Source/JavaScriptCore/runtime/JSGlobalObjectFunctions.cpp
+++ b/Source/JavaScriptCore/runtime/JSGlobalObjectFunctions.cpp
@@ -498,8 +498,8 @@ static double parseFloat(const String& s)
EncodedJSValue JSC_HOST_CALL globalFuncEval(ExecState* exec)
{
JSObject* thisObject = exec->hostThisValue().toThisObject(exec);
- JSObject* unwrappedObject = thisObject->unwrappedObject();
- if (!unwrappedObject->isGlobalObject() || jsCast<JSGlobalObject*>(unwrappedObject)->evalFunction() != exec->callee())
+ JSGlobalObject* calleeGlobalObject = exec->callee()->globalObject();
+ if (thisObject != exec->callee()->globalObject()->globalThis())
return throwVMError(exec, createEvalError(exec, ASCIILiteral("The \"this\" value passed to eval must be the global object from which eval originated")));
JSValue x = exec->argument(0);
@@ -519,11 +519,11 @@ EncodedJSValue JSC_HOST_CALL globalFuncEval(ExecState* exec)
}
EvalExecutable* eval = EvalExecutable::create(exec, makeSource(s), false);
- JSObject* error = eval->compile(exec, jsCast<JSGlobalObject*>(unwrappedObject));
+ JSObject* error = eval->compile(exec, calleeGlobalObject);
if (error)
return throwVMError(exec, error);
- return JSValue::encode(exec->interpreter()->execute(eval, exec, thisObject, jsCast<JSGlobalObject*>(unwrappedObject)));
+ return JSValue::encode(exec->interpreter()->execute(eval, exec, thisObject, calleeGlobalObject));
}
EncodedJSValue JSC_HOST_CALL globalFuncParseInt(ExecState* exec)
diff --git a/Source/JavaScriptCore/runtime/JSObject.cpp b/Source/JavaScriptCore/runtime/JSObject.cpp
index acff8a6ae..7bf12b67e 100644
--- a/Source/JavaScriptCore/runtime/JSObject.cpp
+++ b/Source/JavaScriptCore/runtime/JSObject.cpp
@@ -601,7 +601,7 @@ Structure* JSObject::inheritorID(JSGlobalData& globalData)
bool JSObject::allowsAccessFrom(ExecState* exec)
{
- JSGlobalObject* globalObject = unwrappedGlobalObject();
+ JSGlobalObject* globalObject = this->globalObject();
return globalObject->globalObjectMethodTable()->allowsAccessFrom(globalObject, exec);
}
@@ -924,13 +924,6 @@ JSObject* JSObject::toThisObject(JSCell* cell, ExecState*)
return jsCast<JSObject*>(cell);
}
-JSObject* JSObject::unwrappedObject()
-{
- if (isGlobalThis())
- return jsCast<JSGlobalThis*>(this)->unwrappedObject();
- return this;
-}
-
void JSObject::seal(JSGlobalData& globalData)
{
if (isSealed(globalData))
@@ -954,13 +947,6 @@ void JSObject::preventExtensions(JSGlobalData& globalData)
setStructure(globalData, Structure::preventExtensionsTransition(globalData, structure()));
}
-JSGlobalObject* JSObject::unwrappedGlobalObject()
-{
- if (isGlobalThis())
- return jsCast<JSGlobalThis*>(this)->unwrappedObject();
- return structure()->globalObject();
-}
-
// This presently will flatten to an uncachable dictionary; this is suitable
// for use in delete, we may want to do something different elsewhere.
void JSObject::reifyStaticFunctionsForDelete(ExecState* exec)
@@ -1052,7 +1038,7 @@ void JSObject::notifyUsedAsPrototype(JSGlobalData& globalData)
Structure* JSObject::createInheritorID(JSGlobalData& globalData)
{
- Structure* inheritorID = createEmptyObjectStructure(globalData, unwrappedGlobalObject(), this);
+ Structure* inheritorID = createEmptyObjectStructure(globalData, globalObject(), this);
ASSERT(inheritorID->isEmpty());
PutPropertySlot slot;
diff --git a/Source/JavaScriptCore/runtime/JSObject.h b/Source/JavaScriptCore/runtime/JSObject.h
index bb59eb32b..16efeba5e 100644
--- a/Source/JavaScriptCore/runtime/JSObject.h
+++ b/Source/JavaScriptCore/runtime/JSObject.h
@@ -172,6 +172,15 @@ namespace JSC {
JS_EXPORT_PRIVATE static void put(JSCell*, ExecState*, PropertyName, JSValue, PutPropertySlot&);
JS_EXPORT_PRIVATE static void putByIndex(JSCell*, ExecState*, unsigned propertyName, JSValue, bool shouldThrow);
+ void putByIndexInline(ExecState* exec, unsigned propertyName, JSValue value, bool shouldThrow)
+ {
+ if (canSetIndexQuickly(propertyName)) {
+ setIndexQuickly(exec->globalData(), propertyName, value);
+ return;
+ }
+ methodTable()->putByIndex(this, exec, propertyName, value, shouldThrow);
+ }
+
// This is similar to the putDirect* methods:
// - the prototype chain is not consulted
// - accessors are not called.
@@ -179,7 +188,7 @@ namespace JSC {
// This method creates a property with attributes writable, enumerable and configurable all set to true.
bool putDirectIndex(ExecState* exec, unsigned propertyName, JSValue value, unsigned attributes, PutDirectIndexMode mode)
{
- if (!attributes && canSetIndexQuickly(propertyName)) {
+ if (!attributes && canSetIndexQuicklyForPutDirect(propertyName)) {
setIndexQuickly(exec->globalData(), propertyName, value);
return true;
}
@@ -191,7 +200,7 @@ namespace JSC {
}
// A non-throwing version of putDirect and putDirectIndex.
- void putDirectMayBeIndex(ExecState*, PropertyName, JSValue);
+ JS_EXPORT_PRIVATE void putDirectMayBeIndex(ExecState*, PropertyName, JSValue);
bool canGetIndexQuickly(unsigned i)
{
@@ -235,6 +244,19 @@ namespace JSC {
}
}
+ bool canSetIndexQuicklyForPutDirect(unsigned i)
+ {
+ switch (structure()->indexingType()) {
+ case ALL_BLANK_INDEXING_TYPES:
+ return false;
+ case ALL_ARRAY_STORAGE_INDEXING_TYPES:
+ return i < m_butterfly->arrayStorage()->vectorLength();
+ default:
+ ASSERT_NOT_REACHED();
+ return false;
+ }
+ }
+
void setIndexQuickly(JSGlobalData& globalData, unsigned i, JSValue v)
{
switch (structure()->indexingType()) {
@@ -321,7 +343,6 @@ namespace JSC {
// NOTE: JSObject and its subclasses must be able to gracefully handle ExecState* = 0,
// because this call may come from inside the compiler.
JS_EXPORT_PRIVATE static JSObject* toThisObject(JSCell*, ExecState*);
- JSObject* unwrappedObject();
bool getPropertySpecificValue(ExecState*, PropertyName, JSCell*& specificFunction) const;
@@ -460,11 +481,6 @@ namespace JSC {
return structure()->globalObject();
}
- // Does everything possible to return the global object. If it encounters an object
- // that does not have a global object, it returns 0 instead (for example
- // JSNotAnObject).
- JSGlobalObject* unwrappedGlobalObject();
-
void switchToSlowPutArrayStorage(JSGlobalData&);
// The receiver is the prototype in this case. The following:
diff --git a/Source/JavaScriptCore/runtime/LiteralParser.cpp b/Source/JavaScriptCore/runtime/LiteralParser.cpp
index 732d818bd..cd854417b 100644
--- a/Source/JavaScriptCore/runtime/LiteralParser.cpp
+++ b/Source/JavaScriptCore/runtime/LiteralParser.cpp
@@ -570,7 +570,8 @@ JSValue LiteralParser<CharType>::parse(ParserState initialState)
goto startParseExpression;
}
case DoParseArrayEndExpression: {
- asArray(objectStack.last())->push(m_exec, lastValue);
+ JSArray* array = asArray(objectStack.last());
+ array->putDirectIndex(m_exec, array->length(), lastValue);
if (m_lexer.currentToken().type == TokComma)
goto doParseArrayStartExpression;
diff --git a/Source/JavaScriptCore/runtime/ObjectConstructor.cpp b/Source/JavaScriptCore/runtime/ObjectConstructor.cpp
index 5ac2d8788..8614b9c45 100644
--- a/Source/JavaScriptCore/runtime/ObjectConstructor.cpp
+++ b/Source/JavaScriptCore/runtime/ObjectConstructor.cpp
@@ -404,7 +404,7 @@ EncodedJSValue JSC_HOST_CALL objectConstructorFreeze(ExecState* exec)
return throwVMError(exec, createTypeError(exec, ASCIILiteral("Object.freeze can only be called on Objects.")));
JSObject* object = asObject(obj);
- if (isJSFinalObject(object)) {
+ if (isJSFinalObject(object) && !hasIndexedProperties(object->structure()->indexingType())) {
object->freeze(exec->globalData());
return JSValue::encode(obj);
}
diff --git a/Source/JavaScriptCore/runtime/SparseArrayValueMap.cpp b/Source/JavaScriptCore/runtime/SparseArrayValueMap.cpp
index 3f709b0a7..b9ba25735 100644
--- a/Source/JavaScriptCore/runtime/SparseArrayValueMap.cpp
+++ b/Source/JavaScriptCore/runtime/SparseArrayValueMap.cpp
@@ -159,7 +159,7 @@ JSValue SparseArrayEntry::get(ExecState* exec, JSObject* array) const
CallData callData;
CallType callType = getter->methodTable()->getCallData(getter, callData);
- return call(exec, getter, callType, callData, array, exec->emptyList());
+ return call(exec, getter, callType, callData, array->methodTable()->toThisObject(array, exec), exec->emptyList());
}
void SparseArrayEntry::put(ExecState* exec, JSValue thisValue, SparseArrayValueMap* map, JSValue value, bool shouldThrow)
@@ -189,6 +189,8 @@ void SparseArrayEntry::put(ExecState* exec, JSValue thisValue, SparseArrayValueM
CallType callType = setter->methodTable()->getCallData(setter, callData);
MarkedArgumentBuffer args;
args.append(value);
+ if (thisValue.isObject())
+ thisValue = asObject(thisValue)->methodTable()->toThisObject(asObject(thisValue), exec);
call(exec, setter, callType, callData, thisValue, args);
}
diff --git a/Source/Platform/ChangeLog b/Source/Platform/ChangeLog
index 7502f1c4d..44faebcba 100644
--- a/Source/Platform/ChangeLog
+++ b/Source/Platform/ChangeLog
@@ -1,3 +1,32 @@
+2012-09-24 Dana Jansens <danakj@chromium.org>
+
+ [chromium] Add setters to WebFilterOperation for IPC pickling
+ https://bugs.webkit.org/show_bug.cgi?id=97147
+
+ Reviewed by James Robinson.
+
+ These methods allow us to restore a WebFilterOperation from a blob
+ of opaque data. The pickling code needs to be able to create an
+ empty object and then fill in the pieces, so these setters allow it
+ to do so.
+
+ Test: WebFilterOperationsTest.saveAndRestore
+
+ * chromium/public/WebFilterOperation.h:
+ (WebKit::WebFilterOperation::amount):
+ (WebKit::WebFilterOperation::dropShadowOffset):
+ (WebKit::WebFilterOperation::matrix):
+ (WebKit::WebFilterOperation::zoomRect):
+ (WebFilterOperation):
+ (WebKit::WebFilterOperation::createEmptyFilter):
+ (WebKit::WebFilterOperation::setType):
+ (WebKit::WebFilterOperation::setAmount):
+ (WebKit::WebFilterOperation::setDropShadowOffset):
+ (WebKit::WebFilterOperation::setDropShadowColor):
+ (WebKit::WebFilterOperation::setMatrix):
+ (WebKit::WebFilterOperation::setZoomRect):
+ * chromium/src/WebFilterOperation.cpp:
+
2012-09-24 Yury Semikhatsky <yurys@chromium.org>
Unreviewed, rolling out r122243.
diff --git a/Source/Platform/chromium/public/WebFilterOperation.h b/Source/Platform/chromium/public/WebFilterOperation.h
index 9f15519a1..3628f487b 100644
--- a/Source/Platform/chromium/public/WebFilterOperation.h
+++ b/Source/Platform/chromium/public/WebFilterOperation.h
@@ -55,12 +55,23 @@ public:
float amount() const
{
+ WEBKIT_ASSERT(m_type == FilterTypeGrayscale
+ || m_type == FilterTypeSepia
+ || m_type == FilterTypeSaturate
+ || m_type == FilterTypeHueRotate
+ || m_type == FilterTypeInvert
+ || m_type == FilterTypeBrightness
+ || m_type == FilterTypeContrast
+ || m_type == FilterTypeOpacity
+ || m_type == FilterTypeBlur
+ || m_type == FilterTypeDropShadow
+ || m_type == FilterTypeZoom);
return m_amount;
}
WebPoint dropShadowOffset() const
{
WEBKIT_ASSERT(m_type == FilterTypeDropShadow);
- return WebPoint(m_dropShadowOffset);
+ return m_dropShadowOffset;
}
WebColor dropShadowColor() const
{
@@ -69,16 +80,16 @@ public:
}
const SkScalar* matrix() const
{
+ WEBKIT_ASSERT(m_type == FilterTypeColorMatrix);
return m_matrix;
}
WebRect zoomRect() const
{
WEBKIT_ASSERT(m_type == FilterTypeZoom);
- return WebRect(m_zoomRect);
+ return m_zoomRect;
}
-#define WEBKIT_HAS_NEW_WEBFILTEROPERATION_API 1
static WebFilterOperation createGrayscaleFilter(float amount) { return WebFilterOperation(FilterTypeGrayscale, amount); }
static WebFilterOperation createSepiaFilter(float amount) { return WebFilterOperation(FilterTypeSepia, amount); }
static WebFilterOperation createSaturateFilter(float amount) { return WebFilterOperation(FilterTypeSaturate, amount); }
@@ -94,6 +105,46 @@ public:
bool equals(const WebFilterOperation& other) const;
+ // Methods for restoring a WebFilterOperation.
+ static WebFilterOperation createEmptyFilter() { return WebFilterOperation(FilterTypeGrayscale, 0.0); }
+ void setType(FilterType type) { m_type = type; }
+ void setAmount(float amount)
+ {
+ WEBKIT_ASSERT(m_type == FilterTypeGrayscale
+ || m_type == FilterTypeSepia
+ || m_type == FilterTypeSaturate
+ || m_type == FilterTypeHueRotate
+ || m_type == FilterTypeInvert
+ || m_type == FilterTypeBrightness
+ || m_type == FilterTypeContrast
+ || m_type == FilterTypeOpacity
+ || m_type == FilterTypeBlur
+ || m_type == FilterTypeDropShadow
+ || m_type == FilterTypeZoom);
+ m_amount = amount;
+ }
+ void setDropShadowOffset(WebPoint offset)
+ {
+ WEBKIT_ASSERT(m_type == FilterTypeDropShadow);
+ m_dropShadowOffset = offset;
+ }
+ void setDropShadowColor(WebColor color)
+ {
+ WEBKIT_ASSERT(m_type == FilterTypeDropShadow);
+ m_dropShadowColor = color;
+ }
+ void setMatrix(const SkScalar matrix[20])
+ {
+ WEBKIT_ASSERT(m_type == FilterTypeColorMatrix);
+ for (unsigned i = 0; i < 20; ++i)
+ m_matrix[i] = matrix[i];
+ }
+ void setZoomRect(WebRect rect)
+ {
+ WEBKIT_ASSERT(m_type == FilterTypeZoom);
+ m_zoomRect = rect;
+ }
+
private:
FilterType m_type;
diff --git a/Source/WTF/ChangeLog b/Source/WTF/ChangeLog
index 7bb10c1fb..51f56d177 100644
--- a/Source/WTF/ChangeLog
+++ b/Source/WTF/ChangeLog
@@ -1,3 +1,337 @@
+2012-09-21 Ilya Tikhonovsky <loislo@chromium.org>
+
+ Web Inspector: extract Vector instrumentation from core NMI code into MemoryInstrumentationVector.h header.
+ https://bugs.webkit.org/show_bug.cgi?id=96650
+
+ Reviewed by Vsevolod Vlasov.
+
+ Added reportMemoryUsage free template function with default body to core NMI code
+ and add custom version of reportMemoryUsage function for Vectors.
+
+ * GNUmakefile.list.am:
+ * WTF.gypi:
+ * WTF.pro:
+ * WTF.vcproj/WTF.vcproj:
+ * WTF.xcodeproj/project.pbxproj:
+ * wtf/MemoryInstrumentation.h:
+ (WTF):
+ (MemoryInstrumentation):
+ (WTF::MemoryInstrumentation::addObjectImpl):
+ * wtf/MemoryInstrumentationVector.h: Added.
+ (WTF):
+ (WTF::instrumentVectorValues):
+ (WTF::reportMemoryUsage):
+
+2012-09-24 Mark Lam <mark.lam@apple.com>
+
+ Deleting the classic interpreter and cleaning up some build options.
+ https://bugs.webkit.org/show_bug.cgi?id=96969.
+
+ Reviewed by Geoffrey Garen.
+
+ * wtf/OSAllocatorPosix.cpp:
+ (WTF::OSAllocator::reserveAndCommit):
+ * wtf/Platform.h:
+
+2012-09-24 Patrick Gansterer <paroga@webkit.org>
+
+ Remove String::operator+=()
+ https://bugs.webkit.org/show_bug.cgi?id=96172
+
+ Reviewed by Benjamin Poulain.
+
+ * wtf/Platform.h:
+ * wtf/text/WTFString.h:
+
+2012-09-24 Benjamin Poulain <benjamin@webkit.org>
+
+ Add support for query encoding to WTFURL
+ https://bugs.webkit.org/show_bug.cgi?id=97422
+
+ Reviewed by Adam Barth.
+
+ Expose character conversion through the new abstract class URLQueryCharsetConverter.
+ URLQueryCharsetConverter is implemented by WebCore to expose the TextEncoding classes.
+
+ Unfortunatelly that forces us to bring over URLBuffer in the public API. We may be able
+ to mitigate that later when moving WTFURL to more templates.
+
+ The change fixes 2 of the URL layout tests.
+
+ * WTF.xcodeproj/project.pbxproj:
+ * wtf/url/api/ParsedURL.cpp:
+ (WTF::ParsedURL::ParsedURL):
+ * wtf/url/api/ParsedURL.h:
+ (ParsedURL):
+ ParsedURL was using the same constructor for ParsedURLString, and URL without a base.
+ That was a mistake on my part, I did not intend that, fixed it now :)
+
+ * wtf/url/api/URLBuffer.h: Renamed from Source/WTF/wtf/url/src/URLBuffer.h.
+ (URLBuffer):
+ (WTF::URLBuffer::URLBuffer):
+ (WTF::URLBuffer::~URLBuffer):
+ (WTF::URLBuffer::at):
+ (WTF::URLBuffer::set):
+ (WTF::URLBuffer::capacity):
+ (WTF::URLBuffer::length):
+ (WTF::URLBuffer::data):
+ (WTF::URLBuffer::setLength):
+ (WTF::URLBuffer::append):
+ (WTF::URLBuffer::grow):
+ * wtf/url/api/URLQueryCharsetConverter.h: Added.
+ (URLQueryCharsetConverter):
+ (WTF::URLQueryCharsetConverter::URLQueryCharsetConverter):
+ (WTF::URLQueryCharsetConverter::~URLQueryCharsetConverter):
+ * wtf/url/src/URLCanon.h:
+ (URLCanonicalizer):
+ * wtf/url/src/URLCanonFilesystemurl.cpp:
+ (WTF::URLCanonicalizer::canonicalizeFileSystemURL):
+ (WTF::URLCanonicalizer::ReplaceFileSystemURL):
+ * wtf/url/src/URLCanonFileurl.cpp:
+ (WTF::URLCanonicalizer::CanonicalizeFileURL):
+ (WTF::URLCanonicalizer::ReplaceFileURL):
+ * wtf/url/src/URLCanonInternal.h:
+ (URLCanonicalizer):
+ * wtf/url/src/URLCanonQuery.cpp:
+ (WTF::URLCanonicalizer::CanonicalizeQuery):
+ (WTF::URLCanonicalizer::ConvertUTF16ToQueryEncoding):
+ * wtf/url/src/URLCanonRelative.cpp:
+ (WTF::URLCanonicalizer::resolveRelativeURL):
+ * wtf/url/src/URLCanonStdURL.cpp:
+ (WTF::URLCanonicalizer::CanonicalizeStandardURL):
+ (WTF::URLCanonicalizer::ReplaceStandardURL):
+ * wtf/url/src/URLUtil.cpp:
+ (URLUtilities):
+ (WTF::URLUtilities::canonicalize):
+ (WTF::URLUtilities::resolveRelative):
+ (WTF::URLUtilities::ReplaceComponents):
+ * wtf/url/src/URLUtil.h:
+ (URLUtilities):
+
+2012-09-24 Benjamin Poulain <benjamin@webkit.org>
+
+ Integrate most of GoogleURL in WTFURL
+ https://bugs.webkit.org/show_bug.cgi?id=97405
+
+ Reviewed by Adam Barth.
+
+ This patch brings almost all of the implementatation of Google-URL in WTFURL
+ with only minor changes.
+
+ The changes from the original code are mostly:
+ -Code cleaning.
+ -Replace url_parse::Parsed by URLSegments.
+ -Replace url_parse::Component by URLComponent
+ -More code cleaning.
+ -Adopt URLBuffer and RawURLBuffer instead of the CanonOutputT and RawCanonOutputT.
+ -Use URLCharacterTypes instead of the litany of characters functions.
+ -Some more code cleaning.
+ -Fix the style to match WebKit as much as possible.
+ -Rename the files to match WebKit style.
+
+ * WTF.xcodeproj/project.pbxproj:
+ * wtf/url/api/ParsedURL.cpp:
+ (WTF::ParsedURL::ParsedURL):
+ (WTF::ParsedURL::segment):
+ * wtf/url/api/ParsedURL.h:
+ (WTF::ParsedURL::isValid):
+ * wtf/url/src/RawURLBuffer.h:
+ * wtf/url/src/URLCanon.h: Added.
+ (URLCanonicalizer):
+ (CharsetConverter):
+ (WTF::URLCanonicalizer::CharsetConverter::CharsetConverter):
+ (WTF::URLCanonicalizer::CharsetConverter::~CharsetConverter):
+ (CanonHostInfo):
+ (WTF::URLCanonicalizer::CanonHostInfo::CanonHostInfo):
+ (WTF::URLCanonicalizer::CanonHostInfo::IsIPAddress):
+ (WTF::URLCanonicalizer::CanonHostInfo::AddressLength):
+ (URLComponentSource):
+ (WTF::URLCanonicalizer::URLComponentSource::URLComponentSource):
+ (Replacements):
+ (WTF::URLCanonicalizer::Replacements::Replacements):
+ (WTF::URLCanonicalizer::Replacements::SetScheme):
+ (WTF::URLCanonicalizer::Replacements::IsSchemeOverridden):
+ (WTF::URLCanonicalizer::Replacements::SetUsername):
+ (WTF::URLCanonicalizer::Replacements::ClearUsername):
+ (WTF::URLCanonicalizer::Replacements::IsUsernameOverridden):
+ (WTF::URLCanonicalizer::Replacements::SetPassword):
+ (WTF::URLCanonicalizer::Replacements::ClearPassword):
+ (WTF::URLCanonicalizer::Replacements::IsPasswordOverridden):
+ (WTF::URLCanonicalizer::Replacements::SetHost):
+ (WTF::URLCanonicalizer::Replacements::ClearHost):
+ (WTF::URLCanonicalizer::Replacements::IsHostOverridden):
+ (WTF::URLCanonicalizer::Replacements::SetPort):
+ (WTF::URLCanonicalizer::Replacements::ClearPort):
+ (WTF::URLCanonicalizer::Replacements::IsPortOverridden):
+ (WTF::URLCanonicalizer::Replacements::SetPath):
+ (WTF::URLCanonicalizer::Replacements::ClearPath):
+ (WTF::URLCanonicalizer::Replacements::IsPathOverridden):
+ (WTF::URLCanonicalizer::Replacements::SetQuery):
+ (WTF::URLCanonicalizer::Replacements::ClearQuery):
+ (WTF::URLCanonicalizer::Replacements::IsQueryOverridden):
+ (WTF::URLCanonicalizer::Replacements::SetRef):
+ (WTF::URLCanonicalizer::Replacements::ClearRef):
+ (WTF::URLCanonicalizer::Replacements::IsRefOverridden):
+ (WTF::URLCanonicalizer::Replacements::sources):
+ (WTF::URLCanonicalizer::Replacements::components):
+ (WTF::URLCanonicalizer::Replacements::Placeholder):
+ * wtf/url/src/URLCanonEtc.cpp: Added.
+ (WTF::URLCanonicalizer::removeURLWhitespace):
+ (URLCanonicalizer):
+ (WTF::URLCanonicalizer::canonicalSchemeChar):
+ (WTF::URLCanonicalizer::CanonicalizeScheme):
+ (WTF::URLCanonicalizer::CanonicalizeUserInfo):
+ (WTF::URLCanonicalizer::CanonicalizePort):
+ (WTF::URLCanonicalizer::CanonicalizeRef):
+ * wtf/url/src/URLCanonFilesystemurl.cpp: Added.
+ (WTF::URLCanonicalizer::CanonicalizeFileSystemURL):
+ (URLCanonicalizer):
+ (WTF::URLCanonicalizer::ReplaceFileSystemURL):
+ * wtf/url/src/URLCanonFileurl.cpp: Added.
+ (WTF::URLCanonicalizer::CanonicalizeFileURL):
+ (URLCanonicalizer):
+ (WTF::URLCanonicalizer::FileCanonicalizePath):
+ (WTF::URLCanonicalizer::ReplaceFileURL):
+ * wtf/url/src/URLCanonHost.cpp: Added.
+ (WTF::URLCanonicalizer::CanonicalizeHost):
+ (URLCanonicalizer):
+ (WTF::URLCanonicalizer::CanonicalizeHostVerbose):
+ * wtf/url/src/URLCanonICU.cpp: Added.
+ (WTF::URLCanonicalizer::IDNToASCII):
+ (URLCanonicalizer):
+ (WTF::URLCanonicalizer::readUTFChar):
+ * wtf/url/src/URLCanonIP.cpp: Added.
+ (WTF::URLCanonicalizer::CanonicalizeIPAddress):
+ (URLCanonicalizer):
+ * wtf/url/src/URLCanonInternal.cpp: Added.
+ (URLCanonicalizer):
+ (WTF::URLCanonicalizer::AppendInvalidNarrowString):
+ (WTF::URLCanonicalizer::ConvertUTF16ToUTF8):
+ (WTF::URLCanonicalizer::ConvertUTF8ToUTF16):
+ (WTF::URLCanonicalizer::SetupOverrideComponents):
+ (WTF::URLCanonicalizer::SetupUTF16OverrideComponents):
+ (WTF::URLCanonicalizer::_itoa_s):
+ (WTF::URLCanonicalizer::_itow_s):
+ * wtf/url/src/URLCanonInternal.h: Added.
+ (URLCanonicalizer):
+ (WTF::URLCanonicalizer::hexCharToValue):
+ (WTF::URLCanonicalizer::isDot):
+ (WTF::URLCanonicalizer::appendURLEscapedCharacter):
+ (WTF::URLCanonicalizer::doAppendUTF8):
+ (WTF::URLCanonicalizer::AppendCharToOutput):
+ (WTF::URLCanonicalizer::AppendUTF8Value):
+ (WTF::URLCanonicalizer::AppendUTF8EscapedValue):
+ (WTF::URLCanonicalizer::AppendUTF16Value):
+ (WTF::URLCanonicalizer::AppendUTF8EscapedChar):
+ (WTF::URLCanonicalizer::Is8BitChar):
+ (WTF::URLCanonicalizer::DecodeEscaped):
+ (WTF::URLCanonicalizer::_itoa_s):
+ (WTF::URLCanonicalizer::_itow_s):
+ (WTF::URLCanonicalizer::_strtoui64):
+ * wtf/url/src/URLCanonMailto.cpp: Added.
+ (WTF::URLCanonicalizer::CanonicalizeMailtoURL):
+ (URLCanonicalizer):
+ (WTF::URLCanonicalizer::ReplaceMailtoURL):
+ * wtf/url/src/URLCanonPath.cpp: Added.
+ (WTF::URLCanonicalizer::CanonicalizePath):
+ (URLCanonicalizer):
+ (WTF::URLCanonicalizer::CanonicalizePartialPath):
+ * wtf/url/src/URLCanonPathurl.cpp: Added.
+ (WTF::URLCanonicalizer::canonicalizePathURL):
+ (URLCanonicalizer):
+ (WTF::URLCanonicalizer::ReplacePathURL):
+ * wtf/url/src/URLCanonQuery.cpp: Added.
+ (WTF::URLCanonicalizer::CanonicalizeQuery):
+ (URLCanonicalizer):
+ (WTF::URLCanonicalizer::ConvertUTF16ToQueryEncoding):
+ * wtf/url/src/URLCanonRelative.cpp: Added.
+ (WTF::URLCanonicalizer::isRelativeURL):
+ (URLCanonicalizer):
+ (WTF::URLCanonicalizer::resolveRelativeURL):
+ * wtf/url/src/URLCanonStdURL.cpp: Added.
+ (WTF::URLCanonicalizer::DefaultPortForScheme):
+ (URLCanonicalizer):
+ (WTF::URLCanonicalizer::CanonicalizeStandardURL):
+ (WTF::URLCanonicalizer::ReplaceStandardURL):
+ * wtf/url/src/URLCharacterTypes.cpp:
+ * wtf/url/src/URLCharacterTypes.h:
+ (WTF::URLCharacterTypes::isComponentChar):
+ (WTF::URLCharacterTypes::isHexChar):
+ (WTF::URLCharacterTypes::isIPv4Char):
+ (WTF::URLCharacterTypes::isQueryChar):
+ (WTF::URLCharacterTypes::isCharacterOfType):
+ (URLCharacterTypes):
+ * wtf/url/src/URLEscape.cpp: Removed.
+ * wtf/url/src/URLFile.h: Added.
+ (URLParser):
+ (WTF::URLParser::isWindowsDriveSeparator):
+ (WTF::URLParser::isWindowsDriveLetter):
+ (WTF::URLParser::findNextSlash):
+ (WTF::URLParser::doesBeginWindowsDriveSpec):
+ (WTF::URLParser::doesBeginUNCPath):
+ * wtf/url/src/URLParse.cpp: Added.
+ (WTF::URLParser::ExtractScheme):
+ (URLParser):
+ (WTF::URLParser::IsAuthorityTerminator):
+ (WTF::URLParser::ExtractFileName):
+ (WTF::URLParser::ExtractQueryKeyValue):
+ (WTF::URLParser::ParseAuthority):
+ (WTF::URLParser::ParsePort):
+ (WTF::URLParser::ParseStandardURL):
+ (WTF::URLParser::ParsePathURL):
+ (WTF::URLParser::ParseFileSystemURL):
+ (WTF::URLParser::ParseMailtoURL):
+ (WTF::URLParser::parsePathInternal):
+ (WTF::URLParser::ParseAfterScheme):
+ * wtf/url/src/URLParse.h: Added.
+ (URLParser):
+ * wtf/url/src/URLParseFile.cpp: Added.
+ (WTF):
+ (WTF::URLParser::ParseFileURL):
+ (URLParser):
+ * wtf/url/src/URLParseInternal.h: Added.
+ (URLParser):
+ (WTF::URLParser::isURLSlash):
+ (WTF::URLParser::shouldTrimFromURL):
+ (WTF::URLParser::trimURL):
+ (WTF::URLParser::countConsecutiveSlashes):
+ * wtf/url/src/URLParser.h: Removed.
+ * wtf/url/src/URLQueryCanonicalizer.h: Removed.
+ * wtf/url/src/URLSegments.cpp:
+ * wtf/url/src/URLSegments.h:
+ (WTF::URLSegments::URLSegments):
+ (URLSegments):
+ (WTF::URLSegments::operator=):
+ (WTF::URLSegments::innerURLSegments):
+ (WTF::URLSegments::setInnerURLSegments):
+ (WTF::URLSegments::clearInnerURLSegments):
+ * wtf/url/src/URLUtil.cpp: Added.
+ (URLUtilities):
+ (WTF::URLUtilities::IsStandard):
+ (WTF::URLUtilities::FindAndCompareScheme):
+ (WTF::URLUtilities::Canonicalize):
+ (WTF::URLUtilities::resolveRelative):
+ (WTF::URLUtilities::ReplaceComponents):
+ (WTF::URLUtilities::LowerCaseEqualsASCII):
+ (WTF::URLUtilities::DecodeURLEscapeSequences):
+ (WTF::URLUtilities::EncodeURIComponent):
+ (WTF::URLUtilities::CompareSchemeComponent):
+ * wtf/url/src/URLUtil.h: Added.
+ (URLUtilities):
+ * wtf/url/src/URLUtilInternal.h: Renamed from Source/WTF/wtf/url/src/URLEscape.h.
+ (URLUtilities):
+
+2012-09-24 Joone Hur <joone.hur@intel.com>
+
+ [GTK] Implement GraphicsLayer using Clutter
+ https://bugs.webkit.org/show_bug.cgi?id=73767
+
+ Reviewed by Martin Robinson.
+
+ Add ClutterActor and GraphicsLayerActor to GTypedefs.h.
+
+ * wtf/gobject/GTypedefs.h:
+
2012-09-23 Byungwoo Lee <bw80.lee@gmail.com>
Fix build warnings : -Wunused-parameter, -Wparentheses, -Wuninitialized.
diff --git a/Source/WTF/GNUmakefile.list.am b/Source/WTF/GNUmakefile.list.am
index e8e42edd3..0ed10ddae 100644
--- a/Source/WTF/GNUmakefile.list.am
+++ b/Source/WTF/GNUmakefile.list.am
@@ -80,6 +80,7 @@ wtf_sources += \
Source/WTF/wtf/MediaTime.h \
Source/WTF/wtf/MediaTime.cpp \
Source/WTF/wtf/MemoryInstrumentation.h \
+ Source/WTF/wtf/MemoryInstrumentationVector.h \
Source/WTF/wtf/MessageQueue.h \
Source/WTF/wtf/MetaAllocator.cpp \
Source/WTF/wtf/MetaAllocator.h \
diff --git a/Source/WTF/WTF.gypi b/Source/WTF/WTF.gypi
index 5dcd01ed7..fdc28d6bb 100644
--- a/Source/WTF/WTF.gypi
+++ b/Source/WTF/WTF.gypi
@@ -50,6 +50,7 @@
'wtf/MainThread.h',
'wtf/MathExtras.h',
'wtf/MemoryInstrumentation.h',
+ 'wtf/MemoryInstrumentationVector.h',
'wtf/MessageQueue.h',
'wtf/NonCopyingSort.h',
'wtf/Noncopyable.h',
diff --git a/Source/WTF/WTF.pro b/Source/WTF/WTF.pro
index bc0a8770e..e8da4c0c6 100644
--- a/Source/WTF/WTF.pro
+++ b/Source/WTF/WTF.pro
@@ -87,6 +87,7 @@ HEADERS += \
MD5.h \
MediaTime.h \
MemoryInstrumentation.h \
+ MemoryInstrumentationVector.h \
MessageQueue.h \
MetaAllocator.h \
MetaAllocatorHandle.h \
diff --git a/Source/WTF/WTF.vcproj/WTF.vcproj b/Source/WTF/WTF.vcproj/WTF.vcproj
index 4ec3e5544..9610092d0 100644
--- a/Source/WTF/WTF.vcproj/WTF.vcproj
+++ b/Source/WTF/WTF.vcproj/WTF.vcproj
@@ -905,6 +905,10 @@
>
</File>
<File
+ RelativePath="..\wtf\MemoryInstrumentationVector.h"
+ >
+ </File>
+ <File
RelativePath="..\wtf\MessageQueue.h"
>
</File>
diff --git a/Source/WTF/WTF.xcodeproj/project.pbxproj b/Source/WTF/WTF.xcodeproj/project.pbxproj
index 52af7b9ce..3a89edfa1 100644
--- a/Source/WTF/WTF.xcodeproj/project.pbxproj
+++ b/Source/WTF/WTF.xcodeproj/project.pbxproj
@@ -12,11 +12,36 @@
143F61201565F0F900DB514A /* RAMSize.h in Headers */ = {isa = PBXBuildFile; fileRef = 143F611E1565F0F900DB514A /* RAMSize.h */; settings = {ATTRIBUTES = (Private, ); }; };
14F3B0F715E45E4600210069 /* SaturatedArithmetic.h in Headers */ = {isa = PBXBuildFile; fileRef = 14F3B0F615E45E4600210069 /* SaturatedArithmetic.h */; settings = {ATTRIBUTES = (Private, ); }; };
26147B0A15DDCCDC00DDB907 /* IntegerToStringConversion.h in Headers */ = {isa = PBXBuildFile; fileRef = 26147B0815DDCCDC00DDB907 /* IntegerToStringConversion.h */; };
+ 2661122E160FEAD40013F5C3 /* URLQueryCharsetConverter.h in Headers */ = {isa = PBXBuildFile; fileRef = 2661122D160FEAD40013F5C3 /* URLQueryCharsetConverter.h */; };
+ 26E6C1EE1609037300CA6AF4 /* URLCanonEtc.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 26E6C1CE1609037300CA6AF4 /* URLCanonEtc.cpp */; };
+ 26E6C1EF1609037300CA6AF4 /* URLCanonFilesystemurl.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 26E6C1CF1609037300CA6AF4 /* URLCanonFilesystemurl.cpp */; };
+ 26E6C1F01609037300CA6AF4 /* URLCanonFileurl.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 26E6C1D01609037300CA6AF4 /* URLCanonFileurl.cpp */; };
+ 26E6C1F11609037300CA6AF4 /* URLCanonHost.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 26E6C1D11609037300CA6AF4 /* URLCanonHost.cpp */; };
+ 26E6C1F21609037300CA6AF4 /* URLCanonICU.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 26E6C1D21609037300CA6AF4 /* URLCanonICU.cpp */; };
+ 26E6C1F51609037300CA6AF4 /* URLCanonInternal.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 26E6C1D51609037300CA6AF4 /* URLCanonInternal.cpp */; };
+ 26E6C1F61609037300CA6AF4 /* URLCanonInternal.h in Headers */ = {isa = PBXBuildFile; fileRef = 26E6C1D61609037300CA6AF4 /* URLCanonInternal.h */; };
+ 26E6C1F71609037300CA6AF4 /* URLCanonIP.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 26E6C1D71609037300CA6AF4 /* URLCanonIP.cpp */; };
+ 26E6C1F91609037300CA6AF4 /* URLCanonMailto.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 26E6C1D91609037300CA6AF4 /* URLCanonMailto.cpp */; };
+ 26E6C1FA1609037300CA6AF4 /* URLCanonPath.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 26E6C1DA1609037300CA6AF4 /* URLCanonPath.cpp */; };
+ 26E6C1FB1609037300CA6AF4 /* URLCanonPathurl.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 26E6C1DB1609037300CA6AF4 /* URLCanonPathurl.cpp */; };
+ 26E6C1FC1609037300CA6AF4 /* URLCanonQuery.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 26E6C1DC1609037300CA6AF4 /* URLCanonQuery.cpp */; };
+ 26E6C1FD1609037300CA6AF4 /* URLCanonRelative.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 26E6C1DD1609037300CA6AF4 /* URLCanonRelative.cpp */; };
+ 26E6C1FF1609037300CA6AF4 /* URLCanonStdURL.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 26E6C1DF1609037300CA6AF4 /* URLCanonStdURL.cpp */; };
+ 26E6C2011609037300CA6AF4 /* URLCanon.h in Headers */ = {isa = PBXBuildFile; fileRef = 26E6C1E11609037300CA6AF4 /* URLCanon.h */; };
+ 26E6C2031609037300CA6AF4 /* URLFile.h in Headers */ = {isa = PBXBuildFile; fileRef = 26E6C1E31609037300CA6AF4 /* URLFile.h */; };
+ 26E6C2041609037300CA6AF4 /* URLParseFile.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 26E6C1E41609037300CA6AF4 /* URLParseFile.cpp */; };
+ 26E6C2051609037300CA6AF4 /* URLParseInternal.h in Headers */ = {isa = PBXBuildFile; fileRef = 26E6C1E51609037300CA6AF4 /* URLParseInternal.h */; };
+ 26E6C2071609037300CA6AF4 /* URLParse.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 26E6C1E71609037300CA6AF4 /* URLParse.cpp */; };
+ 26E6C2081609037300CA6AF4 /* URLParse.h in Headers */ = {isa = PBXBuildFile; fileRef = 26E6C1E81609037300CA6AF4 /* URLParse.h */; };
+ 26E6C20A1609037300CA6AF4 /* URLUtilInternal.h in Headers */ = {isa = PBXBuildFile; fileRef = 26E6C1EA1609037300CA6AF4 /* URLUtilInternal.h */; };
+ 26E6C20C1609037300CA6AF4 /* URLUtil.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 26E6C1EC1609037300CA6AF4 /* URLUtil.cpp */; };
+ 26E6C20D1609037300CA6AF4 /* URLUtil.h in Headers */ = {isa = PBXBuildFile; fileRef = 26E6C1ED1609037300CA6AF4 /* URLUtil.h */; };
2C05385415BC819000F21B96 /* GregorianDateTime.h in Headers */ = {isa = PBXBuildFile; fileRef = 2C05385315BC819000F21B96 /* GregorianDateTime.h */; };
2CCD892A15C0390200285083 /* GregorianDateTime.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2CCD892915C0390200285083 /* GregorianDateTime.cpp */; };
4330F38F15745B0500AAFA8F /* URLString.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4330F38E15745B0500AAFA8F /* URLString.cpp */; };
4F0321BC156AA8D1006EBAF6 /* BitArray.h in Headers */ = {isa = PBXBuildFile; fileRef = 4F0321BB156AA8D1006EBAF6 /* BitArray.h */; };
4F1D115415FF11BE0026E908 /* MemoryInstrumentation.h in Headers */ = {isa = PBXBuildFile; fileRef = 4F1D115315FF11BE0026E908 /* MemoryInstrumentation.h */; };
+ 4FCB710A160A1A07008425EC /* MemoryInstrumentationVector.h in Headers */ = {isa = PBXBuildFile; fileRef = 4FCB7109160A1A07008425EC /* MemoryInstrumentationVector.h */; };
7E29C33E15FFD79B00516D61 /* ObjcRuntimeExtras.h in Headers */ = {isa = PBXBuildFile; fileRef = 7E29C33D15FFD79B00516D61 /* ObjcRuntimeExtras.h */; };
8134013815B092FD001FF0B8 /* Base64.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8134013615B092FD001FF0B8 /* Base64.cpp */; };
8134013915B092FD001FF0B8 /* Base64.h in Headers */ = {isa = PBXBuildFile; fileRef = 8134013715B092FD001FF0B8 /* Base64.h */; };
@@ -237,10 +262,6 @@
A8A47474151A825B004123FF /* URLCharacterTypes.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A8A47366151A825B004123FF /* URLCharacterTypes.cpp */; };
A8A47475151A825B004123FF /* URLCharacterTypes.h in Headers */ = {isa = PBXBuildFile; fileRef = A8A47367151A825B004123FF /* URLCharacterTypes.h */; };
A8A47476151A825B004123FF /* URLComponent.h in Headers */ = {isa = PBXBuildFile; fileRef = A8A47368151A825B004123FF /* URLComponent.h */; };
- A8A47477151A825B004123FF /* URLEscape.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A8A47369151A825B004123FF /* URLEscape.cpp */; };
- A8A47478151A825B004123FF /* URLEscape.h in Headers */ = {isa = PBXBuildFile; fileRef = A8A4736A151A825B004123FF /* URLEscape.h */; };
- A8A47479151A825B004123FF /* URLParser.h in Headers */ = {isa = PBXBuildFile; fileRef = A8A4736B151A825B004123FF /* URLParser.h */; };
- A8A4747A151A825B004123FF /* URLQueryCanonicalizer.h in Headers */ = {isa = PBXBuildFile; fileRef = A8A4736C151A825B004123FF /* URLQueryCanonicalizer.h */; };
A8A4747B151A825B004123FF /* URLSegments.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A8A4736D151A825B004123FF /* URLSegments.cpp */; };
A8A4747C151A825B004123FF /* URLSegments.h in Headers */ = {isa = PBXBuildFile; fileRef = A8A4736E151A825B004123FF /* URLSegments.h */; };
A8A4747D151A825B004123FF /* ValueCheck.h in Headers */ = {isa = PBXBuildFile; fileRef = A8A4736F151A825B004123FF /* ValueCheck.h */; };
@@ -260,11 +281,36 @@
143F611E1565F0F900DB514A /* RAMSize.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RAMSize.h; sourceTree = "<group>"; };
14F3B0F615E45E4600210069 /* SaturatedArithmetic.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SaturatedArithmetic.h; sourceTree = "<group>"; };
26147B0815DDCCDC00DDB907 /* IntegerToStringConversion.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = IntegerToStringConversion.h; sourceTree = "<group>"; };
+ 2661122D160FEAD40013F5C3 /* URLQueryCharsetConverter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = URLQueryCharsetConverter.h; sourceTree = "<group>"; };
+ 26E6C1CE1609037300CA6AF4 /* URLCanonEtc.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = URLCanonEtc.cpp; sourceTree = "<group>"; };
+ 26E6C1CF1609037300CA6AF4 /* URLCanonFilesystemurl.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = URLCanonFilesystemurl.cpp; sourceTree = "<group>"; };
+ 26E6C1D01609037300CA6AF4 /* URLCanonFileurl.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = URLCanonFileurl.cpp; sourceTree = "<group>"; };
+ 26E6C1D11609037300CA6AF4 /* URLCanonHost.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = URLCanonHost.cpp; sourceTree = "<group>"; };
+ 26E6C1D21609037300CA6AF4 /* URLCanonICU.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = URLCanonICU.cpp; sourceTree = "<group>"; };
+ 26E6C1D51609037300CA6AF4 /* URLCanonInternal.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = URLCanonInternal.cpp; sourceTree = "<group>"; };
+ 26E6C1D61609037300CA6AF4 /* URLCanonInternal.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = URLCanonInternal.h; sourceTree = "<group>"; };
+ 26E6C1D71609037300CA6AF4 /* URLCanonIP.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = URLCanonIP.cpp; sourceTree = "<group>"; };
+ 26E6C1D91609037300CA6AF4 /* URLCanonMailto.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = URLCanonMailto.cpp; sourceTree = "<group>"; };
+ 26E6C1DA1609037300CA6AF4 /* URLCanonPath.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = URLCanonPath.cpp; sourceTree = "<group>"; };
+ 26E6C1DB1609037300CA6AF4 /* URLCanonPathurl.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = URLCanonPathurl.cpp; sourceTree = "<group>"; };
+ 26E6C1DC1609037300CA6AF4 /* URLCanonQuery.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = URLCanonQuery.cpp; sourceTree = "<group>"; };
+ 26E6C1DD1609037300CA6AF4 /* URLCanonRelative.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = URLCanonRelative.cpp; sourceTree = "<group>"; };
+ 26E6C1DF1609037300CA6AF4 /* URLCanonStdURL.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = URLCanonStdURL.cpp; sourceTree = "<group>"; };
+ 26E6C1E11609037300CA6AF4 /* URLCanon.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = URLCanon.h; sourceTree = "<group>"; };
+ 26E6C1E31609037300CA6AF4 /* URLFile.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = URLFile.h; sourceTree = "<group>"; };
+ 26E6C1E41609037300CA6AF4 /* URLParseFile.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = URLParseFile.cpp; sourceTree = "<group>"; };
+ 26E6C1E51609037300CA6AF4 /* URLParseInternal.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = URLParseInternal.h; sourceTree = "<group>"; };
+ 26E6C1E71609037300CA6AF4 /* URLParse.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = URLParse.cpp; sourceTree = "<group>"; };
+ 26E6C1E81609037300CA6AF4 /* URLParse.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = URLParse.h; sourceTree = "<group>"; };
+ 26E6C1EA1609037300CA6AF4 /* URLUtilInternal.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = URLUtilInternal.h; sourceTree = "<group>"; };
+ 26E6C1EC1609037300CA6AF4 /* URLUtil.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = URLUtil.cpp; sourceTree = "<group>"; };
+ 26E6C1ED1609037300CA6AF4 /* URLUtil.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = URLUtil.h; sourceTree = "<group>"; };
2C05385315BC819000F21B96 /* GregorianDateTime.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GregorianDateTime.h; sourceTree = "<group>"; };
2CCD892915C0390200285083 /* GregorianDateTime.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = GregorianDateTime.cpp; sourceTree = "<group>"; };
4330F38E15745B0500AAFA8F /* URLString.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = URLString.cpp; sourceTree = "<group>"; };
4F0321BB156AA8D1006EBAF6 /* BitArray.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BitArray.h; sourceTree = "<group>"; };
4F1D115315FF11BE0026E908 /* MemoryInstrumentation.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MemoryInstrumentation.h; sourceTree = "<group>"; };
+ 4FCB7109160A1A07008425EC /* MemoryInstrumentationVector.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MemoryInstrumentationVector.h; sourceTree = "<group>"; };
5D247B6214689B8600E78B76 /* libWTF.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libWTF.a; sourceTree = BUILT_PRODUCTS_DIR; };
5D247B6E14689C4700E78B76 /* Base.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = Base.xcconfig; sourceTree = "<group>"; };
5D247B6F14689C4700E78B76 /* CompilerVersion.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = CompilerVersion.xcconfig; sourceTree = "<group>"; };
@@ -494,10 +540,6 @@
A8A47366151A825B004123FF /* URLCharacterTypes.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = URLCharacterTypes.cpp; sourceTree = "<group>"; };
A8A47367151A825B004123FF /* URLCharacterTypes.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = URLCharacterTypes.h; sourceTree = "<group>"; };
A8A47368151A825B004123FF /* URLComponent.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = URLComponent.h; sourceTree = "<group>"; };
- A8A47369151A825B004123FF /* URLEscape.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = URLEscape.cpp; sourceTree = "<group>"; };
- A8A4736A151A825B004123FF /* URLEscape.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = URLEscape.h; sourceTree = "<group>"; };
- A8A4736B151A825B004123FF /* URLParser.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = URLParser.h; sourceTree = "<group>"; };
- A8A4736C151A825B004123FF /* URLQueryCanonicalizer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = URLQueryCanonicalizer.h; sourceTree = "<group>"; };
A8A4736D151A825B004123FF /* URLSegments.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = URLSegments.cpp; sourceTree = "<group>"; };
A8A4736E151A825B004123FF /* URLSegments.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = URLSegments.h; sourceTree = "<group>"; };
A8A4736F151A825B004123FF /* ValueCheck.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ValueCheck.h; sourceTree = "<group>"; };
@@ -650,6 +692,7 @@
CD5497AA15857D0300B5BC30 /* MediaTime.cpp */,
CD5497AB15857D0300B5BC30 /* MediaTime.h */,
4F1D115315FF11BE0026E908 /* MemoryInstrumentation.h */,
+ 4FCB7109160A1A07008425EC /* MemoryInstrumentationVector.h */,
A8A472CC151A825B004123FF /* MessageQueue.h */,
A8A472CD151A825B004123FF /* MetaAllocator.cpp */,
A8A472CE151A825B004123FF /* MetaAllocator.h */,
@@ -862,6 +905,8 @@
children = (
A8A47360151A825B004123FF /* ParsedURL.cpp */,
A8A47361151A825B004123FF /* ParsedURL.h */,
+ A8A47365151A825B004123FF /* URLBuffer.h */,
+ 2661122D160FEAD40013F5C3 /* URLQueryCharsetConverter.h */,
4330F38E15745B0500AAFA8F /* URLString.cpp */,
A8A47362151A825B004123FF /* URLString.h */,
);
@@ -872,16 +917,34 @@
isa = PBXGroup;
children = (
A8A47364151A825B004123FF /* RawURLBuffer.h */,
- A8A47365151A825B004123FF /* URLBuffer.h */,
+ 26E6C1E11609037300CA6AF4 /* URLCanon.h */,
+ 26E6C1CE1609037300CA6AF4 /* URLCanonEtc.cpp */,
+ 26E6C1CF1609037300CA6AF4 /* URLCanonFilesystemurl.cpp */,
+ 26E6C1D01609037300CA6AF4 /* URLCanonFileurl.cpp */,
+ 26E6C1D11609037300CA6AF4 /* URLCanonHost.cpp */,
+ 26E6C1D21609037300CA6AF4 /* URLCanonICU.cpp */,
+ 26E6C1D51609037300CA6AF4 /* URLCanonInternal.cpp */,
+ 26E6C1D61609037300CA6AF4 /* URLCanonInternal.h */,
+ 26E6C1D71609037300CA6AF4 /* URLCanonIP.cpp */,
+ 26E6C1D91609037300CA6AF4 /* URLCanonMailto.cpp */,
+ 26E6C1DA1609037300CA6AF4 /* URLCanonPath.cpp */,
+ 26E6C1DB1609037300CA6AF4 /* URLCanonPathurl.cpp */,
+ 26E6C1DC1609037300CA6AF4 /* URLCanonQuery.cpp */,
+ 26E6C1DD1609037300CA6AF4 /* URLCanonRelative.cpp */,
+ 26E6C1DF1609037300CA6AF4 /* URLCanonStdURL.cpp */,
A8A47366151A825B004123FF /* URLCharacterTypes.cpp */,
A8A47367151A825B004123FF /* URLCharacterTypes.h */,
A8A47368151A825B004123FF /* URLComponent.h */,
- A8A47369151A825B004123FF /* URLEscape.cpp */,
- A8A4736A151A825B004123FF /* URLEscape.h */,
- A8A4736B151A825B004123FF /* URLParser.h */,
- A8A4736C151A825B004123FF /* URLQueryCanonicalizer.h */,
+ 26E6C1E31609037300CA6AF4 /* URLFile.h */,
+ 26E6C1E71609037300CA6AF4 /* URLParse.cpp */,
+ 26E6C1E81609037300CA6AF4 /* URLParse.h */,
+ 26E6C1E41609037300CA6AF4 /* URLParseFile.cpp */,
+ 26E6C1E51609037300CA6AF4 /* URLParseInternal.h */,
A8A4736D151A825B004123FF /* URLSegments.cpp */,
A8A4736E151A825B004123FF /* URLSegments.h */,
+ 26E6C1EC1609037300CA6AF4 /* URLUtil.cpp */,
+ 26E6C1ED1609037300CA6AF4 /* URLUtil.h */,
+ 26E6C1EA1609037300CA6AF4 /* URLUtilInternal.h */,
);
path = src;
sourceTree = "<group>";
@@ -1062,9 +1125,6 @@
A8A47473151A825B004123FF /* URLBuffer.h in Headers */,
A8A47475151A825B004123FF /* URLCharacterTypes.h in Headers */,
A8A47476151A825B004123FF /* URLComponent.h in Headers */,
- A8A47478151A825B004123FF /* URLEscape.h in Headers */,
- A8A47479151A825B004123FF /* URLParser.h in Headers */,
- A8A4747A151A825B004123FF /* URLQueryCanonicalizer.h in Headers */,
A8A4747C151A825B004123FF /* URLSegments.h in Headers */,
A8A47471151A825B004123FF /* URLString.h in Headers */,
A8A4746A151A825B004123FF /* UTF8.h in Headers */,
@@ -1076,6 +1136,15 @@
A8A47446151A825B004123FF /* WTFString.h in Headers */,
A8A47487151A825B004123FF /* WTFThreadData.h in Headers */,
4F1D115415FF11BE0026E908 /* MemoryInstrumentation.h in Headers */,
+ 26E6C1F61609037300CA6AF4 /* URLCanonInternal.h in Headers */,
+ 26E6C2011609037300CA6AF4 /* URLCanon.h in Headers */,
+ 26E6C2031609037300CA6AF4 /* URLFile.h in Headers */,
+ 26E6C2051609037300CA6AF4 /* URLParseInternal.h in Headers */,
+ 26E6C2081609037300CA6AF4 /* URLParse.h in Headers */,
+ 2661122E160FEAD40013F5C3 /* URLQueryCharsetConverter.h in Headers */,
+ 26E6C20A1609037300CA6AF4 /* URLUtilInternal.h in Headers */,
+ 26E6C20D1609037300CA6AF4 /* URLUtil.h in Headers */,
+ 4FCB710A160A1A07008425EC /* MemoryInstrumentationVector.h in Headers */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@@ -1219,10 +1288,25 @@
A8A4744A151A825B004123FF /* Threading.cpp in Sources */,
A8A4744E151A825B004123FF /* ThreadingPthreads.cpp in Sources */,
A8A47458151A825B004123FF /* TypeTraits.cpp in Sources */,
+ 26E6C1EE1609037300CA6AF4 /* URLCanonEtc.cpp in Sources */,
+ 26E6C1EF1609037300CA6AF4 /* URLCanonFilesystemurl.cpp in Sources */,
+ 26E6C1F01609037300CA6AF4 /* URLCanonFileurl.cpp in Sources */,
+ 26E6C1F11609037300CA6AF4 /* URLCanonHost.cpp in Sources */,
+ 26E6C1F21609037300CA6AF4 /* URLCanonICU.cpp in Sources */,
+ 26E6C1F51609037300CA6AF4 /* URLCanonInternal.cpp in Sources */,
+ 26E6C1F71609037300CA6AF4 /* URLCanonIP.cpp in Sources */,
+ 26E6C1F91609037300CA6AF4 /* URLCanonMailto.cpp in Sources */,
+ 26E6C1FA1609037300CA6AF4 /* URLCanonPath.cpp in Sources */,
+ 26E6C1FB1609037300CA6AF4 /* URLCanonPathurl.cpp in Sources */,
+ 26E6C1FC1609037300CA6AF4 /* URLCanonQuery.cpp in Sources */,
+ 26E6C1FD1609037300CA6AF4 /* URLCanonRelative.cpp in Sources */,
+ 26E6C1FF1609037300CA6AF4 /* URLCanonStdURL.cpp in Sources */,
A8A47474151A825B004123FF /* URLCharacterTypes.cpp in Sources */,
- A8A47477151A825B004123FF /* URLEscape.cpp in Sources */,
+ 26E6C2041609037300CA6AF4 /* URLParseFile.cpp in Sources */,
+ 26E6C2071609037300CA6AF4 /* URLParse.cpp in Sources */,
A8A4747B151A825B004123FF /* URLSegments.cpp in Sources */,
4330F38F15745B0500AAFA8F /* URLString.cpp in Sources */,
+ 26E6C20C1609037300CA6AF4 /* URLUtil.cpp in Sources */,
A8A47469151A825B004123FF /* UTF8.cpp in Sources */,
A8A47445151A825B004123FF /* WTFString.cpp in Sources */,
A8A47486151A825B004123FF /* WTFThreadData.cpp in Sources */,
diff --git a/Source/WTF/wtf/MemoryInstrumentation.h b/Source/WTF/wtf/MemoryInstrumentation.h
index 131af8497..b1f2e294a 100644
--- a/Source/WTF/wtf/MemoryInstrumentation.h
+++ b/Source/WTF/wtf/MemoryInstrumentation.h
@@ -81,6 +81,8 @@ private:
size_t m_objectSize;
};
+template<typename T> void reportMemoryUsage(const T* const&, MemoryObjectInfo*);
+
class MemoryInstrumentation {
public:
virtual ~MemoryInstrumentation() { }
@@ -107,6 +109,7 @@ private:
virtual void processDeferredInstrumentedPointers() = 0;
friend class MemoryClassInfo;
+ template<typename T> friend void reportMemoryUsage(const T* const&, MemoryObjectInfo*);
template<typename T> static void selectInstrumentationMethod(const T* const& object, MemoryObjectInfo* memoryObjectInfo)
{
@@ -148,7 +151,6 @@ private:
template<typename MapType> void addInstrumentedMapEntries(const MapType&, MemoryObjectType);
template<typename MapType> void addInstrumentedMapValues(const MapType&, MemoryObjectType);
template<typename ListHashSetType> void addListHashSet(const ListHashSetType&, MemoryObjectType, bool contentOnly = false);
- template<typename VectorType> void addVector(const VectorType&, MemoryObjectType, bool contentOnly = false);
void addRawBuffer(const void* const& buffer, MemoryObjectType ownerObjectType, size_t size)
{
if (!buffer || visited(buffer))
@@ -194,14 +196,9 @@ public:
template<typename HashSetType> void addHashSet(const HashSetType& set) { m_memoryInstrumentation->addHashSet(set, m_objectType, true); }
template<typename HashSetType> void addHashCountedSet(const HashSetType& set) { m_memoryInstrumentation->addHashSet(set, m_objectType, true); }
template<typename HashSetType> void addInstrumentedHashSet(const HashSetType& set) { m_memoryInstrumentation->addInstrumentedCollection(set, m_objectType, true); }
- template<typename VectorType> void addInstrumentedVector(const VectorType& vector) { m_memoryInstrumentation->addInstrumentedCollection(vector, m_objectType, true); }
- template<typename VectorType> void addInstrumentedVectorPtr(const OwnPtr<VectorType>& vector) { m_memoryInstrumentation->addInstrumentedCollection(*vector, m_objectType, false); }
- template<typename VectorType> void addInstrumentedVectorPtr(const VectorType* const& vector) { m_memoryInstrumentation->addInstrumentedCollection(*vector, m_objectType, false); }
template<typename MapType> void addInstrumentedMapEntries(const MapType& map) { m_memoryInstrumentation->addInstrumentedMapEntries(map, m_objectType); }
template<typename MapType> void addInstrumentedMapValues(const MapType& map) { m_memoryInstrumentation->addInstrumentedMapValues(map, m_objectType); }
template<typename ListHashSetType> void addListHashSet(const ListHashSetType& set) { m_memoryInstrumentation->addListHashSet(set, m_objectType, true); }
- template<typename VectorType> void addVector(const VectorType& vector) { m_memoryInstrumentation->addVector(vector, m_objectType, true); }
- template<typename VectorType> void addVectorPtr(const VectorType* const vector) { m_memoryInstrumentation->addVector(*vector, m_objectType, false); }
void addRawBuffer(const void* const& buffer, size_t size) { m_memoryInstrumentation->addRawBuffer(buffer, m_objectType, size); }
void addWeakPointer(void*) { }
@@ -213,11 +210,17 @@ private:
};
template<typename T>
+void reportMemoryUsage(const T* const& object, MemoryObjectInfo* memoryObjectInfo)
+{
+ MemoryInstrumentation::selectInstrumentationMethod<T>(object, memoryObjectInfo);
+}
+
+template<typename T>
void MemoryInstrumentation::addObjectImpl(const T* const& object, MemoryObjectType ownerObjectType, MemoryOwningType owningType)
{
if (owningType == byReference) {
MemoryObjectInfo memoryObjectInfo(this, ownerObjectType);
- selectInstrumentationMethod<T>(object, &memoryObjectInfo);
+ reportMemoryUsage(object, &memoryObjectInfo);
} else {
if (!object || visited(object))
return;
@@ -295,14 +298,6 @@ void MemoryInstrumentation::addListHashSet(const ListHashSetType& hashSet, Memor
countObjectSize(ownerObjectType, size);
}
-template<typename VectorType>
-void MemoryInstrumentation::addVector(const VectorType& vector, MemoryObjectType ownerObjectType, bool contentOnly)
-{
- if (!vector.data() || visited(vector.data()))
- return;
- countObjectSize(ownerObjectType, calculateContainerSize(vector, contentOnly));
-}
-
template<typename Container>
size_t MemoryInstrumentation::calculateContainerSize(const Container& container, bool contentOnly)
{
@@ -313,10 +308,14 @@ template<typename T>
void MemoryInstrumentation::InstrumentedPointer<T>::process(MemoryInstrumentation* memoryInstrumentation)
{
MemoryObjectInfo memoryObjectInfo(memoryInstrumentation, m_ownerObjectType);
- selectInstrumentationMethod<T>(m_pointer, &memoryObjectInfo);
+ reportMemoryUsage(m_pointer, &memoryObjectInfo);
memoryInstrumentation->countObjectSize(memoryObjectInfo.objectType(), memoryObjectInfo.objectSize());
}
+// Link time guard for vector memory instrumentation.
+template<typename T, size_t inlineCapacity> class Vector;
+template<typename T, size_t inlineCapacity> void reportMemoryUsage(const Vector<T, inlineCapacity>* const&, MemoryObjectInfo*);
+
} // namespace WTF
#endif // !defined(MemoryInstrumentation_h)
diff --git a/Source/WTF/wtf/MemoryInstrumentationVector.h b/Source/WTF/wtf/MemoryInstrumentationVector.h
new file mode 100644
index 000000000..fea5cb746
--- /dev/null
+++ b/Source/WTF/wtf/MemoryInstrumentationVector.h
@@ -0,0 +1,61 @@
+/*
+ * Copyright (C) 2012 Google 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:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * 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.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND 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 THE COPYRIGHT
+ * OWNER 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 MemoryInstrumentationVector_h
+#define MemoryInstrumentationVector_h
+
+#include <wtf/MemoryInstrumentation.h>
+#include <wtf/Vector.h>
+
+namespace WTF {
+
+template<typename T, size_t inlineCapacity>
+void instrumentVectorValues(MemoryClassInfo& info, const Vector<T, inlineCapacity>* const& vector)
+{
+ for (size_t i = 0; i < vector->size(); ++i)
+ info.addMember(vector->at(i));
+}
+
+template<size_t inlineCapacity> void instrumentVectorValues(MemoryClassInfo&, const Vector<int, inlineCapacity>* const&) { }
+template<size_t inlineCapacity> void instrumentVectorValues(MemoryClassInfo&, const Vector<char, inlineCapacity>* const&) { }
+template<size_t inlineCapacity> void instrumentVectorValues(MemoryClassInfo&, const Vector<char*, inlineCapacity>* const&) { }
+
+template<typename T, size_t inlineCapacity>
+void reportMemoryUsage(const Vector<T, inlineCapacity>* const& vector, MemoryObjectInfo* memoryObjectInfo)
+{
+ MemoryClassInfo info(memoryObjectInfo, vector);
+ if (inlineCapacity < vector->capacity())
+ info.addRawBuffer(vector->data(), vector->capacity() * sizeof(T));
+ instrumentVectorValues(info, vector);
+}
+
+}
+
+#endif // !defined(MemoryInstrumentationVector_h)
diff --git a/Source/WTF/wtf/OSAllocatorPosix.cpp b/Source/WTF/wtf/OSAllocatorPosix.cpp
index f21f16aa7..a2f6a79bd 100644
--- a/Source/WTF/wtf/OSAllocatorPosix.cpp
+++ b/Source/WTF/wtf/OSAllocatorPosix.cpp
@@ -113,11 +113,11 @@ void* OSAllocator::reserveAndCommit(size_t bytes, Usage usage, bool writable, bo
result = mmap(result, bytes, protection, flags, fd, 0);
if (result == MAP_FAILED) {
- #if ENABLE(CLASSIC_INTERPRETER) || ENABLE(LLINT)
+#if ENABLE(LLINT)
if (executable)
result = 0;
else
- #endif
+#endif
CRASH();
}
if (result && includesGuardPages) {
diff --git a/Source/WTF/wtf/Platform.h b/Source/WTF/wtf/Platform.h
index 0be4bb07d..9d032dd97 100644
--- a/Source/WTF/wtf/Platform.h
+++ b/Source/WTF/wtf/Platform.h
@@ -604,11 +604,9 @@
#define WTF_USE_PTHREADS 1
#if PLATFORM(IOS_SIMULATOR)
- #define ENABLE_CLASSIC_INTERPRETER 1
#define ENABLE_JIT 0
#define ENABLE_YARR_JIT 0
#else
- #define ENABLE_CLASSIC_INTERPRETER 0
#define ENABLE_JIT 1
#define ENABLE_LLINT 1
#define ENABLE_YARR_JIT 1
@@ -641,7 +639,9 @@
#if PLATFORM(WX)
#if !CPU(PPC)
+#if !defined(ENABLE_ASSEMBLER)
#define ENABLE_ASSEMBLER 1
+#endif
#define ENABLE_JIT 1
#endif
#define ENABLE_GLOBAL_FASTMALLOC_NEW 0
@@ -953,13 +953,8 @@
#define ENABLE_WRITE_BARRIER_PROFILING 0
#endif
-/* Ensure that either the JIT or the interpreter has been enabled. */
-#if !defined(ENABLE_CLASSIC_INTERPRETER) && !ENABLE(JIT) && !ENABLE(LLINT)
-#define ENABLE_CLASSIC_INTERPRETER 1
-#endif
-
/* If the jit and classic interpreter is not available, enable the LLInt C Loop: */
-#if !ENABLE(JIT) && !ENABLE(CLASSIC_INTERPRETER)
+#if !ENABLE(JIT)
#define ENABLE_LLINT 1
#define ENABLE_LLINT_C_LOOP 1
#define ENABLE_DFG_JIT 0
@@ -967,14 +962,9 @@
/* Do a sanity check to make sure that we at least have one execution engine in
use: */
-#if !(ENABLE(JIT) || ENABLE(CLASSIC_INTERPRETER) || ENABLE(LLINT))
+#if !(ENABLE(JIT) || ENABLE(LLINT))
#error You have to have at least one execution model enabled to build JSC
#endif
-/* Do a sanity check to make sure that we don't have both the classic interpreter
- and the llint C loop in use at the same time: */
-#if ENABLE(CLASSIC_INTERPRETER) && ENABLE(LLINT_C_LOOP)
-#error You cannot build both the classic interpreter and the llint C loop together
-#endif
/* Configure the JIT */
#if CPU(X86) && COMPILER(MSVC)
@@ -989,12 +979,9 @@
#if COMPILER(GCC) || (RVCT_VERSION_AT_LEAST(4, 0, 0, 0) && defined(__GNUC__))
#define HAVE_COMPUTED_GOTO 1
#endif
-#if HAVE(COMPUTED_GOTO) && ENABLE(CLASSIC_INTERPRETER)
-#define ENABLE_COMPUTED_GOTO_CLASSIC_INTERPRETER 1
-#endif
/* Determine if we need to enable Computed Goto Opcodes or not: */
-#if (HAVE(COMPUTED_GOTO) && ENABLE(LLINT)) || ENABLE(COMPUTED_GOTO_CLASSIC_INTERPRETER)
+#if HAVE(COMPUTED_GOTO) && ENABLE(LLINT)
#define ENABLE_COMPUTED_GOTO_OPCODES 1
#endif
@@ -1009,9 +996,16 @@
#define ENABLE_YARR_JIT_DEBUG 0
#endif
+/* If either the JIT or the RegExp JIT is enabled, then the Assembler must be
+ enabled as well: */
#if ENABLE(JIT) || ENABLE(YARR_JIT)
+#if defined(ENABLE_ASSEMBLER) && !ENABLE_ASSEMBLER
+#error "Cannot enable the JIT or RegExp JIT without enabling the Assembler"
+#else
+#undef ENABLE_ASSEMBLER
#define ENABLE_ASSEMBLER 1
#endif
+#endif
/* Pick which allocator to use; we only need an executable allocator if the assembler is compiled in.
On x86-64 we use a single fixed mmap, on other platforms we mmap on demand. */
@@ -1181,10 +1175,6 @@
#define WTF_USE_ZLIB 1
#endif
-#if PLATFORM(GTK)
-#define WTF_DEPRECATED_STRING_OPERATORS
-#endif
-
#if PLATFORM(QT)
#include <qglobal.h>
#if defined(QT_OPENGL_ES_2) && !defined(WTF_USE_OPENGL_ES_2)
diff --git a/Source/WTF/wtf/gobject/GTypedefs.h b/Source/WTF/wtf/gobject/GTypedefs.h
index 2efc07233..77858d5e9 100644
--- a/Source/WTF/wtf/gobject/GTypedefs.h
+++ b/Source/WTF/wtf/gobject/GTypedefs.h
@@ -71,6 +71,11 @@ typedef struct _cairo_surface cairo_surface_t;
typedef struct _cairo_rectangle_int cairo_rectangle_int_t;
#endif
+#if USE(CLUTTER)
+typedef struct _ClutterActor ClutterActor;
+typedef struct _GraphicsLayerActor GraphicsLayerActor;
+#endif
+
#if PLATFORM(GTK)
typedef struct _GtkAction GtkAction;
typedef struct _GtkAdjustment GtkAdjustment;
diff --git a/Source/WTF/wtf/text/WTFString.h b/Source/WTF/wtf/text/WTFString.h
index c232c67ee..ef8f8da06 100644
--- a/Source/WTF/wtf/text/WTFString.h
+++ b/Source/WTF/wtf/text/WTFString.h
@@ -467,10 +467,6 @@ QDataStream& operator<<(QDataStream& stream, const String& str);
QDataStream& operator>>(QDataStream& stream, String& str);
#endif
-#ifdef WTF_DEPRECATED_STRING_OPERATORS
-inline String& operator+=(String& a, const String& b) { a.append(b); return a; }
-#endif
-
inline bool operator==(const String& a, const String& b) { return equal(a.impl(), b.impl()); }
inline bool operator==(const String& a, const LChar* b) { return equal(a.impl(), b); }
inline bool operator==(const String& a, const char* b) { return equal(a.impl(), reinterpret_cast<const LChar*>(b)); }
diff --git a/Source/WTF/wtf/url/api/ParsedURL.cpp b/Source/WTF/wtf/url/api/ParsedURL.cpp
index 0b15fcbca..c700dd59b 100644
--- a/Source/WTF/wtf/url/api/ParsedURL.cpp
+++ b/Source/WTF/wtf/url/api/ParsedURL.cpp
@@ -33,60 +33,96 @@
#include <wtf/MemoryInstrumentation.h>
#include <wtf/RawURLBuffer.h>
#include <wtf/URLComponent.h>
-#include <wtf/URLParser.h>
+#include <wtf/URLUtil.h>
+#include <wtf/text/CString.h>
namespace WTF {
-ParsedURL::ParsedURL(const String& urlString)
+ParsedURL::ParsedURL(const String& urlString, ParsedURLStringTag)
{
- if (urlString.isEmpty()) {
- m_spec = URLString();
+ unsigned urlStringLength = urlString.length();
+ if (!urlStringLength)
+ return; // FIXME: we should ASSERT on this, but people use KURL incorrectly with ParsedURLStringTag :(.
+
+ RawURLBuffer<char> outputBuffer;
+ String base;
+ const CString& baseStr = base.utf8();
+ bool isValid = false;
+ URLSegments baseSegments;
+
+ // FIXME: we should take shortcuts here! We do not have to resolve the relative part.
+ if (urlString.is8Bit())
+ isValid = URLUtilities::resolveRelative(baseStr.data(), baseSegments,
+ reinterpret_cast<const char*>(urlString.characters8()), urlStringLength,
+ /* charsetConverter */ 0,
+ outputBuffer, &m_segments);
+ else
+ isValid = URLUtilities::resolveRelative(baseStr.data(), baseSegments,
+ urlString.characters16(), urlStringLength,
+ /* charsetConverter */ 0,
+ outputBuffer, &m_segments);
+
+ // FIXME: we should ASSERT on isValid, but people use KURL incorrectly with ParsedURLStringTag :(.
+ if (isValid)
+ m_spec = URLString(String(outputBuffer.data(), outputBuffer.length()));
+}
+
+ParsedURL::ParsedURL(const String& urlString, URLQueryCharsetConverter* queryCharsetConverter)
+{
+ unsigned urlStringLength = urlString.length();
+ if (!urlStringLength)
return;
- }
- // FIXME: handle invalid urlString.
- m_spec = URLString(urlString);
+ RawURLBuffer<char> outputBuffer;
+ String base;
+ const CString& baseStr = base.utf8();
+ bool isValid = false;
+ URLSegments baseSegments;
+
+ // FIXME: we should take shortcuts here! We do not have to resolve the relative part.
if (urlString.is8Bit())
- URLParser<LChar>::parseStandardURL(urlString.characters8(), urlString.length(), m_segments);
+ isValid = URLUtilities::resolveRelative(baseStr.data(), baseSegments,
+ reinterpret_cast<const char*>(urlString.characters8()), urlStringLength,
+ queryCharsetConverter,
+ outputBuffer, &m_segments);
else
- URLParser<UChar>::parseStandardURL(urlString.characters16(), urlString.length(), m_segments);
+ isValid = URLUtilities::resolveRelative(baseStr.data(), baseSegments,
+ urlString.characters16(), urlStringLength,
+ queryCharsetConverter,
+ outputBuffer, &m_segments);
+
+ if (isValid)
+ m_spec = URLString(String(outputBuffer.data(), outputBuffer.length()));
}
-ParsedURL::ParsedURL(const ParsedURL& base, const String& relative)
+ParsedURL::ParsedURL(const ParsedURL& base, const String& relative, URLQueryCharsetConverter* queryCharsetConverter)
{
if (!base.isValid())
return;
- if (relative.isEmpty()) {
+ unsigned relativeLength = relative.length();
+ if (!relativeLength) {
*this = base.withoutFragment();
return;
}
- // FIXME: handle invalid URLs.
- const String& baseString = base.m_spec.string();
- RawURLBuffer<char, 1024> outputBuffer;
- if (relative.is8Bit()) {
- if (baseString.is8Bit()) {
- URLParser<LChar, LChar>::parseURLWithBase(relative.characters8(), relative.length(),
- baseString.characters8(), baseString.length(), base.m_segments,
- outputBuffer, m_segments);
- } else {
- URLParser<LChar, UChar>::parseURLWithBase(relative.characters8(), relative.length(),
- baseString.characters16(), baseString.length(), base.m_segments,
- outputBuffer, m_segments);
- }
- } else {
- if (baseString.is8Bit()) {
- URLParser<UChar, LChar>::parseURLWithBase(relative.characters16(), relative.length(),
- baseString.characters8(), baseString.length(), base.m_segments,
- outputBuffer, m_segments);
- } else {
- URLParser<UChar, UChar>::parseURLWithBase(relative.characters16(), relative.length(),
- baseString.characters16(), baseString.length(), base.m_segments,
- outputBuffer, m_segments);
- }
- }
- m_spec = URLString(String(outputBuffer.data(), outputBuffer.length()));
+ RawURLBuffer<char> outputBuffer;
+ const CString& baseStr = base.m_spec.m_string.utf8();
+ bool isValid = false;
+
+ if (relative.is8Bit())
+ isValid = URLUtilities::resolveRelative(baseStr.data(), base.m_segments,
+ reinterpret_cast<const char*>(relative.characters8()), relativeLength,
+ queryCharsetConverter,
+ outputBuffer, &m_segments);
+ else
+ isValid = URLUtilities::resolveRelative(baseStr.data(), base.m_segments,
+ relative.characters16(), relativeLength,
+ queryCharsetConverter,
+ outputBuffer, &m_segments);
+
+ if (isValid)
+ m_spec = URLString(String(outputBuffer.data(), outputBuffer.length()));
}
ParsedURL ParsedURL::isolatedCopy() const
@@ -171,7 +207,9 @@ String ParsedURL::segment(const URLComponent& component) const
return String();
String segment = m_spec.string().substring(component.begin(), component.length());
- ASSERT_WITH_MESSAGE(!segment.isEmpty(), "A valid URL component should not be empty.");
+
+ // FIXME: GoogleURL create empty segments. This happen for the fragment for the test fast/url/segments.html
+ // ASSERT_WITH_MESSAGE(!segment.isEmpty(), "A valid URL component should not be empty.");
return segment;
}
diff --git a/Source/WTF/wtf/url/api/ParsedURL.h b/Source/WTF/wtf/url/api/ParsedURL.h
index 0603cf116..79a72dd2d 100644
--- a/Source/WTF/wtf/url/api/ParsedURL.h
+++ b/Source/WTF/wtf/url/api/ParsedURL.h
@@ -35,17 +35,22 @@
namespace WTF {
class URLComponent;
+class URLQueryCharsetConverter;
// ParsedURL represents a valid URL decomposed by components.
class ParsedURL {
public:
+ enum ParsedURLStringTag { ParsedURLString };
+
ParsedURL() { };
- WTF_EXPORT_PRIVATE explicit ParsedURL(const String&);
- WTF_EXPORT_PRIVATE explicit ParsedURL(const ParsedURL& base, const String& relative);
+ WTF_EXPORT_PRIVATE explicit ParsedURL(const String&, ParsedURLStringTag);
+
+ WTF_EXPORT_PRIVATE explicit ParsedURL(const String&, URLQueryCharsetConverter*);
+ WTF_EXPORT_PRIVATE explicit ParsedURL(const ParsedURL& base, const String& relative, URLQueryCharsetConverter*);
WTF_EXPORT_PRIVATE ParsedURL isolatedCopy() const;
- bool isValid() const { return !m_spec.string().isEmpty(); }
+ bool isValid() const { return !m_spec.string().isNull(); }
// Return a URL component or a null String if the component is undefined for the URL.
WTF_EXPORT_PRIVATE String scheme() const;
diff --git a/Source/WTF/wtf/url/src/URLBuffer.h b/Source/WTF/wtf/url/api/URLBuffer.h
index 84a4f85c2..6eccd04fa 100644
--- a/Source/WTF/wtf/url/src/URLBuffer.h
+++ b/Source/WTF/wtf/url/api/URLBuffer.h
@@ -1,30 +1,32 @@
-// Copyright 2010, Google 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:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * 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.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND 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 THE COPYRIGHT
-// OWNER 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.
+/*
+ * Copyright 2010 Google 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:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * 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.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND 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 THE COPYRIGHT
+ * OWNER 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 URLBuffer_h
#define URLBuffer_h
diff --git a/Source/WTF/wtf/url/api/URLQueryCharsetConverter.h b/Source/WTF/wtf/url/api/URLQueryCharsetConverter.h
new file mode 100644
index 000000000..5771a42e4
--- /dev/null
+++ b/Source/WTF/wtf/url/api/URLQueryCharsetConverter.h
@@ -0,0 +1,54 @@
+/*
+ * Copyright 2007 Google Inc. All rights reserved.
+ * Copyright 2012 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:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * 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.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND 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 THE COPYRIGHT
+ * OWNER 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 URLQueryCharsetConverter_h
+#define URLQueryCharsetConverter_h
+
+#include <wtf/unicode/Unicode.h>
+
+#if USE(WTFURL)
+
+namespace WTF {
+
+template<typename CharacterType> class URLBuffer;
+
+class URLQueryCharsetConverter {
+public:
+ URLQueryCharsetConverter() { }
+ virtual ~URLQueryCharsetConverter() { }
+ virtual void convertFromUTF16(const UChar* input, unsigned inputLength, URLBuffer<char>& output) = 0;
+};
+
+} // namespace WTF
+
+#endif // USE(WTFURL)
+
+#endif // URLQueryCharsetConverter_h
diff --git a/Source/WTF/wtf/url/src/RawURLBuffer.h b/Source/WTF/wtf/url/src/RawURLBuffer.h
index 59a7f18af..e6f238c29 100644
--- a/Source/WTF/wtf/url/src/RawURLBuffer.h
+++ b/Source/WTF/wtf/url/src/RawURLBuffer.h
@@ -1,30 +1,32 @@
-// Copyright 2010, Google 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:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * 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.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND 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 THE COPYRIGHT
-// OWNER 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.
+/*
+ * Copyright 2010 Google 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:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * 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.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND 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 THE COPYRIGHT
+ * OWNER 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 RawURLBuffer_h
#define RawURLBuffer_h
@@ -32,6 +34,7 @@
#if USE(WTFURL)
#include "URLBuffer.h"
+#include <string.h>
namespace WTF {
diff --git a/Source/WTF/wtf/url/src/URLCanon.h b/Source/WTF/wtf/url/src/URLCanon.h
new file mode 100644
index 000000000..d1e2b1caa
--- /dev/null
+++ b/Source/WTF/wtf/url/src/URLCanon.h
@@ -0,0 +1,617 @@
+/*
+ * Copyright 2007 Google Inc. All rights reserved.
+ * Copyright 2012 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:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * 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.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND 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 THE COPYRIGHT
+ * OWNER 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 URLCanon_h
+#define URLCanon_h
+
+#include "URLBuffer.h"
+#include "URLParse.h"
+#include <stdlib.h>
+#include <wtf/unicode/Unicode.h>
+
+#if USE(WTFURL)
+
+namespace WTF {
+
+class URLQueryCharsetConverter;
+
+namespace URLCanonicalizer {
+
+// Whitespace -----------------------------------------------------------------
+
+// Searches for whitespace that should be removed from the middle of URLs, and
+// removes it. Removed whitespace are tabs and newlines, but NOT spaces. Spaces
+// are preserved, which is what most browsers do. A pointer to the output will
+// be returned, and the length of that output will be in |outputLength|.
+//
+// This should be called before parsing if whitespace removal is desired (which
+// it normally is when you are canonicalizing).
+//
+// If no whitespace is removed, this function will not use the buffer and will
+// return a pointer to the input, to avoid the extra copy. If modification is
+// required, the given |buffer| will be used and the returned pointer will
+// point to the beginning of the buffer.
+//
+// Therefore, callers should not use the buffer, since it may actuall be empty,
+// use the computed pointer and |outputLength| instead.
+const char* removeURLWhitespace(const char* input, int inputLength, URLBuffer<char>&, int& outputLength);
+const UChar* removeURLWhitespace(const UChar* input, int inputLength, URLBuffer<UChar>&, int& outputLength);
+
+// IDN ------------------------------------------------------------------------
+
+// Converts the Unicode input representing a hostname to ASCII using IDN rules.
+// The output must fall in the ASCII range, but will be encoded in UTF-16.
+//
+// On success, the output will be filled with the ASCII host name and it will
+// return true. Unlike most other canonicalization functions, this assumes that
+// the output is empty. The beginning of the host will be at offset 0, and
+// the length of the output will be set to the length of the new host name.
+//
+// On error, returns false. The output in this case is undefined.
+bool IDNToASCII(const UChar* src, int sourceLength, URLBuffer<UChar>& output);
+
+// Piece-by-piece canonicalizers ----------------------------------------------
+//
+// These individual canonicalizers append the canonicalized versions of the
+// corresponding URL component to the given std::string. The spec and the
+// previously-identified range of that component are the input. The range of
+// the canonicalized component will be written to the output component.
+//
+// These functions all append to the output so they can be chained. Make sure
+// the output is empty when you start.
+//
+// These functions returns boolean values indicating success. On failure, they
+// will attempt to write something reasonable to the output so that, if
+// displayed to the user, they will recognise it as something that's messed up.
+// Nothing more should ever be done with these invalid URLs, however.
+
+// Scheme: Appends the scheme and colon to the URL. The output component will
+// indicate the range of characters up to but not including the colon.
+//
+// Canonical URLs always have a scheme. If the scheme is not present in the
+// input, this will just write the colon to indicate an empty scheme. Does not
+// append slashes which will be needed before any authority components for most
+// URLs.
+//
+// The 8-bit version requires UTF-8 encoding.
+bool canonicalizeScheme(const char* spec, const URLComponent& scheme, URLBuffer<char>&, URLComponent& ouputScheme);
+bool canonicalizeScheme(const UChar* spec, const URLComponent& scheme, URLBuffer<char>&, URLComponent& ouputScheme);
+
+// User info: username/password. If present, this will add the delimiters so
+// the output will be "<username>:<password>@" or "<username>@". Empty
+// username/password pairs, or empty passwords, will get converted to
+// nonexistant in the canonical version.
+//
+// The components for the username and password refer to ranges in the
+// respective source strings. Usually, these will be the same string, which
+// is legal as long as the two components don't overlap.
+//
+// The 8-bit version requires UTF-8 encoding.
+bool canonicalizeUserInfo(const char* usernameSource, const URLComponent& username, const char* passwordSource, const URLComponent& password,
+ URLBuffer<char>&, URLComponent& outputUsername, URLComponent& outputPassword);
+bool canonicalizeUserInfo(const UChar* usernameSource, const URLComponent& username, const UChar* passwordSource, const URLComponent& password,
+ URLBuffer<char>&, URLComponent& outputUsername, URLComponent& outputPassword);
+
+
+// This structure holds detailed state exported from the IP/Host canonicalizers.
+// Additional fields may be added as callers require them.
+struct CanonHostInfo {
+ CanonHostInfo()
+ : family(NEUTRAL)
+ , ipv4ComponentsCount(0)
+ , ouputHost()
+ {
+ }
+
+ // Convenience function to test if family is an IP address.
+ bool IsIPAddress() const { return family == IPV4 || family == IPV6; }
+
+ // This field summarizes how the input was classified by the canonicalizer.
+ enum Family {
+ // - Doesn't resemble an IP address. As far as the IP
+ // canonicalizer is concerned, it should be treated as a
+ // hostname.
+ NEUTRAL,
+
+ // - Almost an IP, but was not canonicalized. This could be an
+ // IPv4 address where truncation occurred, or something
+ // containing the special characters :[] which did not parse
+ // as an IPv6 address. Never attempt to connect to this
+ // address, because it might actually succeed!
+ BROKEN,
+
+ IPV4, // - Successfully canonicalized as an IPv4 address.
+ IPV6, // - Successfully canonicalized as an IPv6 address.
+ };
+ Family family;
+
+ // If |family| is IPV4, then this is the number of nonempty dot-separated
+ // components in the input text, from 1 to 4. If |family| is not IPV4,
+ // this value is undefined.
+ int ipv4ComponentsCount;
+
+ // Location of host within the canonicalized output.
+ // canonicalizeIPAddress() only sets this field if |family| is IPV4 or IPV6.
+ URLComponent ouputHost;
+
+ // |address| contains the parsed IP Address (if any) in its first
+ // AddressLength() bytes, in network order. If IsIPAddress() is false
+ // AddressLength() will return zero and the content of |address| is undefined.
+ unsigned char address[16];
+
+ // Convenience function to calculate the length of an IP address corresponding
+ // to the current IP version in |family|, if any. For use with |address|.
+ int AddressLength() const
+ {
+ return family == IPV4 ? 4 : (family == IPV6 ? 16 : 0);
+ }
+};
+
+// Host.
+//
+// The 8-bit version requires UTF-8 encoding. Use this version when you only
+// need to know whether canonicalization succeeded.
+bool canonicalizeHost(const char* spec, const URLComponent& host, URLBuffer<char>&, URLComponent& ouputHost);
+bool canonicalizeHost(const UChar* spec, const URLComponent& host, URLBuffer<char>&, URLComponent& ouputHost);
+
+// IP addresses.
+//
+// Tries to interpret the given host name as an IPv4 or IPv6 address. If it is
+// an IP address, it will canonicalize it as such, appending it to |output|.
+// Additional status information is returned via the |*hostInfo| parameter.
+// See the definition of CanonHostInfo above for details.
+//
+// This is called AUTOMATICALLY from the host canonicalizer, which ensures that
+// the input is unescaped and name-prepped, etc. It should not normally be
+// necessary or wise to call this directly.
+void canonicalizeIPAddress(const char* spec, const URLComponent& host, URLBuffer<char>&, CanonHostInfo&);
+void canonicalizeIPAddress(const UChar* spec, const URLComponent& host, URLBuffer<char>&, CanonHostInfo&);
+
+// Port: this function will add the colon for the port if a port is present.
+// The caller can pass URLParser::PORT_UNSPECIFIED as the
+// defaultPortForScheme argument if there is no default port.
+//
+// The 8-bit version requires UTF-8 encoding.
+bool canonicalizePort(const char* spec, const URLComponent& port, int defaultPortForScheme, URLBuffer<char>&, URLComponent& ouputPort);
+bool canonicalizePort(const UChar* spec, const URLComponent& port, int defaultPortForScheme, URLBuffer<char>&, URLComponent& ouputPort);
+
+// Returns the default port for the given canonical scheme, or PORT_UNSPECIFIED
+// if the scheme is unknown.
+int defaultPortForScheme(const char* scheme, int schemeLength);
+
+// Path. If the input does not begin in a slash (including if the input is
+// empty), we'll prepend a slash to the path to make it canonical.
+//
+// The 8-bit version assumes UTF-8 encoding, but does not verify the validity
+// of the UTF-8 (i.e., you can have invalid UTF-8 sequences, invalid
+// characters, etc.). Normally, URLs will come in as UTF-16, so this isn't
+// an issue. Somebody giving us an 8-bit path is responsible for generating
+// the path that the server expects (we'll escape high-bit characters), so
+// if something is invalid, it's their problem.
+bool CanonicalizePath(const char* spec, const URLComponent& path, URLBuffer<char>&, URLComponent* outputPath);
+bool CanonicalizePath(const UChar* spec, const URLComponent& path, URLBuffer<char>&, URLComponent* outputPath);
+
+// Canonicalizes the input as a file path. This is like CanonicalizePath except
+// that it also handles Windows drive specs. For example, the path can begin
+// with "c|\" and it will get properly canonicalized to "C:/".
+// The string will be appended to |output| and |outputPath| will be updated.
+//
+// The 8-bit version requires UTF-8 encoding.
+bool FileCanonicalizePath(const char* spec, const URLComponent& path, URLBuffer<char>&, URLComponent* outputPath);
+bool FileCanonicalizePath(const UChar* spec, const URLComponent& path, URLBuffer<char>&, URLComponent* outputPath);
+
+// Query: Prepends the ? if needed.
+//
+// The 8-bit version requires the input to be UTF-8 encoding. Incorrectly
+// encoded characters (in UTF-8 or UTF-16) will be replaced with the Unicode
+// "invalid character." This function can not fail, we always just try to do
+// our best for crazy input here since web pages can set it themselves.
+//
+// This will convert the given input into the output encoding that the given
+// character set converter object provides. The converter will only be called
+// if necessary, for ASCII input, no conversions are necessary.
+//
+// The converter can be null. In this case, the output encoding will be UTF-8.
+void CanonicalizeQuery(const char* spec, const URLComponent& query, URLQueryCharsetConverter*, URLBuffer<char>&, URLComponent* outputQuery);
+void CanonicalizeQuery(const UChar* spec, const URLComponent& query, URLQueryCharsetConverter*, URLBuffer<char>&, URLComponent* outputQuery);
+
+// Ref: Prepends the # if needed. The output will be UTF-8 (this is the only
+// canonicalizer that does not produce ASCII output). The output is
+// guaranteed to be valid UTF-8.
+//
+// This function will not fail. If the input is invalid UTF-8/UTF-16, we'll use
+// the "Unicode replacement character" for the confusing bits and copy the rest.
+void canonicalizeFragment(const char* spec, const URLComponent& path, URLBuffer<char>&, URLComponent& outputFragment);
+void canonicalizeFragment(const UChar* spec, const URLComponent& path, URLBuffer<char>&, URLComponent& outputFragment);
+
+// Full canonicalizer ---------------------------------------------------------
+//
+// These functions replace any string contents, rather than append as above.
+// See the above piece-by-piece functions for information specific to
+// canonicalizing individual components.
+//
+// The output will be ASCII except the reference fragment, which may be UTF-8.
+//
+// The 8-bit versions require UTF-8 encoding.
+
+// Use for standard URLs with authorities and paths.
+bool CanonicalizeStandardURL(const char* spec, int specLength, const URLSegments& parsed, URLQueryCharsetConverter* queryConverter,
+ URLBuffer<char>&, URLSegments* outputParsed);
+bool CanonicalizeStandardURL(const UChar* spec, int specLength, const URLSegments& parsed, URLQueryCharsetConverter* queryConverter,
+ URLBuffer<char>&, URLSegments* outputParsed);
+
+// Use for file URLs.
+bool CanonicalizeFileURL(const char* spec, int specLength, const URLSegments& parsed, URLQueryCharsetConverter* queryConverter,
+ URLBuffer<char>&, URLSegments* outputParsed);
+bool CanonicalizeFileURL(const UChar* spec, int specLength, const URLSegments& parsed, URLQueryCharsetConverter* queryConverter,
+ URLBuffer<char>&, URLSegments* outputParsed);
+
+// Use for filesystem URLs.
+bool canonicalizeFileSystemURL(const char* spec, const URLSegments& parsed, URLQueryCharsetConverter* queryConverter,
+ URLBuffer<char>&, URLSegments& outputParsed);
+bool canonicalizeFileSystemURL(const UChar* spec, const URLSegments& parsed, URLQueryCharsetConverter* queryConverter,
+ URLBuffer<char>&, URLSegments& outputParsed);
+
+// Use for path URLs such as javascript. This does not modify the path in any
+// way, for example, by escaping it.
+bool canonicalizePathURL(const char* spec, const URLSegments& parsed, URLBuffer<char>& output, URLSegments& ouputParsed);
+bool canonicalizePathURL(const UChar* spec, const URLSegments& parsed, URLBuffer<char>& output, URLSegments& ouputParsed);
+
+// Use for mailto URLs. This "canonicalizes" the url into a path and query
+// component. It does not attempt to merge "to" fields. It uses UTF-8 for
+// the query encoding if there is a query. This is because a mailto URL is
+// really intended for an external mail program, and the encoding of a page,
+// etc. which would influence a query encoding normally are irrelevant.
+bool canonicalizeMailtoURL(const char* spec, const URLSegments& parsed, URLBuffer<char>&, URLSegments& outputParsed);
+bool canonicalizeMailtoURL(const UChar* spec, const URLSegments& parsed, URLBuffer<char>&, URLSegments& outputParsed);
+
+// Part replacer --------------------------------------------------------------
+
+// Internal structure used for storing separate strings for each component.
+// The basic canonicalization functions use this structure internally so that
+// component replacement (different strings for different components) can be
+// treated on the same code path as regular canonicalization (the same string
+// for each component).
+//
+// A URLSegments structure usually goes along with this. Those
+// components identify offsets within these strings, so that they can all be
+// in the same string, or spread arbitrarily across different ones.
+//
+// This structures does not own any data. It is the caller's responsibility to
+// ensure that the data the pointers point to stays in scope and is not
+// modified.
+template<typename CharacterType>
+struct URLComponentSource {
+ // Constructor normally used by callers wishing to replace components. This
+ // will make them all null, which is no replacement. The caller would then
+ // override the components they want to replace.
+ URLComponentSource()
+ : scheme(0)
+ , username(0)
+ , password(0)
+ , host(0)
+ , port(0)
+ , path(0)
+ , query(0)
+ , ref(0)
+ {
+ }
+
+ // Constructor normally used internally to initialize all the components to
+ // point to the same spec.
+ explicit URLComponentSource(const CharacterType* defaultValue)
+ : scheme(defaultValue)
+ , username(defaultValue)
+ , password(defaultValue)
+ , host(defaultValue)
+ , port(defaultValue)
+ , path(defaultValue)
+ , query(defaultValue)
+ , ref(defaultValue)
+ {
+ }
+
+ const CharacterType* scheme;
+ const CharacterType* username;
+ const CharacterType* password;
+ const CharacterType* host;
+ const CharacterType* port;
+ const CharacterType* path;
+ const CharacterType* query;
+ const CharacterType* ref;
+};
+
+// This structure encapsulates information on modifying a URL. Each component
+// may either be left unchanged, replaced, or deleted.
+//
+// By default, each component is unchanged. For those components that should be
+// modified, call either Set* or Clear* to modify it.
+//
+// The string passed to Set* functions DOES NOT GET COPIED AND MUST BE KEPT
+// IN SCOPE BY THE CALLER for as long as this object exists!
+//
+// Prefer the 8-bit replacement version if possible since it is more efficient.
+template<typename CharacterType>
+class Replacements {
+public:
+ Replacements()
+ {
+ }
+
+ // Scheme
+ void SetScheme(const CharacterType* s, const URLComponent& comp)
+ {
+ m_sources.scheme = s;
+ m_segments.scheme = comp;
+ }
+ // Note: we don't have a ClearScheme since this doesn't make any sense.
+ bool IsSchemeOverridden() const { return !!m_sources.scheme; }
+
+ // Username
+ void SetUsername(const CharacterType* s, const URLComponent& comp)
+ {
+ m_sources.username = s;
+ m_segments.username = comp;
+ }
+ void ClearUsername()
+ {
+ m_sources.username = Placeholder();
+ m_segments.username = URLComponent();
+ }
+ bool IsUsernameOverridden() const { return !!m_sources.username; }
+
+ // Password
+ void SetPassword(const CharacterType* s, const URLComponent& comp)
+ {
+ m_sources.password = s;
+ m_segments.password = comp;
+ }
+ void ClearPassword()
+ {
+ m_sources.password = Placeholder();
+ m_segments.password = URLComponent();
+ }
+ bool IsPasswordOverridden() const { return !!m_sources.password; }
+
+ // Host
+ void SetHost(const CharacterType* s, const URLComponent& comp)
+ {
+ m_sources.host = s;
+ m_segments.host = comp;
+ }
+ void ClearHost()
+ {
+ m_sources.host = Placeholder();
+ m_segments.host = URLComponent();
+ }
+ bool IsHostOverridden() const { return !!m_sources.host; }
+
+ // Port
+ void SetPort(const CharacterType* s, const URLComponent& comp)
+ {
+ m_sources.port = s;
+ m_segments.port = comp;
+ }
+ void ClearPort()
+ {
+ m_sources.port = Placeholder();
+ m_segments.port = URLComponent();
+ }
+ bool IsPortOverridden() const { return !!m_sources.port; }
+
+ // Path
+ void SetPath(const CharacterType* s, const URLComponent& comp)
+ {
+ m_sources.path = s;
+ m_segments.path = comp;
+ }
+ void ClearPath()
+ {
+ m_sources.path = Placeholder();
+ m_segments.path = URLComponent();
+ }
+ bool IsPathOverridden() const { return !m_sources.path; }
+
+ // Query
+ void SetQuery(const CharacterType* s, const URLComponent& comp)
+ {
+ m_sources.query = s;
+ m_segments.query = comp;
+ }
+ void ClearQuery()
+ {
+ m_sources.query = Placeholder();
+ m_segments.query = URLComponent();
+ }
+ bool IsQueryOverridden() const { return !m_sources.query; }
+
+ // Ref
+ void SetRef(const CharacterType* s, const URLComponent& comp)
+ {
+ m_sources.ref = s;
+ m_segments.fragment = comp;
+ }
+ void ClearRef()
+ {
+ m_sources.ref = Placeholder();
+ m_segments.fragment = URLComponent();
+ }
+ bool IsRefOverridden() const { return !m_sources.ref; }
+
+ // Getters for the itnernal data. See the variables below for how the
+ // information is encoded.
+ const URLComponentSource<CharacterType>& sources() const { return m_sources; }
+ const URLSegments& components() const { return m_segments; }
+
+private:
+ // Returns a pointer to a static empty string that is used as a placeholder
+ // to indicate a component should be deleted (see below).
+ const CharacterType* Placeholder()
+ {
+ static const CharacterType emptyString = 0;
+ return &emptyString;
+ }
+
+ // We support three states:
+ //
+ // Action | Source Component
+ // -----------------------+--------------------------------------------------
+ // Don't change component | null (unused)
+ // Replace component | (replacement string) (replacement component)
+ // Delete component | (non-null) (invalid component: (0,-1))
+ //
+ // We use a pointer to the empty string for the source when the component
+ // should be deleted.
+ URLComponentSource<CharacterType> m_sources;
+ URLSegments m_segments;
+};
+
+// The base must be an 8-bit canonical URL.
+bool ReplaceStandardURL(const char* base,
+ const URLSegments& baseParsed,
+ const Replacements<char>&,
+ URLQueryCharsetConverter* queryConverter,
+ URLBuffer<char>&,
+ URLSegments* outputParsed);
+bool ReplaceStandardURL(const char* base,
+ const URLSegments& baseParsed,
+ const Replacements<UChar>&,
+ URLQueryCharsetConverter* queryConverter,
+ URLBuffer<char>&,
+ URLSegments* outputParsed);
+
+// Filesystem URLs can only have the path, query, or ref replaced.
+// All other components will be ignored.
+bool ReplaceFileSystemURL(const char* base,
+ const URLSegments& baseParsed,
+ const Replacements<char>&,
+ URLQueryCharsetConverter* queryConverter,
+ URLBuffer<char>&,
+ URLSegments* outputParsed);
+bool ReplaceFileSystemURL(const char* base,
+ const URLSegments& baseParsed,
+ const Replacements<UChar>&,
+ URLQueryCharsetConverter* queryConverter,
+ URLBuffer<char>&,
+ URLSegments* outputParsed);
+
+// Replacing some parts of a file URL is not permitted. Everything except
+// the host, path, query, and ref will be ignored.
+bool ReplaceFileURL(const char* base,
+ const URLSegments& baseParsed,
+ const Replacements<char>&,
+ URLQueryCharsetConverter* queryConverter,
+ URLBuffer<char>&,
+ URLSegments* outputParsed);
+bool ReplaceFileURL(const char* base,
+ const URLSegments& baseParsed,
+ const Replacements<UChar>&,
+ URLQueryCharsetConverter* queryConverter,
+ URLBuffer<char>&,
+ URLSegments* outputParsed);
+
+// Path URLs can only have the scheme and path replaced. All other components
+// will be ignored.
+bool ReplacePathURL(const char* base,
+ const URLSegments& baseParsed,
+ const Replacements<char>&,
+ URLBuffer<char>&,
+ URLSegments* outputParsed);
+bool ReplacePathURL(const char* base,
+ const URLSegments& baseParsed,
+ const Replacements<UChar>&,
+ URLBuffer<char>&,
+ URLSegments* outputParsed);
+
+// Mailto URLs can only have the scheme, path, and query replaced.
+// All other components will be ignored.
+bool replaceMailtoURL(const char* base, const URLSegments& baseParsed,
+ const Replacements<char>&,
+ URLBuffer<char>& output, URLSegments& outputParsed);
+bool replaceMailtoURL(const char* base, const URLSegments& baseParsed,
+ const Replacements<UChar>&,
+ URLBuffer<char>& output, URLSegments& outputParsed);
+
+// Relative URL ---------------------------------------------------------------
+
+// Given an input URL or URL fragment |fragment|, determines if it is a
+// relative or absolute URL and places the result into |*isRelative|. If it is
+// relative, the relevant portion of the URL will be placed into
+// |*relativeComponent| (there may have been trimmed whitespace, for example).
+// This value is passed to resolveRelativeURL. If the input is not relative,
+// this value is UNDEFINED (it may be changed by the function).
+//
+// Returns true on success (we successfully determined the URL is relative or
+// not). Failure means that the combination of URLs doesn't make any sense.
+//
+// The base URL should always be canonical, therefore is ASCII.
+bool isRelativeURL(const char* base, const URLSegments& baseParsed,
+ const char* fragment, int fragmentLength,
+ bool isBaseHierarchical,
+ bool& isRelative, URLComponent& relativeComponent);
+bool isRelativeURL(const char* base, const URLSegments& baseParsed,
+ const UChar* fragment, int fragmentLength,
+ bool isBaseHierarchical,
+ bool& isRelative, URLComponent& relativeComponent);
+
+// Given a canonical parsed source URL, a URL fragment known to be relative,
+// and the identified relevant portion of the relative URL (computed by
+// isRelativeURL), this produces a new parsed canonical URL in |output| and
+// |outputParsed|.
+//
+// It also requires a flag indicating whether the base URL is a file: URL
+// which triggers additional logic.
+//
+// The base URL should be canonical and have a host (may be empty for file
+// URLs) and a path. If it doesn't have these, we can't resolve relative
+// URLs off of it and will return the base as the output with an error flag.
+// Becausee it is canonical is should also be ASCII.
+//
+// The query charset converter follows the same rules as CanonicalizeQuery.
+//
+// Returns true on success. On failure, the output will be "something
+// reasonable" that will be consistent and valid, just probably not what
+// was intended by the web page author or caller.
+bool resolveRelativeURL(const char* baseURL, const URLSegments& baseParsed, bool baseIsFile,
+ const char* relativeURL, const URLComponent& relativeComponent,
+ URLQueryCharsetConverter* queryConverter,
+ URLBuffer<char>&, URLSegments* outputParsed);
+bool resolveRelativeURL(const char* baseURL, const URLSegments& baseParsed, bool baseIsFile,
+ const UChar* relativeURL, const URLComponent& relativeComponent,
+ URLQueryCharsetConverter* queryConverter,
+ URLBuffer<char>&, URLSegments* outputParsed);
+
+} // namespace URLCanonicalizer
+
+} // namespace WTF
+
+#endif // USE(WTFURL)
+
+#endif // URLCanon_h
diff --git a/Source/WTF/wtf/url/src/URLCanonEtc.cpp b/Source/WTF/wtf/url/src/URLCanonEtc.cpp
new file mode 100644
index 000000000..4ed6d18e8
--- /dev/null
+++ b/Source/WTF/wtf/url/src/URLCanonEtc.cpp
@@ -0,0 +1,374 @@
+/*
+ * Copyright 2007 Google Inc. All rights reserved.
+ * Copyright 2012 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:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * 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.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND 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 THE COPYRIGHT
+ * OWNER 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.
+ */
+
+// Canonicalizers for random bits that aren't big enough for their own files.
+
+#include "config.h"
+#include "URLCanon.h"
+
+#include "URLCanonInternal.h"
+#include <wtf/ASCIICType.h>
+
+#if USE(WTFURL)
+
+namespace WTF {
+
+namespace URLCanonicalizer {
+
+namespace {
+
+// Returns true if the given character should be removed from the middle of a
+// URL.
+inline bool isRemovableURLWhitespace(int character)
+{
+ return character == '\r' || character == '\n' || character == '\t';
+}
+
+// Backend for removeURLWhitespace (see declaration in URLCanon.h).
+// It sucks that we have to do this, since this takes about 13% of the total URL
+// canonicalization time.
+template<typename CharacterType>
+const CharacterType* doRemoveURLWhitespace(const CharacterType* input, int inputLength, URLBuffer<CharacterType>& buffer, int& outputLength)
+{
+ // Fast verification that there's nothing that needs removal. This is the 99%
+ // case, so we want it to be fast and don't care about impacting the speed
+ // when we do find whitespace.
+ bool foundWhitespace = false;
+ for (int i = 0; i < inputLength; ++i) {
+ if (!isRemovableURLWhitespace(input[i]))
+ continue;
+ foundWhitespace = true;
+ break;
+ }
+
+ if (!foundWhitespace) {
+ // Didn't find any whitespace, we don't need to do anything. We can just
+ // return the input as the output.
+ outputLength = inputLength;
+ return input;
+ }
+
+ // Remove the whitespace into the new buffer and return it.
+ for (int i = 0; i < inputLength; i++) {
+ if (!isRemovableURLWhitespace(input[i]))
+ buffer.append(input[i]);
+ }
+ outputLength = buffer.length();
+ return buffer.data();
+}
+
+// Contains the canonical version of each possible input letter in the scheme
+// (basically, lower-cased). The corresponding entry will be 0 if the letter
+// is not allowed in a scheme.
+const char kSchemeCanonical[0x80] = {
+// 00-1f: all are invalid
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+// ' ' ! " # $ % & ' ( ) * + , - . /
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, '+', 0, '-', '.', 0,
+// 0 1 2 3 4 5 6 7 8 9 : ; < = > ?
+ '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 0 , 0 , 0 , 0 , 0 , 0 ,
+// @ A B C D E F G H I J K L M N O
+ 0 , 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o',
+// P Q R S T U V W X Y Z [ \ ] ^ _
+ 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', 0, 0 , 0, 0 , 0,
+// ` a b c d e f g h i j k l m n o
+ 0 , 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o',
+// p q r s t u v w x y z { | } ~
+ 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', 0 , 0 , 0 , 0 , 0 };
+
+// This could be a table lookup as well by setting the high bit for each
+// valid character, but it's only called once per URL, and it makes the lookup
+// table easier to read not having extra stuff in it.
+inline bool isSchemeFirstChar(unsigned char character)
+{
+ return isASCIIAlpha(character);
+}
+
+template<typename CharacterType, typename UCHAR>
+bool doScheme(const CharacterType* spec, const URLComponent& scheme, URLBuffer<char>& output, URLComponent& outputScheme)
+{
+ if (scheme.length() <= 0) {
+ // Scheme is unspecified or empty, convert to empty by appending a colon.
+ outputScheme = URLComponent(output.length(), 0);
+ output.append(':');
+ return true;
+ }
+
+ // The output scheme starts from the current position.
+ outputScheme.setBegin(outputScheme.begin() + output.length());
+
+ // Danger: it's important that this code does not strip any characters: it
+ // only emits the canonical version (be it valid or escaped) of each of
+ // the input characters. Stripping would put it out of sync with
+ // URLUtilities::FindAndCompareScheme, which could cause some security checks on
+ // schemes to be incorrect.
+ bool success = true;
+ int end = scheme.end();
+ for (int i = scheme.begin(); i < end; ++i) {
+ UCHAR character = static_cast<UCHAR>(spec[i]);
+ char replacement = 0;
+ if (character < 0x80) {
+ if (i == scheme.begin()) {
+ // Need to do a special check for the first letter of the scheme.
+ if (isSchemeFirstChar(static_cast<unsigned char>(character)))
+ replacement = kSchemeCanonical[character];
+ } else
+ replacement = kSchemeCanonical[character];
+ }
+
+ if (replacement)
+ output.append(replacement);
+ else if (character == '%') {
+ // Canonicalizing the scheme multiple times should lead to the same
+ // result. Since invalid characters will be escaped, we need to preserve
+ // the percent to avoid multiple escaping. The scheme will be invalid.
+ success = false;
+ output.append('%');
+ } else {
+ // Invalid character, store it but mark this scheme as invalid.
+ success = false;
+
+ // This will escape the output and also handle encoding issues.
+ // Ignore the return value since we already failed.
+ AppendUTF8EscapedChar(spec, &i, end, output);
+ }
+ }
+
+ // The output scheme ends with the the current position, before appending
+ // the colon.
+ outputScheme.setLength(output.length() - outputScheme.begin());
+ output.append(':');
+ return success;
+}
+
+// The username and password components reference ranges in the corresponding
+// *_spec strings. Typically, these specs will be the same (we're
+// canonicalizing a single source string), but may be different when
+// replacing components.
+template<typename CharacterType, typename UCHAR>
+bool doUserInfo(const CharacterType* usernameSpec,
+ const URLComponent& username,
+ const CharacterType* passwordSpec,
+ const URLComponent& password,
+ URLBuffer<char>& output,
+ URLComponent& outputUsername,
+ URLComponent& outputPassword)
+{
+ if (username.length() <= 0 && password.length() <= 0) {
+ // Common case: no user info. We strip empty username/passwords.
+ outputUsername = URLComponent();
+ outputPassword = URLComponent();
+ return true;
+ }
+
+ // Write the username.
+ outputUsername.setBegin(output.length());
+ if (username.length() > 0) {
+ // This will escape characters not valid for the username.
+ appendStringOfType(&usernameSpec[username.begin()], username.length(), URLCharacterTypes::UserInfoCharacter, output);
+ }
+ outputUsername.setLength(output.length() - outputUsername.begin());
+
+ // When there is a password, we need the separator. Note that we strip
+ // empty but specified passwords.
+ if (password.length() > 0) {
+ output.append(':');
+ outputPassword.setBegin(output.length());
+ appendStringOfType(&passwordSpec[password.begin()], password.length(), URLCharacterTypes::UserInfoCharacter, output);
+ outputPassword.setLength(output.length() - outputPassword.begin());
+ } else
+ outputPassword = URLComponent();
+
+ output.append('@');
+ return true;
+}
+
+// Helper functions for converting port integers to strings.
+inline void writePortInt(char* output, int outputLength, int port)
+{
+ _itoa_s(port, output, outputLength, 10);
+}
+
+// This function will prepend the colon if there will be a port.
+template<typename CharacterType, typename UCHAR>
+bool doPort(const CharacterType* spec,
+ const URLComponent& port,
+ int defaultPortForScheme,
+ URLBuffer<char>& output,
+ URLComponent& outputPortComponent)
+{
+ int portNumber = URLParser::ParsePort(spec, port);
+ if (portNumber == URLParser::PORT_UNSPECIFIED || portNumber == defaultPortForScheme) {
+ outputPortComponent = URLComponent();
+ return true; // Leave port empty.
+ }
+
+ if (portNumber == URLParser::PORT_INVALID) {
+ // Invalid port: We'll copy the text from the input so the user can see
+ // what the error was, and mark the URL as invalid by returning false.
+ output.append(':');
+ outputPortComponent.setBegin(output.length());
+ AppendInvalidNarrowString(spec, port.begin(), port.end(), output);
+ outputPortComponent.setLength(output.length() - outputPortComponent.begin());
+ return false;
+ }
+
+ // Convert port number back to an integer. Max port value is 5 digits, and
+ // the Parsed::ExtractPort will have made sure the integer is in range.
+ const int bufferSize = 6;
+ char buffer[bufferSize];
+ writePortInt(buffer, bufferSize, portNumber);
+
+ // Append the port number to the output, preceeded by a colon.
+ output.append(':');
+ outputPortComponent.setBegin(output.length());
+ for (int i = 0; i < bufferSize && buffer[i]; ++i)
+ output.append(buffer[i]);
+
+ outputPortComponent.setLength(output.length() - outputPortComponent.begin());
+ return true;
+}
+
+template<typename CharacterType, typename UCHAR>
+void doCanonicalizeFragment(const CharacterType* spec, const URLComponent& fragment, URLBuffer<char>& output, URLComponent& outputFragment)
+{
+ if (fragment.length() < 0) {
+ // Common case of no fragment.
+ outputFragment = URLComponent();
+ return;
+ }
+
+ // Append the fragment separator. Note that we need to do this even when the fragment
+ // is empty but present.
+ output.append('#');
+ outputFragment.setBegin(output.length());
+
+ // Now iterate through all the characters, converting to UTF-8 and validating.
+ int end = fragment.end();
+ for (int i = fragment.begin(); i < end; ++i) {
+ if (!spec[i]) {
+ // IE just strips NULLs, so we do too.
+ continue;
+ }
+ if (static_cast<UCHAR>(spec[i]) < 0x20) {
+ // Unline IE seems to, we escape control characters. This will probably
+ // make the reference fragment unusable on a web page, but people
+ // shouldn't be using control characters in their anchor names.
+ appendURLEscapedCharacter(static_cast<unsigned char>(spec[i]), output);
+ } else if (static_cast<UCHAR>(spec[i]) < 0x80) {
+ // Normal ASCII characters are just appended.
+ output.append(static_cast<char>(spec[i]));
+ } else {
+ // Non-ASCII characters are appended unescaped, but only when they are
+ // valid. Invalid Unicode characters are replaced with the "invalid
+ // character" as IE seems to (readUTFChar puts the unicode replacement
+ // character in the output on failure for us).
+ unsigned codePoint;
+ readUTFChar(spec, &i, end, &codePoint);
+ AppendUTF8Value(codePoint, output);
+ }
+ }
+
+ outputFragment.setLength(output.length() - outputFragment.begin());
+}
+
+} // namespace
+
+const char* removeURLWhitespace(const char* input, int inputLength, URLBuffer<char>& buffer, int& outputLength)
+{
+ return doRemoveURLWhitespace(input, inputLength, buffer, outputLength);
+}
+
+const UChar* removeURLWhitespace(const UChar* input, int inputLength, URLBuffer<UChar>& buffer, int& outputLength)
+{
+ return doRemoveURLWhitespace(input, inputLength, buffer, outputLength);
+}
+
+char canonicalSchemeChar(UChar character)
+{
+ if (character >= 0x80)
+ return 0; // Non-ASCII is not supported by schemes.
+ return kSchemeCanonical[character];
+}
+
+bool canonicalizeScheme(const char* spec, const URLComponent& scheme, URLBuffer<char>& output, URLComponent& outputScheme)
+{
+ return doScheme<char, unsigned char>(spec, scheme, output, outputScheme);
+}
+
+bool canonicalizeScheme(const UChar* spec, const URLComponent& scheme, URLBuffer<char>& output, URLComponent& outputScheme)
+{
+ return doScheme<UChar, UChar>(spec, scheme, output, outputScheme);
+}
+
+bool canonicalizeUserInfo(const char* usernameSource, const URLComponent& username, const char* passwordSource, const URLComponent& password,
+ URLBuffer<char>& output, URLComponent& outputUsername, URLComponent& outputPassword)
+{
+ return doUserInfo<char, unsigned char>(usernameSource, username, passwordSource, password, output, outputUsername, outputPassword);
+}
+
+bool canonicalizeUserInfo(const UChar* usernameSource, const URLComponent& username, const UChar* passwordSource, const URLComponent& password,
+ URLBuffer<char>& output, URLComponent& outputUsername, URLComponent& outputPassword)
+{
+ return doUserInfo<UChar, UChar>(usernameSource, username, passwordSource, password, output, outputUsername, outputPassword);
+}
+
+bool canonicalizePort(const char* spec, const URLComponent& port, int defaultPortForScheme,
+ URLBuffer<char>& output, URLComponent& outputPortComponent)
+{
+ return doPort<char, unsigned char>(spec, port,
+ defaultPortForScheme,
+ output, outputPortComponent);
+}
+
+bool canonicalizePort(const UChar* spec, const URLComponent& port, int defaultPortForScheme,
+ URLBuffer<char>& output, URLComponent& outputPortComponent)
+{
+ return doPort<UChar, UChar>(spec, port, defaultPortForScheme,
+ output, outputPortComponent);
+}
+
+void canonicalizeFragment(const char* spec, const URLComponent& ref, URLBuffer<char>& output, URLComponent& outputFragment)
+{
+ doCanonicalizeFragment<char, unsigned char>(spec, ref, output, outputFragment);
+}
+
+void canonicalizeFragment(const UChar* spec, const URLComponent& ref, URLBuffer<char>& output, URLComponent& outputFragment)
+{
+ doCanonicalizeFragment<UChar, UChar>(spec, ref, output, outputFragment);
+}
+
+} // namespace URLCanonicalizer
+
+} // namespace WTF
+
+#endif // USE(WTFURL)
diff --git a/Source/WTF/wtf/url/src/URLCanonFilesystemurl.cpp b/Source/WTF/wtf/url/src/URLCanonFilesystemurl.cpp
new file mode 100644
index 000000000..361bbbef7
--- /dev/null
+++ b/Source/WTF/wtf/url/src/URLCanonFilesystemurl.cpp
@@ -0,0 +1,164 @@
+/*
+ * Copyright 2012 Google Inc. All rights reserved.
+ * Copyright 2012 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:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * 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.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND 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 THE COPYRIGHT
+ * OWNER 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.
+ */
+
+// Functions for canonicalizing "filesystem:file:" URLs.
+
+#include "config.h"
+#include "URLCanon.h"
+
+#include "RawURLBuffer.h"
+#include "URLCanonInternal.h"
+#include "URLFile.h"
+#include "URLParseInternal.h"
+#include "URLUtil.h"
+#include "URLUtilInternal.h"
+
+#if USE(WTFURL)
+
+namespace WTF {
+
+namespace URLCanonicalizer {
+
+namespace {
+
+// We use the URLComponentSource for the outer URL, as it can have replacements,
+// whereas the inner_url can't, so it uses spec.
+template<typename CharacterType, typename UCHAR>
+bool doCanonicalizeFileSystemURL(const CharacterType* spec,
+ const URLComponentSource<CharacterType>& source,
+ const URLSegments& parsed,
+ URLQueryCharsetConverter* charsetConverter,
+ URLBuffer<char>& output,
+ URLSegments& outputParsed)
+{
+ // filesystem only uses {scheme, path, query, ref} -- clear the rest.
+ outputParsed.username = URLComponent();
+ outputParsed.password = URLComponent();
+ outputParsed.host = URLComponent();
+ outputParsed.port = URLComponent();
+
+ const URLSegments* innerParsed = parsed.innerURLSegments();
+ URLSegments newInnerParsed;
+
+ // Scheme (known, so we don't bother running it through the more
+ // complicated scheme canonicalizer).
+ outputParsed.scheme.setBegin(output.length());
+ output.append("filesystem:", 11);
+ outputParsed.scheme.setLength(10);
+
+ if (!parsed.innerURLSegments() || !parsed.innerURLSegments()->scheme.isValid())
+ return false;
+
+ bool success = true;
+ if (URLUtilities::CompareSchemeComponent(spec, innerParsed->scheme, URLUtilities::kFileScheme)) {
+ newInnerParsed.scheme.setBegin(output.length());
+ output.append("file://", 7);
+ newInnerParsed.scheme.setLength(4);
+ success &= CanonicalizePath(spec, innerParsed->path, output,
+ &newInnerParsed.path);
+ } else if (URLUtilities::isStandard(spec, innerParsed->scheme)) {
+ success =
+ URLCanonicalizer::CanonicalizeStandardURL(spec,
+ parsed.innerURLSegments()->length(),
+ *parsed.innerURLSegments(),
+ charsetConverter, output,
+ &newInnerParsed);
+ } else {
+ // TODO(ericu): The URL is wrong, but should we try to output more of what
+ // we were given? Echoing back filesystem:mailto etc. doesn't seem all that useful.
+ return false;
+ }
+ // The filesystem type must be more than just a leading slash for validity.
+ success &= parsed.innerURLSegments()->path.length() > 1;
+
+ success &= CanonicalizePath(source.path, parsed.path, output, &outputParsed.path);
+
+ // Ignore failures for query/ref since the URL can probably still be loaded.
+ CanonicalizeQuery(source.query, parsed.query, charsetConverter, output, &outputParsed.query);
+ canonicalizeFragment(source.ref, parsed.fragment, output, outputParsed.fragment);
+ if (success)
+ outputParsed.setInnerURLSegments(newInnerParsed);
+
+ return success;
+}
+
+} // namespace
+
+bool canonicalizeFileSystemURL(const char* spec,
+ const URLSegments& parsed,
+ URLQueryCharsetConverter* charsetConverter,
+ URLBuffer<char>& output,
+ URLSegments& outputParsed)
+{
+ return doCanonicalizeFileSystemURL<char, unsigned char>(spec, URLComponentSource<char>(spec), parsed, charsetConverter, output, outputParsed);
+}
+
+bool canonicalizeFileSystemURL(const UChar* spec,
+ const URLSegments& parsed,
+ URLQueryCharsetConverter* charsetConverter,
+ URLBuffer<char>& output,
+ URLSegments& outputParsed)
+{
+ return doCanonicalizeFileSystemURL<UChar, UChar>(spec, URLComponentSource<UChar>(spec), parsed, charsetConverter, output, outputParsed);
+}
+
+bool ReplaceFileSystemURL(const char* base,
+ const URLSegments& baseParsed,
+ const Replacements<char>& replacements,
+ URLQueryCharsetConverter* charsetConverter,
+ URLBuffer<char>& output,
+ URLSegments* outputParsed)
+{
+ URLComponentSource<char> source(base);
+ URLSegments parsed(baseParsed);
+ SetupOverrideComponents(base, replacements, &source, &parsed);
+ return doCanonicalizeFileSystemURL<char, unsigned char>(base, source, parsed, charsetConverter, output, *outputParsed);
+}
+
+bool ReplaceFileSystemURL(const char* base,
+ const URLSegments& baseParsed,
+ const Replacements<UChar>& replacements,
+ URLQueryCharsetConverter* charsetConverter,
+ URLBuffer<char>& output,
+ URLSegments* outputParsed)
+{
+ RawURLBuffer<char> utf8;
+ URLComponentSource<char> source(base);
+ URLSegments parsed(baseParsed);
+ SetupUTF16OverrideComponents(base, replacements, utf8, &source, &parsed);
+ return doCanonicalizeFileSystemURL<char, unsigned char>(base, source, parsed, charsetConverter, output, *outputParsed);
+}
+
+} // namespace URLCanonicalizer
+
+} // namespace WTF
+
+#endif // USE(WTFURL)
diff --git a/Source/WTF/wtf/url/src/URLCanonFileurl.cpp b/Source/WTF/wtf/url/src/URLCanonFileurl.cpp
new file mode 100644
index 000000000..73a9f6dd1
--- /dev/null
+++ b/Source/WTF/wtf/url/src/URLCanonFileurl.cpp
@@ -0,0 +1,224 @@
+/*
+ * Copyright 2007 Google Inc. All rights reserved.
+ * Copyright 2012 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:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * 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.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND 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 THE COPYRIGHT
+ * OWNER 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.
+ */
+
+// Functions for canonicalizing "file:" URLs.
+
+#include "config.h"
+#include "URLCanon.h"
+
+#include "RawURLBuffer.h"
+#include "URLCanonInternal.h"
+#include "URLFile.h"
+#include "URLParseInternal.h"
+
+#if USE(WTFURL)
+
+namespace WTF {
+
+namespace URLCanonicalizer {
+
+namespace {
+
+#if OS(WINDOWS)
+
+// Given a pointer into the spec, this copies and canonicalizes the drive
+// letter and colon to the output, if one is found. If there is not a drive
+// spec, it won't do anything. The index of the next character in the input
+// spec is returned (after the colon when a drive spec is found, the begin
+// offset if one is not).
+template<typename CHAR>
+int FileDoDriveSpec(const CHAR* spec, int begin, int end, URLBuffer<char>& output)
+{
+ // The path could be one of several things: /foo/bar, c:/foo/bar, /c:/foo,
+ // (with backslashes instead of slashes as well).
+ int numSlashes = URLParser::countConsecutiveSlashes(spec, begin, end);
+ int afterSlashes = begin + numSlashes;
+
+ if (!URLParser::doesBeginWindowsDriveSpec(spec, afterSlashes, end))
+ return begin; // Haven't consumed any characters
+
+ // A drive spec is the start of a path, so we need to add a slash for the
+ // authority terminator (typically the third slash).
+ output.append('/');
+
+ // doesBeginWindowsDriveSpec will ensure that the drive letter is valid
+ // and that it is followed by a colon/pipe.
+
+ // Normalize Windows drive letters to uppercase
+ if (spec[afterSlashes] >= 'a' && spec[afterSlashes] <= 'z')
+ output.append(spec[afterSlashes] - 'a' + 'A');
+ else
+ output.append(static_cast<char>(spec[afterSlashes]));
+
+ // Normalize the character following it to a colon rather than pipe.
+ output.append(':');
+ return afterSlashes + 2;
+}
+
+#endif // OS(WINDOWS)
+
+template<typename CharacterType, typename UCHAR>
+bool doFileCanonicalizePath(const CharacterType* spec,
+ const URLComponent& path,
+ URLBuffer<char>& output,
+ URLComponent& outputPath)
+{
+ // Copies and normalizes the "c:" at the beginning, if present.
+ outputPath.setBegin(output.length());
+ int afterDrive;
+#if OS(WINDOWS)
+ afterDrive = FileDoDriveSpec(spec, path.begin, path.end(), output);
+#else
+ afterDrive = path.begin();
+#endif
+
+ // Copies the rest of the path, starting from the slash following the
+ // drive colon (if any, Windows only), or the first slash of the path.
+ bool success = true;
+ if (afterDrive < path.end()) {
+ // Use the regular path canonicalizer to canonicalize the rest of the
+ // path. Give it a fake output component to write into. DoCanonicalizeFile
+ // will compute the full path component.
+ URLComponent subPath = URLComponent::fromRange(afterDrive, path.end());
+ URLComponent fakeOutputPath;
+ success = CanonicalizePath(spec, subPath, output, &fakeOutputPath);
+ } else {
+ // No input path, canonicalize to a slash.
+ output.append('/');
+ }
+
+ outputPath.setLength(output.length() - outputPath.begin());
+ return success;
+}
+
+template<typename CharacterType, typename UCHAR>
+bool doCanonicalizeFileURL(const URLComponentSource<CharacterType>& source,
+ const URLSegments& parsed,
+ URLQueryCharsetConverter* queryConverter,
+ URLBuffer<char>& output,
+ URLSegments& outputParsed)
+{
+ // Things we don't set in file: URLs.
+ outputParsed.username = URLComponent();
+ outputParsed.password = URLComponent();
+ outputParsed.port = URLComponent();
+
+ // Scheme (known, so we don't bother running it through the more
+ // complicated scheme canonicalizer).
+ outputParsed.scheme.setBegin(output.length());
+ output.append("file://", 7);
+ outputParsed.scheme.setLength(4);
+
+ // Append the host. For many file URLs, this will be empty. For UNC, this
+ // will be present.
+ // TODO(brettw) This doesn't do any checking for host name validity. We
+ // should probably handle validity checking of UNC hosts differently than
+ // for regular IP hosts.
+ bool success = canonicalizeHost(source.host, parsed.host, output, outputParsed.host);
+ success &= doFileCanonicalizePath<CharacterType, UCHAR>(source.path, parsed.path, output, outputParsed.path);
+ CanonicalizeQuery(source.query, parsed.query, queryConverter, output, &outputParsed.query);
+
+ // Ignore failure for refs since the URL can probably still be loaded.
+ canonicalizeFragment(source.ref, parsed.fragment, output, outputParsed.fragment);
+
+ return success;
+}
+
+} // namespace
+
+bool CanonicalizeFileURL(const char* spec,
+ int /* specLength */,
+ const URLSegments& parsed,
+ URLQueryCharsetConverter* queryConverter,
+ URLBuffer<char>& output,
+ URLSegments* outputParsed)
+{
+ return doCanonicalizeFileURL<char, unsigned char>(URLComponentSource<char>(spec), parsed, queryConverter, output, *outputParsed);
+}
+
+bool CanonicalizeFileURL(const UChar* spec,
+ int /* specLength */,
+ const URLSegments& parsed,
+ URLQueryCharsetConverter* queryConverter,
+ URLBuffer<char>& output,
+ URLSegments* outputParsed)
+{
+ return doCanonicalizeFileURL<UChar, UChar>(URLComponentSource<UChar>(spec), parsed, queryConverter, output, *outputParsed);
+}
+
+bool FileCanonicalizePath(const char* spec,
+ const URLComponent& path,
+ URLBuffer<char>& output,
+ URLComponent* outputPath)
+{
+ return doFileCanonicalizePath<char, unsigned char>(spec, path, output, *outputPath);
+}
+
+bool FileCanonicalizePath(const UChar* spec,
+ const URLComponent& path,
+ URLBuffer<char>& output,
+ URLComponent* outputPath)
+{
+ return doFileCanonicalizePath<UChar, UChar>(spec, path, output, *outputPath);
+}
+
+bool ReplaceFileURL(const char* base,
+ const URLSegments& baseParsed,
+ const Replacements<char>& replacements,
+ URLQueryCharsetConverter* queryConverter,
+ URLBuffer<char>& output,
+ URLSegments* outputParsed)
+{
+ URLComponentSource<char> source(base);
+ URLSegments parsed(baseParsed);
+ SetupOverrideComponents(base, replacements, &source, &parsed);
+ return doCanonicalizeFileURL<char, unsigned char>(source, parsed, queryConverter, output, *outputParsed);
+}
+
+bool ReplaceFileURL(const char* base,
+ const URLSegments& baseParsed,
+ const Replacements<UChar>& replacements,
+ URLQueryCharsetConverter* queryConverter,
+ URLBuffer<char>& output,
+ URLSegments* outputParsed)
+{
+ RawURLBuffer<char> utf8;
+ URLComponentSource<char> source(base);
+ URLSegments parsed(baseParsed);
+ SetupUTF16OverrideComponents(base, replacements, utf8, &source, &parsed);
+ return doCanonicalizeFileURL<char, unsigned char>(source, parsed, queryConverter, output, *outputParsed);
+}
+
+} // namespace URLCanonicalizer
+
+} // namespace WTF
+
+#endif // USE(WTFURL)
diff --git a/Source/WTF/wtf/url/src/URLCanonHost.cpp b/Source/WTF/wtf/url/src/URLCanonHost.cpp
new file mode 100644
index 000000000..5ea2f9906
--- /dev/null
+++ b/Source/WTF/wtf/url/src/URLCanonHost.cpp
@@ -0,0 +1,383 @@
+/*
+ * Copyright 2007 Google Inc. All rights reserved.
+ * Copyright 2012 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:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * 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.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND 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 THE COPYRIGHT
+ * OWNER 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 "URLCanon.h"
+
+#include "RawURLBuffer.h"
+#include "URLCanonInternal.h"
+
+#if USE(WTFURL)
+
+namespace WTF {
+
+namespace URLCanonicalizer {
+
+namespace {
+
+// For reference, here's what IE supports:
+// Key: 0 (disallowed: failure if present in the input)
+// + (allowed either escaped or unescaped, and unmodified)
+// U (allowed escaped or unescaped but always unescaped if present in
+// escaped form)
+// E (allowed escaped or unescaped but always escaped if present in
+// unescaped form)
+// % (only allowed escaped in the input, will be unmodified).
+// I left blank alpha numeric characters.
+//
+// 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f
+// -----------------------------------------------
+// 0 0 E E E E E E E E E E E E E E E
+// 1 E E E E E E E E E E E E E E E E
+// 2 E + E E + E + + + + + + + U U 0
+// 3 % % E + E 0 <-- Those are : ; < = > ?
+// 4 %
+// 5 U 0 U U U <-- Those are [ \ ] ^ _
+// 6 E <-- That's `
+// 7 E E E U E <-- Those are { | } ~ (UNPRINTABLE)
+//
+// NOTE: I didn't actually test all the control characters. Some may be
+// disallowed in the input, but they are all accepted escaped except for 0.
+// I also didn't test if characters affecting HTML parsing are allowed
+// unescaped, eg. (") or (#), which would indicate the beginning of the path.
+// Surprisingly, space is accepted in the input and always escaped.
+
+// This table lists the canonical version of all characters we allow in the
+// input, with 0 indicating it is disallowed. We use the magic kEscapedHostChar
+// value to indicate that this character should be escaped. We are a little more
+// restrictive than IE, but less restrictive than Firefox.
+//
+// Note that we disallow the % character. We will allow it when part of an
+// escape sequence, of course, but this disallows "%25". Even though IE allows
+// it, allowing it would put us in a funny state. If there was an invalid
+// escape sequence like "%zz", we'll add "%25zz" to the output and fail.
+// Allowing percents means we'll succeed a second time, so validity would change
+// based on how many times you run the canonicalizer. We prefer to always report
+// the same vailidity, so reject this.
+const unsigned char kEsc = 0xff;
+const unsigned char kHostCharLookup[0x80] = {
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+// ' ' ! " # $ % & ' ( ) * + , - . /
+ kEsc, kEsc, kEsc, kEsc, kEsc, 0, kEsc, kEsc, kEsc, kEsc, kEsc, '+', kEsc, '-', '.', 0,
+// 0 1 2 3 4 5 6 7 8 9 : ; < = > ?
+ '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', ':', 0 , kEsc, kEsc, kEsc, 0 ,
+// @ A B C D E F G H I J K L M N O
+ kEsc, 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o',
+// P Q R S T U V W X Y Z [ \ ] ^ _
+ 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', '[', 0 , ']', 0 , '_',
+// ` a b c d e f g h i j k l m n o
+ kEsc, 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o',
+// p q r s t u v w x y z { | } ~
+ 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', kEsc, kEsc, kEsc, 0 , 0 };
+
+typedef RawURLBuffer<char> StackBuffer;
+typedef RawURLBuffer<UChar> StackBufferW;
+
+// Scans a host name and fills in the output flags according to what we find.
+// |hasNonASCII| will be true if there are any non-7-bit characters, and
+// |hasEscaped| will be true if there is a percent sign.
+template<typename CharacterType, typename UCHAR>
+void scanHostname(const CharacterType* spec, const URLComponent& host, bool& hasNonASCII, bool& hasEscaped)
+{
+ int end = host.end();
+ hasNonASCII = false;
+ hasEscaped = false;
+ for (int i = host.begin(); i < end; ++i) {
+ if (static_cast<UCHAR>(spec[i]) >= 0x80)
+ hasNonASCII = true;
+ else if (spec[i] == '%')
+ hasEscaped = true;
+ }
+}
+
+// Canonicalizes a host name that is entirely 8-bit characters (even though
+// the type holding them may be 16 bits. Escaped characters will be unescaped.
+// Non-7-bit characters (for example, UTF-8) will be passed unchanged.
+//
+// The |*hasNonASCII| flag will be true if there are non-7-bit characters in
+// the output.
+//
+// This function is used in two situations:
+//
+// * When the caller knows there is no non-ASCII or percent escaped
+// characters. This is what DoHost does. The result will be a completely
+// canonicalized host since we know nothing weird can happen (escaped
+// characters could be unescaped to non-7-bit, so they have to be treated
+// with suspicion at this point). It does not use the |hasNonASCII| flag.
+//
+// * When the caller has an 8-bit string that may need unescaping.
+// doComplexHost calls us this situation to do unescaping and validation.
+// After this, it may do other IDN operations depending on the value of the
+// |*hasNonASCII| flag.
+//
+// The return value indicates if the output is a potentially valid host name.
+template<typename INCHAR, typename OUTCHAR>
+bool doSimpleHost(const INCHAR* host, int hostLength, URLBuffer<OUTCHAR>& output, bool& hasNonASCII)
+{
+ hasNonASCII = false;
+
+ bool success = true;
+ for (int i = 0; i < hostLength; ++i) {
+ unsigned source = host[i];
+ if (source == '%') {
+ // Unescape first, if possible.
+ // Source will be used only if decode operation was successful.
+ if (!DecodeEscaped(host, &i, hostLength,
+ reinterpret_cast<unsigned char*>(&source))) {
+ // Invalid escaped character. There is nothing that can make this
+ // host valid. We append an escaped percent so the URL looks reasonable
+ // and mark as failed.
+ appendURLEscapedCharacter('%', output);
+ success = false;
+ continue;
+ }
+ }
+
+ if (source < 0x80) {
+ // We have ASCII input, we can use our lookup table.
+ unsigned char replacement = kHostCharLookup[source];
+ if (!replacement) {
+ // Invalid character, add it as percent-escaped and mark as failed.
+ appendURLEscapedCharacter(source, output);
+ success = false;
+ } else if (replacement == kEsc) {
+ // This character is valid but should be escaped.
+ appendURLEscapedCharacter(source, output);
+ } else {
+ // Common case, the given character is valid in a hostname, the lookup
+ // table tells us the canonical representation of that character (lower
+ // cased).
+ output.append(replacement);
+ }
+ } else {
+ // It's a non-ascii char. Just push it to the output.
+ // In case where we have UChar input, and char output it's safe to
+ // cast UChar->char only if input string was converted to ASCII.
+ output.append(static_cast<OUTCHAR>(source));
+ hasNonASCII = true;
+ }
+ }
+
+ return success;
+}
+
+// Canonicalizes a host that requires IDN conversion. Returns true on success
+bool doIDNHost(const UChar* src, int sourceLength, URLBuffer<char>& output)
+{
+ // We need to escape URL before doing IDN conversion, since punicode strings
+ // cannot be escaped after they are created.
+ RawURLBuffer<UChar> urlEscapedHost;
+ bool hasNonASCII;
+ doSimpleHost(src, sourceLength, urlEscapedHost, hasNonASCII);
+
+ StackBufferW wideOutput;
+ if (!IDNToASCII(urlEscapedHost.data(),
+ urlEscapedHost.length(),
+ wideOutput)) {
+ // Some error, give up. This will write some reasonable looking
+ // representation of the string to the output.
+ AppendInvalidNarrowString(src, 0, sourceLength, output);
+ return false;
+ }
+
+ // Now we check the ASCII output like a normal host. It will also handle
+ // unescaping. Although we unescaped everything before this function call, if
+ // somebody does %00 as fullwidth, ICU will convert this to ASCII.
+ bool success = doSimpleHost(wideOutput.data(), wideOutput.length(), output, hasNonASCII);
+ ASSERT(!hasNonASCII);
+ return success;
+}
+
+// 8-bit convert host to its ASCII version: this converts the UTF-8 input to
+// UTF-16. The hasEscaped flag should be set if the input string requires
+// unescaping.
+bool doComplexHost(const char* host, int hostLength, bool hasNonASCII, bool hasEscaped, URLBuffer<char>& output)
+{
+ // Save the current position in the output. We may write stuff and rewind it
+ // below, so we need to know where to rewind to.
+ int beginLength = output.length();
+
+ // Points to the UTF-8 data we want to convert. This will either be the
+ // input or the unescaped version written to |output| if necessary.
+ const char* utf8Source;
+ int utf8SourceLength;
+ if (hasEscaped) {
+ // Unescape before converting to UTF-16 for IDN. We write this into the
+ // output because it most likely does not require IDNization, and we can
+ // save another huge stack buffer. It will be replaced below if it requires
+ // IDN. This will also update our non-ASCII flag so we know whether the
+ // unescaped input requires IDN.
+ if (!doSimpleHost(host, hostLength, output, hasNonASCII)) {
+ // Error with some escape sequence. We'll call the current output
+ // complete. doSimpleHost will have written some "reasonable" output.
+ return false;
+ }
+
+ // Unescaping may have left us with ASCII input, in which case the
+ // unescaped version we wrote to output is complete.
+ if (!hasNonASCII)
+ return true;
+
+ // Save the pointer into the data was just converted (it may be appended to
+ // other data in the output buffer).
+ utf8Source = &output.data()[beginLength];
+ utf8SourceLength = output.length() - beginLength;
+ } else {
+ // We don't need to unescape, use input for IDNization later. (We know the
+ // input has non-ASCII, or the simple version would have been called
+ // instead of us.)
+ utf8Source = host;
+ utf8SourceLength = hostLength;
+ }
+
+ // Non-ASCII input requires IDN, convert to UTF-16 and do the IDN conversion.
+ // Above, we may have used the output to write the unescaped values to, so
+ // we have to rewind it to where we started after we convert it to UTF-16.
+ StackBufferW utf16;
+ if (!ConvertUTF8ToUTF16(utf8Source, utf8SourceLength, utf16)) {
+ // In this error case, the input may or may not be the output.
+ StackBuffer utf8;
+ for (int i = 0; i < utf8SourceLength; i++)
+ utf8.append(utf8Source[i]);
+ output.setLength(beginLength);
+ AppendInvalidNarrowString(utf8.data(), 0, utf8.length(), output);
+ return false;
+ }
+ output.setLength(beginLength);
+
+ // This will call doSimpleHost which will do normal ASCII canonicalization
+ // and also check for IP addresses in the outpt.
+ return doIDNHost(utf16.data(), utf16.length(), output);
+}
+
+// UTF-16 convert host to its ASCII version. The set up is already ready for
+// the backend, so we just pass through. The hasEscaped flag should be set if
+// the input string requires unescaping.
+bool doComplexHost(const UChar* host, int hostLength, bool hasNonASCII, bool hasEscaped, URLBuffer<char>& output)
+{
+ if (hasEscaped) {
+ // Yikes, we have escaped characters with wide input. The escaped
+ // characters should be interpreted as UTF-8. To solve this problem,
+ // we convert to UTF-8, unescape, then convert back to UTF-16 for IDN.
+ //
+ // We don't bother to optimize the conversion in the ASCII case (which
+ // *could* just be a copy) and use the UTF-8 path, because it should be
+ // very rare that host names have escaped characters, and it is relatively
+ // fast to do the conversion anyway.
+ StackBuffer utf8;
+ if (!ConvertUTF16ToUTF8(host, hostLength, utf8)) {
+ AppendInvalidNarrowString(host, 0, hostLength, output);
+ return false;
+ }
+
+ // Once we convert to UTF-8, we can use the 8-bit version of the complex
+ // host handling code above.
+ return doComplexHost(utf8.data(), utf8.length(), hasNonASCII,
+ hasEscaped, output);
+ }
+
+ // No unescaping necessary, we can safely pass the input to ICU. This
+ // function will only get called if we either have escaped or non-ascii
+ // input, so it's safe to just use ICU now. Even if the input is ASCII,
+ // this function will do the right thing (just slower than we could).
+ return doIDNHost(host, hostLength, output);
+}
+
+template<typename CharacterType, typename UCHAR>
+void doHost(const CharacterType* spec, const URLComponent& host, URLBuffer<char>& output, CanonHostInfo& hostInfo)
+{
+ if (host.length() <= 0) {
+ // Empty hosts don't need anything.
+ hostInfo.family = CanonHostInfo::NEUTRAL;
+ hostInfo.ouputHost = URLComponent();
+ return;
+ }
+
+ bool hasNonASCII;
+ bool hasEscaped;
+ scanHostname<CharacterType, UCHAR>(spec, host, hasNonASCII, hasEscaped);
+
+ // Keep track of output's initial length, so we can rewind later.
+ const int outputBegin = output.length();
+
+ bool success;
+ if (!hasNonASCII && !hasEscaped) {
+ success = doSimpleHost(&spec[host.begin()], host.length(), output, hasNonASCII);
+ ASSERT(!hasNonASCII);
+ } else
+ success = doComplexHost(&spec[host.begin()], host.length(), hasNonASCII, hasEscaped, output);
+
+ if (!success) {
+ // Canonicalization failed. Set BROKEN to notify the caller.
+ hostInfo.family = CanonHostInfo::BROKEN;
+ } else {
+ // After all the other canonicalization, check if we ended up with an IP
+ // address. IP addresses are small, so writing into this temporary buffer
+ // should not cause an allocation.
+ RawURLBuffer<char, 64> canon_ip;
+ canonicalizeIPAddress(output.data(), URLComponent::fromRange(outputBegin, output.length()), canon_ip, hostInfo);
+
+ // If we got an IPv4/IPv6 address, copy the canonical form back to the
+ // real buffer. Otherwise, it's a hostname or broken IP, in which case
+ // we just leave it in place.
+ if (hostInfo.IsIPAddress()) {
+ output.setLength(outputBegin);
+ output.append(canon_ip.data(), canon_ip.length());
+ }
+ }
+
+ hostInfo.ouputHost = URLComponent::fromRange(outputBegin, output.length());
+}
+
+} // namespace
+
+bool canonicalizeHost(const char* spec, const URLComponent& host, URLBuffer<char>& output, URLComponent& ouputHost)
+{
+ CanonHostInfo hostInfo;
+ doHost<char, unsigned char>(spec, host, output, hostInfo);
+ ouputHost = hostInfo.ouputHost;
+ return (hostInfo.family != CanonHostInfo::BROKEN);
+}
+
+bool canonicalizeHost(const UChar* spec, const URLComponent& host, URLBuffer<char>& output, URLComponent& ouputHost)
+{
+ CanonHostInfo hostInfo;
+ doHost<UChar, UChar>(spec, host, output, hostInfo);
+ ouputHost = hostInfo.ouputHost;
+ return (hostInfo.family != CanonHostInfo::BROKEN);
+}
+
+} // namespace URLCanonicalizer
+
+} // namespace WTF
+
+#endif // USE(WTFURL)
diff --git a/Source/WTF/wtf/url/src/URLCanonICU.cpp b/Source/WTF/wtf/url/src/URLCanonICU.cpp
new file mode 100644
index 000000000..e61fa707a
--- /dev/null
+++ b/Source/WTF/wtf/url/src/URLCanonICU.cpp
@@ -0,0 +1,187 @@
+/*
+ * Copyright 2011 Google Inc. All rights reserved.
+ * Copyright 2012 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:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * 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.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND 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 THE COPYRIGHT
+ * OWNER 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.
+ */
+
+// ICU integration functions.
+
+#include "config.h"
+
+#if USE(WTFURL)
+
+#include "URLCanonInternal.h" // for _itoa_s
+#include <stdlib.h>
+#include <string.h>
+#include <unicode/ucnv.h>
+#include <unicode/ucnv_cb.h>
+#include <unicode/uidna.h>
+
+namespace WTF {
+
+namespace URLCanonicalizer {
+
+namespace {
+
+// Called when converting a character that can not be represented, this will
+// append an escaped version of the numerical character reference for that code
+// point. It is of the form "&#1234;" and we will escape the non-digits to
+// "%26%231234%3B". Why? This is what Netscape did back in the olden days.
+void appendURLEscapedChar(const void* /* context */,
+ UConverterFromUnicodeArgs* fromArgs,
+ const UChar* /* code_units */,
+ int32_t /* length */,
+ UChar32 codePoint,
+ UConverterCallbackReason reason,
+ UErrorCode* err)
+{
+ if (reason == UCNV_UNASSIGNED) {
+ *err = U_ZERO_ERROR;
+
+ const static int prefixLength = 6;
+ const static char prefix[prefixLength + 1] = "%26%23"; // "&#" percent-escaped
+ ucnv_cbFromUWriteBytes(fromArgs, prefix, prefixLength, 0, err);
+
+ ASSERT(codePoint < 0x110000);
+ char number[8]; // Max Unicode code point is 7 digits.
+ _itoa_s(codePoint, number, 10);
+ int numberLength = static_cast<int>(strlen(number));
+ ucnv_cbFromUWriteBytes(fromArgs, number, numberLength, 0, err);
+
+ const static int postfixLength = 3;
+ const static char postfix[postfixLength + 1] = "%3B"; // ";" percent-escaped
+ ucnv_cbFromUWriteBytes(fromArgs, postfix, postfixLength, 0, err);
+ }
+}
+
+// A class for scoping the installation of the invalid character callback.
+class AppendHandlerInstaller {
+public:
+ // The owner of this object must ensure that the converter is alive for the
+ // duration of this object's lifetime.
+ AppendHandlerInstaller(UConverter* converter)
+ : m_converter(converter)
+ {
+ UErrorCode err = U_ZERO_ERROR;
+ ucnv_setFromUCallBack(m_converter, appendURLEscapedChar, 0, &m_oldCallback, &m_oldContext, &err);
+ }
+
+ ~AppendHandlerInstaller()
+ {
+ UErrorCode err = U_ZERO_ERROR;
+ ucnv_setFromUCallBack(m_converter, m_oldCallback, m_oldContext, 0, 0, &err);
+ }
+
+private:
+ UConverter* m_converter;
+
+ UConverterFromUCallback m_oldCallback;
+ const void* m_oldContext;
+};
+
+} // namespace
+
+// Converts the Unicode input representing a hostname to ASCII using IDN rules.
+// The output must be ASCII, but is represented as wide characters.
+//
+// On success, the output will be filled with the ASCII host name and it will
+// return true. Unlike most other canonicalization functions, this assumes that
+// the output is empty. The beginning of the host will be at offset 0, and
+// the length of the output will be set to the length of the new host name.
+//
+// On error, this will return false. The output in this case is undefined.
+bool IDNToASCII(const UChar* src, int sourceLength, URLBuffer<UChar>& output)
+{
+ ASSERT(!output.length()); // Output buffer is assumed empty.
+ while (true) {
+ // Use ALLOW_UNASSIGNED to be more tolerant of hostnames that violate
+ // the spec (which do exist). This does not present any risk and is a
+ // little more future proof.
+ UErrorCode err = U_ZERO_ERROR;
+ int numConverted = uidna_IDNToASCII(src, sourceLength, output.data(),
+ output.capacity(),
+ UIDNA_ALLOW_UNASSIGNED, 0, &err);
+ if (err == U_ZERO_ERROR) {
+ output.setLength(numConverted);
+ return true;
+ }
+ if (err != U_BUFFER_OVERFLOW_ERROR)
+ return false; // Unknown error, give up.
+
+ // Not enough room in our buffer, expand.
+ output.resize(output.capacity() * 2);
+ }
+}
+
+bool readUTFChar(const char* str, int* begin, int length, unsigned* codePointOut)
+{
+ int codePoint; // Avoids warning when U8_NEXT writes -1 to it.
+ U8_NEXT(str, *begin, length, codePoint);
+ *codePointOut = static_cast<unsigned>(codePoint);
+
+ // The ICU macro above moves to the next char, we want to point to the last
+ // char consumed.
+ (*begin)--;
+
+ // Validate the decoded value.
+ if (U_IS_UNICODE_CHAR(codePoint))
+ return true;
+ *codePointOut = kUnicodeReplacementCharacter;
+ return false;
+}
+
+bool readUTFChar(const UChar* str, int* begin, int length, unsigned* codePoint)
+{
+ if (U16_IS_SURROGATE(str[*begin])) {
+ if (!U16_IS_SURROGATE_LEAD(str[*begin]) || *begin + 1 >= length || !U16_IS_TRAIL(str[*begin + 1])) {
+ // Invalid surrogate pair.
+ *codePoint = kUnicodeReplacementCharacter;
+ return false;
+ }
+
+ // Valid surrogate pair.
+ *codePoint = U16_GET_SUPPLEMENTARY(str[*begin], str[*begin + 1]);
+ (*begin)++;
+ } else {
+ // Not a surrogate, just one 16-bit word.
+ *codePoint = str[*begin];
+ }
+
+ if (U_IS_UNICODE_CHAR(*codePoint))
+ return true;
+
+ // Invalid code point.
+ *codePoint = kUnicodeReplacementCharacter;
+ return false;
+}
+
+} // namespace URLCanonicalizer
+
+} // namespace WTF
+
+#endif // USE(WTFURL)
diff --git a/Source/WTF/wtf/url/src/URLCanonIP.cpp b/Source/WTF/wtf/url/src/URLCanonIP.cpp
new file mode 100644
index 000000000..4462353cb
--- /dev/null
+++ b/Source/WTF/wtf/url/src/URLCanonIP.cpp
@@ -0,0 +1,683 @@
+/*
+ * Copyright 2009 Google Inc. All rights reserved.
+ * Copyright 2012 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:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * 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.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND 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 THE COPYRIGHT
+ * OWNER 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 "URLCanonInternal.h"
+#include "URLCharacterTypes.h"
+#include <limits>
+#include <stdint.h>
+#include <stdlib.h>
+
+#if USE(WTFURL)
+
+namespace WTF {
+
+namespace URLCanonicalizer {
+
+namespace {
+
+// Converts one of the character types that represent a numerical base to the
+// corresponding base.
+static inline int baseForType(URLCharacterTypes::CharacterTypes type)
+{
+ switch (type) {
+ case URLCharacterTypes::HexadecimalCharacter:
+ return 16;
+ case URLCharacterTypes::DecimalCharacter:
+ return 10;
+ case URLCharacterTypes::OctalCharacter:
+ return 8;
+ default:
+ return 0;
+ }
+}
+
+// Converts an IPv4 component to a 32-bit number, while checking for overflow.
+//
+// Possible return values:
+// - IPV4 - The number was valid, and did not overflow.
+// - BROKEN - The input was numeric, but too large for a 32-bit field.
+// - NEUTRAL - Input was not numeric.
+//
+// The input is assumed to be ASCII. FindIPv4Components should have stripped
+// out any input that is greater than 7 bits. The components are assumed
+// to be non-empty.
+template<typename CharacterType>
+CanonHostInfo::Family IPv4ComponentToNumber(const CharacterType* spec, const URLComponent& component, uint32_t* number)
+{
+ // Figure out the base
+ URLCharacterTypes::CharacterTypes base;
+ int basePrefixLength = 0; // Size of the prefix for this base.
+ if (spec[component.begin()] == '0') {
+ // Either hex or dec, or a standalone zero.
+ if (component.length() == 1) {
+ base = URLCharacterTypes::DecimalCharacter;
+ } else if (spec[component.begin() + 1] == 'X' || spec[component.begin() + 1] == 'x') {
+ base = URLCharacterTypes::HexadecimalCharacter;
+ basePrefixLength = 2;
+ } else {
+ base = URLCharacterTypes::OctalCharacter;
+ basePrefixLength = 1;
+ }
+ } else
+ base = URLCharacterTypes::DecimalCharacter;
+
+ // Extend the prefix to consume all leading zeros.
+ while (basePrefixLength < component.length() && spec[component.begin() + basePrefixLength] == '0')
+ ++basePrefixLength;
+
+ // Put the component, minus any base prefix, into a zero-terminated buffer so
+ // we can call the standard library. Because leading zeros have already been
+ // discarded, filling the entire buffer is guaranteed to trigger the 32-bit
+ // overflow check.
+ const int kMaxComponentLen = 16;
+ char buf[kMaxComponentLen + 1]; // digits + '\0'
+ int destI = 0;
+ for (int i = component.begin() + basePrefixLength; i < component.end(); i++) {
+ // We know the input is 7-bit, so convert to narrow (if this is the wide
+ // version of the template) by casting.
+ char input = static_cast<char>(spec[i]);
+
+ // Validate that this character is OK for the given base.
+ if (!URLCharacterTypes::isCharacterOfType(input, base))
+ return CanonHostInfo::NEUTRAL;
+
+ // Fill the buffer, if there's space remaining. This check allows us to
+ // verify that all characters are numeric, even those that don't fit.
+ if (destI < kMaxComponentLen)
+ buf[destI++] = input;
+ }
+
+ buf[destI] = '\0';
+
+ // Use the 64-bit strtoi so we get a big number (no hex, decimal, or octal
+ // number can overflow a 64-bit number in <= 16 characters).
+ uint64_t num = _strtoui64(buf, 0, baseForType(base));
+
+ // Check for 32-bit overflow.
+ if (num > std::numeric_limits<uint32_t>::max())
+ return CanonHostInfo::BROKEN;
+
+ // No overflow. Success!
+ *number = static_cast<uint32_t>(num);
+ return CanonHostInfo::IPV4;
+}
+
+template<typename CharacterType, typename UCHAR>
+bool doFindIPv4Components(const CharacterType* spec, const URLComponent& host, URLComponent components[4])
+{
+ if (!host.isNonEmpty())
+ return false;
+
+ int currentComponent = 0; // Index of the component we're working on.
+ int currentComponentBegin = host.begin(); // Start of the current component.
+ int end = host.end();
+ for (int i = host.begin(); /* nothing */; ++i) {
+ if (i >= end || spec[i] == '.') {
+ // Found the end of the current component.
+ int componentLength = i - currentComponentBegin;
+ components[currentComponent] = URLComponent(currentComponentBegin, componentLength);
+
+ // The next component starts after the dot.
+ currentComponentBegin = i + 1;
+ currentComponent++;
+
+ // Don't allow empty components (two dots in a row), except we may
+ // allow an empty component at the end (this would indicate that the
+ // input ends in a dot). We also want to error if the component is
+ // empty and it's the only component (currentComponent == 1).
+ if (!componentLength && (i < end || currentComponent == 1))
+ return false;
+
+ if (i >= end)
+ break; // End of the input.
+
+ if (currentComponent == 4) {
+ // Anything else after the 4th component is an error unless it is a
+ // dot that would otherwise be treated as the end of input.
+ if (spec[i] == '.' && i + 1 == end)
+ break;
+ return false;
+ }
+ } else if (static_cast<UCHAR>(spec[i]) >= 0x80 || !URLCharacterTypes::isIPv4Char(static_cast<unsigned char>(spec[i]))) {
+ // Invalid character for an IPv4 address.
+ return false;
+ }
+ }
+
+ // Fill in any unused components.
+ while (currentComponent < 4)
+ components[currentComponent++] = URLComponent();
+ return true;
+}
+
+static bool FindIPv4Components(const char* spec, const URLComponent& host, URLComponent components[4])
+{
+ return doFindIPv4Components<char, unsigned char>(spec, host, components);
+}
+
+static bool FindIPv4Components(const UChar* spec, const URLComponent& host, URLComponent components[4])
+{
+ return doFindIPv4Components<UChar, UChar>(spec, host, components);
+}
+
+template<typename CharacterType>
+CanonHostInfo::Family doIPv4AddressToNumber(const CharacterType* spec, const URLComponent& host, unsigned char address[4], int& ipv4ComponentsCount)
+{
+ // The identified components. Not all may exist.
+ URLComponent components[4];
+ if (!FindIPv4Components(spec, host, components))
+ return CanonHostInfo::NEUTRAL;
+
+ // Convert existing components to digits. Values up to
+ // |existingComponents| will be valid.
+ uint32_t componentValues[4];
+ int existingComponents = 0;
+
+ // Set to true if one or more components are BROKEN. BROKEN is only
+ // returned if all components are IPV4 or BROKEN, so, for example,
+ // 12345678912345.de returns NEUTRAL rather than broken.
+ bool broken = false;
+ for (int i = 0; i < 4; i++) {
+ if (components[i].length() <= 0)
+ continue;
+ CanonHostInfo::Family family = IPv4ComponentToNumber(spec, components[i], &componentValues[existingComponents]);
+
+ if (family == CanonHostInfo::BROKEN)
+ broken = true;
+ else if (family != CanonHostInfo::IPV4) {
+ // Stop if we hit a non-BROKEN invalid non-empty component.
+ return family;
+ }
+
+ existingComponents++;
+ }
+
+ if (broken)
+ return CanonHostInfo::BROKEN;
+
+ // Use that sequence of numbers to fill out the 4-component IP address.
+
+ // First, process all components but the last, while making sure each fits
+ // within an 8-bit field.
+ for (int i = 0; i < existingComponents - 1; i++) {
+ if (componentValues[i] > std::numeric_limits<uint8_t>::max())
+ return CanonHostInfo::BROKEN;
+ address[i] = static_cast<unsigned char>(componentValues[i]);
+ }
+
+ // Next, consume the last component to fill in the remaining bytes.
+ uint32_t lastValue = componentValues[existingComponents - 1];
+ for (int i = 3; i >= existingComponents - 1; i--) {
+ address[i] = static_cast<unsigned char>(lastValue);
+ lastValue >>= 8;
+ }
+
+ // If the last component has residual bits, report overflow.
+ if (lastValue)
+ return CanonHostInfo::BROKEN;
+
+ // Tell the caller how many components we saw.
+ ipv4ComponentsCount = existingComponents;
+
+ // Success!
+ return CanonHostInfo::IPV4;
+}
+
+static inline void appendIPv4Address(const unsigned char address[4], URLBuffer<char>& output)
+{
+ for (int i = 0; i < 4; ++i) {
+ char buffer[16];
+ _itoa_s(address[i], buffer, 10);
+
+ for (int ch = 0; buffer[ch]; ch++)
+ output.append(buffer[ch]);
+
+ if (i != 3)
+ output.append('.');
+ }
+}
+
+// Return true if we've made a final IPV4/BROKEN decision, false if the result
+// is NEUTRAL, and we could use a second opinion.
+template<typename CharacterType, typename UCHAR>
+bool doCanonicalizeIPv4Address(const CharacterType* spec, const URLComponent& host, URLBuffer<char>& output, CanonHostInfo& hostInfo)
+{
+ hostInfo.family = doIPv4AddressToNumber(spec, host, hostInfo.address, hostInfo.ipv4ComponentsCount);
+
+ switch (hostInfo.family) {
+ case CanonHostInfo::IPV4:
+ // Definitely an IPv4 address.
+ hostInfo.ouputHost.setBegin(output.length());
+ appendIPv4Address(hostInfo.address, output);
+ hostInfo.ouputHost.setLength(output.length() - hostInfo.ouputHost.begin());
+ return true;
+ case CanonHostInfo::BROKEN:
+ // Definitely broken.
+ return true;
+ default:
+ // Could be IPv6 or a hostname.
+ return false;
+ }
+}
+
+// Helper class that describes the main components of an IPv6 input string.
+// See the following examples to understand how it breaks up an input string:
+//
+// [Example 1]: input = "[::aa:bb]"
+// ==> numHexComponents = 2
+// ==> hexComponents[0] = Component(3,2) "aa"
+// ==> hexComponents[1] = Component(6,2) "bb"
+// ==> indexOfContraction = 0
+// ==> ipv4Component = Component(0, -1)
+//
+// [Example 2]: input = "[1:2::3:4:5]"
+// ==> numHexComponents = 5
+// ==> hexComponents[0] = Component(1,1) "1"
+// ==> hexComponents[1] = Component(3,1) "2"
+// ==> hexComponents[2] = Component(6,1) "3"
+// ==> hexComponents[3] = Component(8,1) "4"
+// ==> hexComponents[4] = Component(10,1) "5"
+// ==> indexOfContraction = 2
+// ==> ipv4Component = Component(0, -1)
+//
+// [Example 3]: input = "[::ffff:192.168.0.1]"
+// ==> numHexComponents = 1
+// ==> hexComponents[0] = Component(3,4) "ffff"
+// ==> indexOfContraction = 0
+// ==> ipv4Component = Component(8, 11) "192.168.0.1"
+//
+// [Example 4]: input = "[1::]"
+// ==> numHexComponents = 1
+// ==> hexComponents[0] = Component(1,1) "1"
+// ==> indexOfContraction = 1
+// ==> ipv4Component = Component(0, -1)
+//
+// [Example 5]: input = "[::192.168.0.1]"
+// ==> numHexComponents = 0
+// ==> indexOfContraction = 0
+// ==> ipv4Component = Component(8, 11) "192.168.0.1"
+//
+struct IPv6Parsed {
+ // Zero-out the parse information.
+ void reset()
+ {
+ numHexComponents = 0;
+ indexOfContraction = -1;
+ ipv4Component.reset();
+ }
+
+ // There can be up to 8 hex components (colon separated) in the literal.
+ URLComponent hexComponents[8];
+
+ // The count of hex components present. Ranges from [0,8].
+ int numHexComponents;
+
+ // The index of the hex component that the "::" contraction precedes, or
+ // -1 if there is no contraction.
+ int indexOfContraction;
+
+ // The range of characters which are an IPv4 literal.
+ URLComponent ipv4Component;
+};
+
+// Parse the IPv6 input string. If parsing succeeded returns true and fills
+// |parsed| with the information. If parsing failed (because the input is
+// invalid) returns false.
+template<typename CharacterType, typename UCHAR>
+bool doParseIPv6(const CharacterType* spec, const URLComponent& host, IPv6Parsed& parsed)
+{
+ // Zero-out the info.
+ parsed.reset();
+
+ if (!host.isNonEmpty())
+ return false;
+
+ // The index for start and end of address range (no brackets).
+ int begin = host.begin();
+ int end = host.end();
+
+ int currentComponentBegin = begin; // Start of the current component.
+
+ // Scan through the input, searching for hex components, "::" contractions,
+ // and IPv4 components.
+ for (int i = begin; /* i <= end */; i++) {
+ bool isColon = spec[i] == ':';
+ bool isContraction = isColon && i < end - 1 && spec[i + 1] == ':';
+
+ // We reached the end of the current component if we encounter a colon
+ // (separator between hex components, or start of a contraction), or end of
+ // input.
+ if (isColon || i == end) {
+ int componentLength = i - currentComponentBegin;
+
+ // A component should not have more than 4 hex digits.
+ if (componentLength > 4)
+ return false;
+
+ // Don't allow empty components.
+ if (!componentLength) {
+ // The exception is when contractions appear at beginning of the
+ // input or at the end of the input.
+ if (!((isContraction && i == begin) || (i == end && parsed.indexOfContraction == parsed.numHexComponents)))
+ return false;
+ }
+
+ // Add the hex component we just found to running list.
+ if (componentLength > 0) {
+ // Can't have more than 8 components!
+ if (parsed.numHexComponents >= 8)
+ return false;
+
+ parsed.hexComponents[parsed.numHexComponents++] =
+ URLComponent(currentComponentBegin, componentLength);
+ }
+ }
+
+ if (i == end)
+ break; // Reached the end of the input, DONE.
+
+ // We found a "::" contraction.
+ if (isContraction) {
+ // There can be at most one contraction in the literal.
+ if (parsed.indexOfContraction != -1)
+ return false;
+ parsed.indexOfContraction = parsed.numHexComponents;
+ ++i; // Consume the colon we peeked.
+ }
+
+ if (isColon) {
+ // Colons are separators between components, keep track of where the
+ // current component started (after this colon).
+ currentComponentBegin = i + 1;
+ } else {
+ if (static_cast<UCHAR>(spec[i]) >= 0x80)
+ return false; // Not ASCII.
+
+ if (!URLCharacterTypes::isHexChar(static_cast<unsigned char>(spec[i]))) {
+ // Regular components are hex numbers. It is also possible for
+ // a component to be an IPv4 address in dotted form.
+ if (URLCharacterTypes::isIPv4Char(static_cast<unsigned char>(spec[i]))) {
+ // Since IPv4 address can only appear at the end, assume the rest
+ // of the string is an IPv4 address. (We will parse this separately
+ // later).
+ parsed.ipv4Component = URLComponent::fromRange(currentComponentBegin, end);
+ break;
+ }
+ // The character was neither a hex digit, nor an IPv4 character.
+ return false;
+ }
+ }
+ }
+
+ return true;
+}
+
+// Verifies the parsed IPv6 information, checking that the various components
+// add up to the right number of bits (hex components are 16 bits, while
+// embedded IPv4 formats are 32 bits, and contractions are placeholdes for
+// 16 or more bits). Returns true if sizes match up, false otherwise. On
+// success writes the length of the contraction (if any) to
+// |outNumBytesOfContraction|.
+bool CheckIPv6ComponentsSize(const IPv6Parsed& parsed, int* outNumBytesOfContraction)
+{
+ // Each group of four hex digits contributes 16 bits.
+ int numBytesWithoutContraction = parsed.numHexComponents * 2;
+
+ // If an IPv4 address was embedded at the end, it contributes 32 bits.
+ if (parsed.ipv4Component.isValid())
+ numBytesWithoutContraction += 4;
+
+ // If there was a "::" contraction, its size is going to be:
+ // MAX([16bits], [128bits] - numBytesWithoutContraction).
+ int numBytesOfContraction = 0;
+ if (parsed.indexOfContraction != -1) {
+ numBytesOfContraction = 16 - numBytesWithoutContraction;
+ if (numBytesOfContraction < 2)
+ numBytesOfContraction = 2;
+ }
+
+ // Check that the numbers add up.
+ if (numBytesWithoutContraction + numBytesOfContraction != 16)
+ return false;
+
+ *outNumBytesOfContraction = numBytesOfContraction;
+ return true;
+}
+
+// Converts a hex comonent into a number. This cannot fail since the caller has
+// already verified that each character in the string was a hex digit, and
+// that there were no more than 4 characters.
+template<typename CharacterType>
+uint16_t IPv6HexComponentToNumber(const CharacterType* spec, const URLComponent& component)
+{
+ ASSERT(component.length() <= 4);
+
+ // Copy the hex string into a C-string.
+ char buf[5];
+ for (int i = 0; i < component.length(); ++i)
+ buf[i] = static_cast<char>(spec[component.begin() + i]);
+ buf[component.length()] = '\0';
+
+ // Convert it to a number (overflow is not possible, since with 4 hex
+ // characters we can at most have a 16 bit number).
+ return static_cast<uint16_t>(_strtoui64(buf, 0, 16));
+}
+
+// Converts an IPv6 address to a 128-bit number (network byte order), returning
+// true on success. False means that the input was not a valid IPv6 address.
+template<typename CharacterType, typename UCHAR>
+bool doIPv6AddressToNumber(const CharacterType* spec,
+ const URLComponent& host,
+ unsigned char address[16])
+{
+ // Make sure the component is bounded by '[' and ']'.
+ int end = host.end();
+ if (!host.isNonEmpty() || spec[host.begin()] != '[' || spec[end - 1] != ']')
+ return false;
+
+ // Exclude the square brackets.
+ URLComponent ipv6Component(host.begin() + 1, host.length() - 2);
+
+ // Parse the IPv6 address -- identify where all the colon separated hex
+ // components are, the "::" contraction, and the embedded IPv4 address.
+ IPv6Parsed ipv6Parsed;
+ if (!doParseIPv6<CharacterType, UCHAR>(spec, ipv6Component, ipv6Parsed))
+ return false;
+
+ // Do some basic size checks to make sure that the address doesn't
+ // specify more than 128 bits or fewer than 128 bits. This also resolves
+ // how may zero bytes the "::" contraction represents.
+ int numBytesOfContraction;
+ if (!CheckIPv6ComponentsSize(ipv6Parsed, &numBytesOfContraction))
+ return false;
+
+ int currentIndexInAddress = 0;
+
+ // Loop through each hex components, and contraction in order.
+ for (int i = 0; i <= ipv6Parsed.numHexComponents; ++i) {
+ // Append the contraction if it appears before this component.
+ if (i == ipv6Parsed.indexOfContraction) {
+ for (int j = 0; j < numBytesOfContraction; ++j)
+ address[currentIndexInAddress++] = 0;
+ }
+ // Append the hex component's value.
+ if (i != ipv6Parsed.numHexComponents) {
+ // Get the 16-bit value for this hex component.
+ uint16_t number = IPv6HexComponentToNumber<CharacterType>(spec, ipv6Parsed.hexComponents[i]);
+ // Append to |address|, in network byte order.
+ address[currentIndexInAddress++] = (number & 0xFF00) >> 8;
+ address[currentIndexInAddress++] = (number & 0x00FF);
+ }
+ }
+
+ // If there was an IPv4 section, convert it into a 32-bit number and append
+ // it to |address|.
+ if (ipv6Parsed.ipv4Component.isValid()) {
+ // Append the 32-bit number to |address|.
+ int ignoredIPv4ComponentsCount;
+ if (CanonHostInfo::IPV4 !=
+ doIPv4AddressToNumber(spec, ipv6Parsed.ipv4Component, &address[currentIndexInAddress], ignoredIPv4ComponentsCount))
+ return false;
+ }
+
+ return true;
+}
+
+// Searches for the longest sequence of zeros in |address|, and writes the
+// range into |contractionRange|. The run of zeros must be at least 16 bits,
+// and if there is a tie the first is chosen.
+void ChooseIPv6ContractionRange(const unsigned char address[16], URLComponent* contractionRange)
+{
+ // The longest run of zeros in |address| seen so far.
+ URLComponent maxRange;
+
+ // The current run of zeros in |address| being iterated over.
+ URLComponent currentRange;
+
+ for (int i = 0; i < 16; i += 2) {
+ // Test for 16 bits worth of zero.
+ bool isZero = (!address[i] && !address[i + 1]);
+
+ if (isZero) {
+ // Add the zero to the current range (or start a new one).
+ if (!currentRange.isValid())
+ currentRange = URLComponent(i, 0);
+ currentRange.setLength(currentRange.length() + 2);
+ }
+
+ if (!isZero || i == 14) {
+ // Just completed a run of zeros. If the run is greater than 16 bits,
+ // it is a candidate for the contraction.
+ if (currentRange.length() > 2 && currentRange.length() > maxRange.length())
+ maxRange = currentRange;
+
+ currentRange.reset();
+ }
+ }
+ *contractionRange = maxRange;
+}
+
+static inline void appendIPv6Address(const unsigned char address[16], URLBuffer<char>& output)
+{
+ // We will output the address according to the rules in:
+ // http://tools.ietf.org/html/draft-kawamura-ipv6-text-representation-01#section-4
+
+ // Start by finding where to place the "::" contraction (if any).
+ URLComponent contractionRange;
+ ChooseIPv6ContractionRange(address, &contractionRange);
+
+ for (int i = 0; i <= 14;) {
+ // We check 2 bytes at a time, from bytes (0, 1) to (14, 15), inclusive.
+ ASSERT(!(i % 2));
+ if (i == contractionRange.begin() && contractionRange.length() > 0) {
+ // Jump over the contraction.
+ if (!i)
+ output.append(':');
+ output.append(':');
+ i = contractionRange.end();
+ } else {
+ // Consume the next 16 bits from |address|.
+ int x = address[i] << 8 | address[i + 1];
+
+ i += 2;
+
+ // Stringify the 16 bit number (at most requires 4 hex digits).
+ char str[5];
+ _itoa_s(x, str, 16);
+ for (int ch = 0; str[ch]; ++ch)
+ output.append(str[ch]);
+
+ // Put a colon after each number, except the last.
+ if (i < 16)
+ output.append(':');
+ }
+ }
+}
+
+// Return true if we've made a final IPV6/BROKEN decision, false if the result
+// is NEUTRAL, and we could use a second opinion.
+template<typename CharacterType, typename UCHAR>
+bool doCanonicalizeIPv6Address(const CharacterType* spec, const URLComponent& host, URLBuffer<char>& output, CanonHostInfo& hostInfo)
+{
+ // Turn the IP address into a 128 bit number.
+ if (!doIPv6AddressToNumber<CharacterType, UCHAR>(spec, host, hostInfo.address)) {
+ // If it's not an IPv6 address, scan for characters that should *only*
+ // exist in an IPv6 address.
+ for (int i = host.begin(); i < host.end(); i++) {
+ switch (spec[i]) {
+ case '[':
+ case ']':
+ case ':':
+ hostInfo.family = CanonHostInfo::BROKEN;
+ return true;
+ }
+ }
+
+ // No invalid characters. Could still be IPv4 or a hostname.
+ hostInfo.family = CanonHostInfo::NEUTRAL;
+ return false;
+ }
+
+ hostInfo.ouputHost.setBegin(output.length());
+ output.append('[');
+ appendIPv6Address(hostInfo.address, output);
+ output.append(']');
+ hostInfo.ouputHost.setLength(output.length() - hostInfo.ouputHost.begin());
+
+ hostInfo.family = CanonHostInfo::IPV6;
+ return true;
+}
+
+} // namespace
+
+void canonicalizeIPAddress(const char* spec, const URLComponent& host, URLBuffer<char>& output, CanonHostInfo& hostInfo)
+{
+ if (doCanonicalizeIPv4Address<char, unsigned char>(spec, host, output, hostInfo))
+ return;
+ if (doCanonicalizeIPv6Address<char, unsigned char>(spec, host, output, hostInfo))
+ return;
+}
+
+void canonicalizeIPAddress(const UChar* spec, const URLComponent& host, URLBuffer<char>& output, CanonHostInfo& hostInfo)
+{
+ if (doCanonicalizeIPv4Address<UChar, UChar>(spec, host, output, hostInfo))
+ return;
+ if (doCanonicalizeIPv6Address<UChar, UChar>(spec, host, output, hostInfo))
+ return;
+}
+
+} // namespace URLCanonicalizer
+
+} // namespace WTF
+
+#endif // USE(WTFURL)
diff --git a/Source/WTF/wtf/url/src/URLCanonInternal.cpp b/Source/WTF/wtf/url/src/URLCanonInternal.cpp
new file mode 100644
index 000000000..b7ae09814
--- /dev/null
+++ b/Source/WTF/wtf/url/src/URLCanonInternal.cpp
@@ -0,0 +1,310 @@
+/*
+ * Copyright 2007 Google Inc. All rights reserved.
+ * Copyright 2012 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:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * 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.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND 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 THE COPYRIGHT
+ * OWNER 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 "URLCanonInternal.h"
+
+#include <cstdio>
+#include <errno.h>
+#include <stdlib.h>
+#include <string>
+
+#if USE(WTFURL)
+
+namespace WTF {
+
+namespace URLCanonicalizer {
+
+namespace {
+
+template<typename CharacterType, typename UCHAR>
+void doAppendStringOfType(const CharacterType* source, int length, URLCharacterTypes::CharacterTypes type, URLBuffer<char>& output)
+{
+ for (int i = 0; i < length; ++i) {
+ if (static_cast<UCHAR>(source[i]) >= 0x80) {
+ // ReadChar will fill the code point with kUnicodeReplacementCharacter
+ // when the input is invalid, which is what we want.
+ unsigned codePoint;
+ readUTFChar(source, &i, length, &codePoint);
+ AppendUTF8EscapedValue(codePoint, output);
+ } else {
+ // Just append the 7-bit character, possibly escaping it.
+ unsigned char uch = static_cast<unsigned char>(source[i]);
+ if (!URLCharacterTypes::isCharacterOfType(uch, type))
+ appendURLEscapedCharacter(uch, output);
+ else
+ output.append(uch);
+ }
+ }
+}
+
+// This function assumes the input values are all contained in 8-bit,
+// although it allows any type. Returns true if input is valid, false if not.
+template<typename CharacterType, typename UCHAR>
+void doAppendInvalidNarrowString(const CharacterType* spec, int begin, int end, URLBuffer<char>& output)
+{
+ for (int i = begin; i < end; ++i) {
+ UCHAR uch = static_cast<UCHAR>(spec[i]);
+ if (uch >= 0x80) {
+ // Handle UTF-8/16 encodings. This call will correctly handle the error
+ // case by appending the invalid character.
+ AppendUTF8EscapedChar(spec, &i, end, output);
+ } else if (uch <= ' ' || uch == 0x7f) {
+ // This function is for error handling, so we escape all control
+ // characters and spaces, but not anything else since we lack
+ // context to do something more specific.
+ appendURLEscapedCharacter(static_cast<unsigned char>(uch), output);
+ } else
+ output.append(static_cast<char>(uch));
+ }
+}
+
+// Overrides one component, see the URLCanonicalizer::Replacements structure for
+// what the various combionations of source pointer and component mean.
+void doOverrideComponent(const char* overrideSource, const URLComponent& overrideComponent, const char*& destination, URLComponent& destinationComponent)
+{
+ if (overrideSource) {
+ destination = overrideSource;
+ destinationComponent = overrideComponent;
+ }
+}
+
+// Similar to doOverrideComponent except that it takes a UTF-16 input and does
+// not actually set the output character pointer.
+//
+// The input is converted to UTF-8 at the end of the given buffer as a temporary
+// holding place. The component indentifying the portion of the buffer used in
+// the |utf8Buffer| will be specified in |*destinationComponent|.
+//
+// This will not actually set any |dest| pointer like doOverrideComponent
+// does because all of the pointers will point into the |utf8Buffer|, which
+// may get resized while we're overriding a subsequent component. Instead, the
+// caller should use the beginning of the |utf8Buffer| as the string pointer
+// for all components once all overrides have been prepared.
+bool PrepareUTF16OverrideComponent(const UChar* overrideSource,
+ const URLComponent& overrideComponent,
+ URLBuffer<char>& utf8Buffer,
+ URLComponent* destinationComponent)
+{
+ bool success = true;
+ if (overrideSource) {
+ if (!overrideComponent.isValid()) {
+ // Non-"valid" component (means delete), so we need to preserve that.
+ *destinationComponent = URLComponent();
+ } else {
+ // Convert to UTF-8.
+ destinationComponent->setBegin(utf8Buffer.length());
+ success = ConvertUTF16ToUTF8(&overrideSource[overrideComponent.begin()],
+ overrideComponent.length(), utf8Buffer);
+ destinationComponent->setLength(utf8Buffer.length() - destinationComponent->begin());
+ }
+ }
+ return success;
+}
+
+} // namespace
+
+const char kCharToHexLookup[8] = {
+ 0, // 0x00 - 0x1f
+ '0', // 0x20 - 0x3f: digits 0 - 9 are 0x30 - 0x39
+ 'A' - 10, // 0x40 - 0x5f: letters A - F are 0x41 - 0x46
+ 'a' - 10, // 0x60 - 0x7f: letters a - f are 0x61 - 0x66
+ 0, // 0x80 - 0x9F
+ 0, // 0xA0 - 0xBF
+ 0, // 0xC0 - 0xDF
+ 0, // 0xE0 - 0xFF
+};
+
+const UChar kUnicodeReplacementCharacter = 0xfffd;
+
+void appendStringOfType(const char* source, int length, URLCharacterTypes::CharacterTypes urlComponentType, URLBuffer<char>& output)
+{
+ doAppendStringOfType<char, unsigned char>(source, length, urlComponentType, output);
+}
+
+void appendStringOfType(const UChar* source, int length, URLCharacterTypes::CharacterTypes urlComponentType, URLBuffer<char>& output)
+{
+ doAppendStringOfType<UChar, UChar>(source, length, urlComponentType, output);
+}
+
+void AppendInvalidNarrowString(const char* spec, int begin, int end, URLBuffer<char>& output)
+{
+ doAppendInvalidNarrowString<char, unsigned char>(spec, begin, end, output);
+}
+
+void AppendInvalidNarrowString(const UChar* spec, int begin, int end, URLBuffer<char>& output)
+{
+ doAppendInvalidNarrowString<UChar, UChar>(spec, begin, end, output);
+}
+
+bool ConvertUTF16ToUTF8(const UChar* input, int inputLength, URLBuffer<char>& output)
+{
+ bool success = true;
+ for (int i = 0; i < inputLength; ++i) {
+ unsigned codePoint;
+ success &= readUTFChar(input, &i, inputLength, &codePoint);
+ AppendUTF8Value(codePoint, output);
+ }
+ return success;
+}
+
+bool ConvertUTF8ToUTF16(const char* input, int inputLength, URLBuffer<UChar>& output)
+{
+ bool success = true;
+ for (int i = 0; i < inputLength; i++) {
+ unsigned codePoint;
+ success &= readUTFChar(input, &i, inputLength, &codePoint);
+ AppendUTF16Value(codePoint, output);
+ }
+ return success;
+}
+
+void SetupOverrideComponents(const char* /* base */,
+ const Replacements<char>& repl,
+ URLComponentSource<char>* source,
+ URLSegments* parsed)
+{
+ // Get the source and parsed structures of the things we are replacing.
+ const URLComponentSource<char>& replSource = repl.sources();
+ const URLSegments& replParsed = repl.components();
+
+ doOverrideComponent(replSource.scheme, replParsed.scheme, source->scheme, parsed->scheme);
+ doOverrideComponent(replSource.username, replParsed.username, source->username, parsed->username);
+ doOverrideComponent(replSource.password, replParsed.password, source->password, parsed->password);
+
+ // Our host should be empty if not present, so override the default setup.
+ doOverrideComponent(replSource.host, replParsed.host, source->host, parsed->host);
+ if (parsed->host.length() == -1)
+ parsed->host.setLength(0);
+
+ doOverrideComponent(replSource.port, replParsed.port, source->port, parsed->port);
+ doOverrideComponent(replSource.path, replParsed.path, source->path, parsed->path);
+ doOverrideComponent(replSource.query, replParsed.query, source->query, parsed->query);
+ doOverrideComponent(replSource.ref, replParsed.fragment, source->ref, parsed->fragment);
+}
+
+bool SetupUTF16OverrideComponents(const char* /* base */,
+ const Replacements<UChar>& repl,
+ URLBuffer<char>& utf8Buffer,
+ URLComponentSource<char>* source,
+ URLSegments* parsed)
+ {
+ bool success = true;
+
+ // Get the source and parsed structures of the things we are replacing.
+ const URLComponentSource<UChar>& replSource = repl.sources();
+ const URLSegments& replParsed = repl.components();
+
+ success &= PrepareUTF16OverrideComponent(replSource.scheme, replParsed.scheme,
+ utf8Buffer, &parsed->scheme);
+ success &= PrepareUTF16OverrideComponent(replSource.username, replParsed.username,
+ utf8Buffer, &parsed->username);
+ success &= PrepareUTF16OverrideComponent(replSource.password, replParsed.password,
+ utf8Buffer, &parsed->password);
+ success &= PrepareUTF16OverrideComponent(replSource.host, replParsed.host,
+ utf8Buffer, &parsed->host);
+ success &= PrepareUTF16OverrideComponent(replSource.port, replParsed.port,
+ utf8Buffer, &parsed->port);
+ success &= PrepareUTF16OverrideComponent(replSource.path, replParsed.path,
+ utf8Buffer, &parsed->path);
+ success &= PrepareUTF16OverrideComponent(replSource.query, replParsed.query,
+ utf8Buffer, &parsed->query);
+ success &= PrepareUTF16OverrideComponent(replSource.ref, replParsed.fragment,
+ utf8Buffer, &parsed->fragment);
+
+ // PrepareUTF16OverrideComponent will not have set the data pointer since the
+ // buffer could be resized, invalidating the pointers. We set the data
+ // pointers for affected components now that the buffer is finalized.
+ if (replSource.scheme)
+ source->scheme = utf8Buffer.data();
+ if (replSource.username)
+ source->username = utf8Buffer.data();
+ if (replSource.password)
+ source->password = utf8Buffer.data();
+ if (replSource.host)
+ source->host = utf8Buffer.data();
+ if (replSource.port)
+ source->port = utf8Buffer.data();
+ if (replSource.path)
+ source->path = utf8Buffer.data();
+ if (replSource.query)
+ source->query = utf8Buffer.data();
+ if (replSource.ref)
+ source->ref = utf8Buffer.data();
+
+ return success;
+}
+
+#if !OS(WINDOWS)
+int _itoa_s(int value, char* buffer, size_t sizeInChars, int radix)
+{
+ int written;
+ if (radix == 10)
+ written = snprintf(buffer, sizeInChars, "%d", value);
+ else if (radix == 16)
+ written = snprintf(buffer, sizeInChars, "%x", value);
+ else
+ return EINVAL;
+
+ if (static_cast<size_t>(written) >= sizeInChars) {
+ // Output was truncated, or written was negative.
+ return EINVAL;
+ }
+ return 0;
+}
+
+int _itow_s(int value, UChar* buffer, size_t sizeInChars, int radix)
+{
+ if (radix != 10)
+ return EINVAL;
+
+ // No more than 12 characters will be required for a 32-bit integer.
+ // Add an extra byte for the terminating null.
+ char temp[13];
+ int written = snprintf(temp, sizeof(temp), "%d", value);
+ if (static_cast<size_t>(written) >= sizeInChars) {
+ // Output was truncated, or written was negative.
+ return EINVAL;
+ }
+
+ for (int i = 0; i < written; ++i)
+ buffer[i] = static_cast<UChar>(temp[i]);
+ buffer[written] = '\0';
+ return 0;
+}
+
+#endif // !OS(WINDOWS)
+
+} // namespace URLCanonicalizer
+
+} // namespace WTF
+
+#endif // USE(WTFURL)
diff --git a/Source/WTF/wtf/url/src/URLCanonInternal.h b/Source/WTF/wtf/url/src/URLCanonInternal.h
new file mode 100644
index 000000000..9b2970632
--- /dev/null
+++ b/Source/WTF/wtf/url/src/URLCanonInternal.h
@@ -0,0 +1,394 @@
+/*
+ * Copyright 2011 Google Inc. All rights reserved.
+ * Copyright 2012 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:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * 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.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND 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 THE COPYRIGHT
+ * OWNER 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.
+ */
+
+// This file is intended to be included in another C++ file where the character
+// types are defined. This allows us to write mostly generic code, but not have
+// templace bloat because everything is inlined when anybody calls any of our
+// functions.
+
+#ifndef URLCanonInternal_h
+#define URLCanonInternal_h
+
+#include "URLCanon.h"
+#include "URLCharacterTypes.h"
+#include <stdlib.h>
+#include <wtf/HexNumber.h>
+
+#if USE(WTFURL)
+
+namespace WTF {
+
+namespace URLCanonicalizer {
+
+// Appends the given string to the output, escaping characters that do not
+// match the given |type| in SharedCharTypes.
+void appendStringOfType(const char* source, int length, URLCharacterTypes::CharacterTypes urlComponentType, URLBuffer<char>& output);
+void appendStringOfType(const UChar* source, int length, URLCharacterTypes::CharacterTypes urlComponentType, URLBuffer<char>& output);
+
+// This lookup table allows fast conversion between ASCII hex letters and their
+// corresponding numerical value. The 8-bit range is divided up into 8
+// regions of 0x20 characters each. Each of the three character types (numbers,
+// uppercase, lowercase) falls into different regions of this range. The table
+// contains the amount to subtract from characters in that range to get at
+// the corresponding numerical value.
+//
+// See HexDigitToValue for the lookup.
+extern const char kCharToHexLookup[8];
+
+// Assumes the input is a valid hex digit! Call isHexChar before using this.
+inline unsigned char hexCharToValue(unsigned char character)
+{
+ return character - kCharToHexLookup[character / 0x20];
+}
+
+// Indicates if the given character is a dot or dot equivalent, returning the
+// number of characters taken by it. This will be one for a literal dot, 3 for
+// an escaped dot. If the character is not a dot, this will return 0.
+template<typename CharacterType>
+inline int isDot(const CharacterType* spec, int offset, int end)
+{
+ if (spec[offset] == '.')
+ return 1;
+
+ if (spec[offset] == '%' && offset + 3 <= end && spec[offset + 1] == '2' && (spec[offset + 2] == 'e' || spec[offset + 2] == 'E')) {
+ // Found "%2e"
+ return 3;
+ }
+ return 0;
+}
+
+// Returns the canonicalized version of the input character according to scheme
+// rules. This is implemented alongside the scheme canonicalizer, and is
+// required for relative URL resolving to test for scheme equality.
+//
+// Returns 0 if the input character is not a valid scheme character.
+char canonicalSchemeChar(UChar);
+
+// Write a single character, escaped, to the output. This always escapes: it
+// does no checking that thee character requires escaping.
+// Escaping makes sense only 8 bit chars, so code works in all cases of
+// input parameters (8/16bit).
+template<typename InChar, typename OutChar>
+inline void appendURLEscapedCharacter(InChar character, URLBuffer<OutChar>& buffer)
+{
+ buffer.append('%');
+ buffer.append(WTF::Internal::upperHexDigits[character >> 4]);
+ buffer.append(WTF::Internal::upperHexDigits[character & 0xf]);
+}
+
+// The character we'll substitute for undecodable or invalid characters.
+extern const UChar kUnicodeReplacementCharacter;
+
+// UTF-8 functions ------------------------------------------------------------
+
+// Reads one character in UTF-8 starting at |*begin| in |str| and places
+// the decoded value into |*codePoint|. If the character is valid, we will
+// return true. If invalid, we'll return false and put the
+// kUnicodeReplacementCharacter into |*codePoint|.
+//
+// |*begin| will be updated to point to the last character consumed so it
+// can be incremented in a loop and will be ready for the next character.
+// (for a single-byte ASCII character, it will not be changed).
+//
+// Implementation is in URLCanonicalizer_icu.cc.
+bool readUTFChar(const char* str, int* begin, int length, unsigned* codePointOut);
+
+// Generic To-UTF-8 converter. This will call the given append method for each
+// character that should be appended, with the given output method. Wrappers
+// are provided below for escaped and non-escaped versions of this.
+//
+// The charactervalue must have already been checked that it's a valid Unicode
+// character.
+template<class Output, void appendFunction(unsigned char, Output&)>
+inline void doAppendUTF8(unsigned charactervalue, Output& output)
+{
+ if (charactervalue <= 0x7f) {
+ appendFunction(static_cast<unsigned char>(charactervalue), output);
+ } else if (charactervalue <= 0x7ff) {
+ // 110xxxxx 10xxxxxx
+ appendFunction(static_cast<unsigned char>(0xC0 | (charactervalue >> 6)), output);
+ appendFunction(static_cast<unsigned char>(0x80 | (charactervalue & 0x3f)), output);
+ } else if (charactervalue <= 0xffff) {
+ // 1110xxxx 10xxxxxx 10xxxxxx
+ appendFunction(static_cast<unsigned char>(0xe0 | (charactervalue >> 12)), output);
+ appendFunction(static_cast<unsigned char>(0x80 | ((charactervalue >> 6) & 0x3f)), output);
+ appendFunction(static_cast<unsigned char>(0x80 | (charactervalue & 0x3f)), output);
+ } else if (charactervalue <= 0x10FFFF) { // Max unicode code point.
+ // 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
+ appendFunction(static_cast<unsigned char>(0xf0 | (charactervalue >> 18)), output);
+ appendFunction(static_cast<unsigned char>(0x80 | ((charactervalue >> 12) & 0x3f)), output);
+ appendFunction(static_cast<unsigned char>(0x80 | ((charactervalue >> 6) & 0x3f)), output);
+ appendFunction(static_cast<unsigned char>(0x80 | (charactervalue & 0x3f)), output);
+ } else {
+ // Invalid UTF-8 character (>20 bits).
+ ASSERT_NOT_REACHED();
+ }
+}
+
+// Helper used by AppendUTF8Value below. We use an unsigned parameter so there
+// are no funny sign problems with the input, but then have to convert it to
+// a regular char for appending.
+inline void AppendCharToOutput(unsigned char character, URLBuffer<char>& output)
+{
+ output.append(static_cast<char>(character));
+}
+
+// Writes the given character to the output as UTF-8. This does NO checking
+// of the validity of the unicode characters; the caller should ensure that
+// the value it is appending is valid to append.
+inline void AppendUTF8Value(unsigned charactervalue, URLBuffer<char>& output)
+{
+ doAppendUTF8<URLBuffer<char>, AppendCharToOutput>(charactervalue, output);
+}
+
+// Writes the given character to the output as UTF-8, escaping ALL
+// characters (even when they are ASCII). This does NO checking of the
+// validity of the unicode characters; the caller should ensure that the value
+// it is appending is valid to append.
+inline void AppendUTF8EscapedValue(unsigned charactervalue, URLBuffer<char>& output)
+{
+ doAppendUTF8<URLBuffer<char>, appendURLEscapedCharacter>(charactervalue, output);
+}
+
+// UTF-16 functions -----------------------------------------------------------
+
+// Reads one character in UTF-16 starting at |*begin| in |str| and places
+// the decoded value into |*codePoint|. If the character is valid, we will
+// return true. If invalid, we'll return false and put the
+// kUnicodeReplacementCharacter into |*codePoint|.
+//
+// |*begin| will be updated to point to the last character consumed so it
+// can be incremented in a loop and will be ready for the next character.
+// (for a single-16-bit-word character, it will not be changed).
+//
+// Implementation is in URLCanonicalizer_icu.cc.
+bool readUTFChar(const UChar* str, int* begin, int length, unsigned* codePoint);
+
+// Equivalent to U16_APPEND_UNSAFE in ICU but uses our output method.
+inline void AppendUTF16Value(unsigned codePoint, URLBuffer<UChar>& output)
+{
+ if (codePoint > 0xffff) {
+ output.append(static_cast<UChar>((codePoint >> 10) + 0xd7c0));
+ output.append(static_cast<UChar>((codePoint & 0x3ff) | 0xdc00));
+ } else
+ output.append(static_cast<UChar>(codePoint));
+}
+
+// Escaping functions ---------------------------------------------------------
+
+// Writes the given character to the output as UTF-8, escaped. Call this
+// function only when the input is wide. Returns true on success. Failure
+// means there was some problem with the encoding, we'll still try to
+// update the |*begin| pointer and add a placeholder character to the
+// output so processing can continue.
+//
+// We will append the character starting at ch[begin] with the buffer ch
+// being |length|. |*begin| will be updated to point to the last character
+// consumed (we may consume more than one for UTF-16) so that if called in
+// a loop, incrementing the pointer will move to the next character.
+//
+// Every single output character will be escaped. This means that if you
+// give it an ASCII character as input, it will be escaped. Some code uses
+// this when it knows that a character is invalid according to its rules
+// for validity. If you don't want escaping for ASCII characters, you will
+// have to filter them out prior to calling this function.
+//
+// Assumes that ch[begin] is within range in the array, but does not assume
+// that any following characters are.
+inline bool AppendUTF8EscapedChar(const UChar* str, int* begin, int length, URLBuffer<char>& output)
+{
+ // UTF-16 input. ReadUChar will handle invalid characters for us and give
+ // us the kUnicodeReplacementCharacter, so we don't have to do special
+ // checking after failure, just pass through the failure to the caller.
+ unsigned charactervalue;
+ bool success = readUTFChar(str, begin, length, &charactervalue);
+ AppendUTF8EscapedValue(charactervalue, output);
+ return success;
+}
+
+// Handles UTF-8 input. See the wide version above for usage.
+inline bool AppendUTF8EscapedChar(const char* str, int* begin, int length, URLBuffer<char>& output)
+{
+ // ReadUTF8Char will handle invalid characters for us and give us the
+ // kUnicodeReplacementCharacter, so we don't have to do special checking
+ // after failure, just pass through the failure to the caller.
+ unsigned ch;
+ bool success = readUTFChar(str, begin, length, &ch);
+ AppendUTF8EscapedValue(ch, output);
+ return success;
+}
+
+// Given a '%' character at |*begin| in the string |spec|, this will decode
+// the escaped value and put it into |*unescapedValue| on success (returns
+// true). On failure, this will return false, and will not write into
+// |*unescapedValue|.
+//
+// |*begin| will be updated to point to the last character of the escape
+// sequence so that when called with the index of a for loop, the next time
+// through it will point to the next character to be considered. On failure,
+// |*begin| will be unchanged.
+inline bool Is8BitChar(char)
+{
+ return true; // this case is specialized to avoid a warning
+}
+inline bool Is8BitChar(UChar c)
+{
+ return c <= 255;
+}
+
+template<typename CHAR>
+inline bool DecodeEscaped(const CHAR* spec, int* begin, int end, unsigned char* unescapedValue)
+{
+ if (*begin + 3 > end || !Is8BitChar(spec[*begin + 1]) || !Is8BitChar(spec[*begin + 2])) {
+ // Invalid escape sequence because there's not enough room, or the
+ // digits are not ASCII.
+ return false;
+ }
+
+ unsigned char first = static_cast<unsigned char>(spec[*begin + 1]);
+ unsigned char second = static_cast<unsigned char>(spec[*begin + 2]);
+ if (!URLCharacterTypes::isHexChar(first) || !URLCharacterTypes::isHexChar(second)) {
+ // Invalid hex digits, fail.
+ return false;
+ }
+
+ // Valid escape sequence.
+ *unescapedValue = (hexCharToValue(first) << 4) + hexCharToValue(second);
+ *begin += 2;
+ return true;
+}
+
+// Appends the given substring to the output, escaping "some" characters that
+// it feels may not be safe. It assumes the input values are all contained in
+// 8-bit although it allows any type.
+//
+// This is used in error cases to append invalid output so that it looks
+// approximately correct. Non-error cases should not call this function since
+// the escaping rules are not guaranteed!
+void AppendInvalidNarrowString(const char* spec, int begin, int end, URLBuffer<char>& output);
+void AppendInvalidNarrowString(const UChar* spec, int begin, int end, URLBuffer<char>& output);
+
+// Misc canonicalization helpers ----------------------------------------------
+
+// Converts between UTF-8 and UTF-16, returning true on successful conversion.
+// The output will be appended to the given canonicalizer output (so make sure
+// it's empty if you want to replace).
+//
+// On invalid input, this will still write as much output as possible,
+// replacing the invalid characters with the "invalid character". It will
+// return false in the failure case, and the caller should not continue as
+// normal.
+bool ConvertUTF16ToUTF8(const UChar* input, int inputLength, URLBuffer<char>& output);
+bool ConvertUTF8ToUTF16(const char* input, int inputLength, URLBuffer<UChar>& output);
+
+// Converts from UTF-16 to 8-bit using the character set converter. If the
+// converter is null, this will use UTF-8.
+void ConvertUTF16ToQueryEncoding(const UChar* input, const URLComponent& query, URLQueryCharsetConverter*, URLBuffer<char>& output);
+
+// Applies the replacements to the given component source. The component source
+// should be pre-initialized to the "old" base. That is, all pointers will
+// point to the spec of the old URL, and all of the Parsed components will
+// be indices into that string.
+//
+// The pointers and components in the |source| for all non-null strings in the
+// |repl| (replacements) will be updated to reference those strings.
+// Canonicalizing with the new |source| and |parsed| can then combine URL
+// components from many different strings.
+void SetupOverrideComponents(const char* base,
+ const Replacements<char>&,
+ URLComponentSource<char>*,
+ URLSegments* parsed);
+
+// Like the above 8-bit version, except that it additionally converts the
+// UTF-16 input to UTF-8 before doing the overrides.
+//
+// The given utf8Buffer is used to store the converted components. They will
+// be appended one after another, with the parsed structure identifying the
+// appropriate substrings. This buffer is a parameter because the source has
+// no storage, so the buffer must have the same lifetime as the source
+// parameter owned by the caller.
+//
+// THE CALLER MUST NOT ADD TO THE |utf8Buffer| AFTER THIS CALL. Members of
+// |source| will point into this buffer, which could be invalidated if
+// additional data is added and the CanonOutput resizes its buffer.
+//
+// Returns true on success. Fales means that the input was not valid UTF-16,
+// although we will have still done the override with "invalid characters" in
+// place of errors.
+bool SetupUTF16OverrideComponents(const char* base,
+ const Replacements<UChar>&,
+ URLBuffer<char>& utf8Buffer,
+ URLComponentSource<char>*,
+ URLSegments* parsed);
+
+// Implemented in URLCanonicalizer_path.cc, these are required by the relative URL
+// resolver as well, so we declare them here.
+bool CanonicalizePartialPath(const char* spec,
+ const URLComponent& path,
+ int pathBeginInOutput,
+ URLBuffer<char>& output);
+bool CanonicalizePartialPath(const UChar* spec,
+ const URLComponent& path,
+ int pathBeginInOutput,
+ URLBuffer<char>& output);
+
+#if !OS(WINDOWS)
+// Implementations of Windows' int-to-string conversions
+int _itoa_s(int value, char* buffer, size_t sizeInChars, int radix);
+int _itow_s(int value, UChar* buffer, size_t sizeInChars, int radix);
+
+// Secure template overloads for these functions
+template<size_t N>
+inline int _itoa_s(int value, char (&buffer)[N], int radix)
+{
+ return _itoa_s(value, buffer, N, radix);
+}
+
+template<size_t N>
+inline int _itow_s(int value, UChar (&buffer)[N], int radix)
+{
+ return _itow_s(value, buffer, N, radix);
+}
+
+// _strtoui64 and strtoull behave the same
+inline unsigned long long _strtoui64(const char* nptr, char** endptr, int base)
+{
+ return strtoull(nptr, endptr, base);
+}
+#endif // OS(WINDOWS)
+
+} // namespace URLCanonicalizer
+
+} // namespace WTF
+
+#endif // USE(WTFURL)
+
+#endif // URLCanonInternal_h
diff --git a/Source/WTF/wtf/url/src/URLCanonMailto.cpp b/Source/WTF/wtf/url/src/URLCanonMailto.cpp
new file mode 100644
index 000000000..bdb353845
--- /dev/null
+++ b/Source/WTF/wtf/url/src/URLCanonMailto.cpp
@@ -0,0 +1,134 @@
+/*
+ * Copyright 2008 Google Inc. All rights reserved.
+ * Copyright 2012 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:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * 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.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND 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 THE COPYRIGHT
+ * OWNER 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.
+ */
+
+// Functions for canonicalizing "mailto:" URLs.
+
+#include "config.h"
+#include "URLCanon.h"
+
+#include "RawURLBuffer.h"
+#include "URLCanonInternal.h"
+#include "URLFile.h"
+#include "URLParseInternal.h"
+
+#if USE(WTFURL)
+
+namespace WTF {
+
+namespace URLCanonicalizer {
+
+namespace {
+
+
+template<typename CharacterType, typename UCHAR>
+bool doCanonicalizeMailtoURL(const URLComponentSource<CharacterType>& source, const URLSegments& parsed, URLBuffer<char>& output, URLSegments& outputParsed)
+{
+ // mailto: only uses {scheme, path, query} -- clear the rest.
+ outputParsed.username = URLComponent();
+ outputParsed.password = URLComponent();
+ outputParsed.host = URLComponent();
+ outputParsed.port = URLComponent();
+ outputParsed.fragment = URLComponent();
+
+ // Scheme (known, so we don't bother running it through the more
+ // complicated scheme canonicalizer).
+ outputParsed.scheme.setBegin(output.length());
+ output.append("mailto:", 7);
+ outputParsed.scheme.setLength(6);
+
+ bool success = true;
+
+ // Path
+ if (parsed.path.isValid()) {
+ outputParsed.path.setBegin(output.length());
+
+ // Copy the path using path URL's more lax escaping rules.
+ // We convert to UTF-8 and escape non-ASCII, but leave all
+ // ASCII characters alone.
+ int end = parsed.path.end();
+ for (int i = parsed.path.begin(); i < end; ++i) {
+ UCHAR uch = static_cast<UCHAR>(source.path[i]);
+ if (uch < 0x20 || uch >= 0x80)
+ success &= AppendUTF8EscapedChar(source.path, &i, end, output);
+ else
+ output.append(static_cast<char>(uch));
+ }
+
+ outputParsed.path.setLength(output.length() - outputParsed.path.begin());
+ } else {
+ // No path at all
+ outputParsed.path.reset();
+ }
+
+ // Query -- always use the default utf8 charset converter.
+ CanonicalizeQuery(source.query, parsed.query, 0, output, &outputParsed.query);
+
+ return success;
+}
+
+} // namespace
+
+bool canonicalizeMailtoURL(const char* spec, const URLSegments& parsed, URLBuffer<char>& output, URLSegments& outputParsed)
+{
+ return doCanonicalizeMailtoURL<char, unsigned char>(URLComponentSource<char>(spec), parsed, output, outputParsed);
+}
+
+bool canonicalizeMailtoURL(const UChar* spec, const URLSegments& parsed, URLBuffer<char>& output, URLSegments& outputParsed)
+{
+ return doCanonicalizeMailtoURL<UChar, UChar>(URLComponentSource<UChar>(spec), parsed, output, outputParsed);
+}
+
+bool replaceMailtoURL(const char* base, const URLSegments& baseParsed,
+ const Replacements<char>& replacements,
+ URLBuffer<char>& output, URLSegments& outputParsed)
+{
+ URLComponentSource<char> source(base);
+ URLSegments parsed(baseParsed);
+ SetupOverrideComponents(base, replacements, &source, &parsed);
+ return doCanonicalizeMailtoURL<char, unsigned char>(source, parsed, output, outputParsed);
+}
+
+bool replaceMailtoURL(const char* base, const URLSegments& baseParsed,
+ const Replacements<UChar>& replacements,
+ URLBuffer<char>& output, URLSegments& outputParsed)
+{
+ RawURLBuffer<char> utf8;
+ URLComponentSource<char> source(base);
+ URLSegments parsed(baseParsed);
+ SetupUTF16OverrideComponents(base, replacements, utf8, &source, &parsed);
+ return doCanonicalizeMailtoURL<char, unsigned char>(source, parsed, output, outputParsed);
+}
+
+} // namespace URLCanonicalizer
+
+} // namespace WTF
+
+#endif // USE(WTFURL)
diff --git a/Source/WTF/wtf/url/src/URLCanonPath.cpp b/Source/WTF/wtf/url/src/URLCanonPath.cpp
new file mode 100644
index 000000000..9bc443fd7
--- /dev/null
+++ b/Source/WTF/wtf/url/src/URLCanonPath.cpp
@@ -0,0 +1,372 @@
+/*
+ * Copyright 2007 Google Inc. All rights reserved.
+ * Copyright 2012 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:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * 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.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND 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 THE COPYRIGHT
+ * OWNER 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.
+ */
+
+// Canonicalization functions for the paths of URLs.
+
+#include "config.h"
+#include "URLCanon.h"
+
+#include "URLCanonInternal.h"
+#include "URLParseInternal.h"
+
+#if USE(WTFURL)
+
+namespace WTF {
+
+namespace URLCanonicalizer {
+
+namespace {
+
+enum CharacterFlags {
+ // Pass through unchanged, whether escaped or unescaped. This doesn't
+ // actually set anything so you can't OR it to check, it's just to make the
+ // table below more clear when neither ESCAPE or UNESCAPE is set.
+ PASS = 0,
+
+ // This character requires special handling in doPartialPath. Doing this test
+ // first allows us to filter out the common cases of regular characters that
+ // can be directly copied.
+ SPECIAL = 1,
+
+ // This character must be escaped in the canonical output. Note that all
+ // escaped chars also have the "special" bit set so that the code that looks
+ // for this is triggered. Not valid with PASS or ESCAPE
+ ESCAPE_BIT = 2,
+ ESCAPE = ESCAPE_BIT | SPECIAL,
+
+ // This character must be unescaped in canonical output. Not valid with
+ // ESCAPE or PASS. We DON'T set the SPECIAL flag since if we encounter these
+ // characters unescaped, they should just be copied.
+ UNESCAPE = 4,
+
+ // This character is disallowed in URLs. Note that the "special" bit is also
+ // set to trigger handling.
+ INVALID_BIT = 8,
+ INVALID = INVALID_BIT | SPECIAL,
+};
+
+// This table contains one of the above flag values. Note some flags are more
+// than one bits because they also turn on the "special" flag. Special is the
+// only flag that may be combined with others.
+//
+// This table is designed to match exactly what IE does with the characters.
+//
+// Dot is even more special, and the escaped version is handled specially by
+// isDot. Therefore, we don't need the "escape" flag, and even the "unescape"
+// bit is never handled (we just need the "special") bit.
+const unsigned char kPathCharLookup[0x100] = {
+// null control chars...
+ INVALID, ESCAPE, ESCAPE, ESCAPE, ESCAPE, ESCAPE, ESCAPE, ESCAPE, ESCAPE, ESCAPE, ESCAPE, ESCAPE, ESCAPE, ESCAPE, ESCAPE, ESCAPE,
+// control chars...
+ ESCAPE, ESCAPE, ESCAPE, ESCAPE, ESCAPE, ESCAPE, ESCAPE, ESCAPE, ESCAPE, ESCAPE, ESCAPE, ESCAPE, ESCAPE, ESCAPE, ESCAPE, ESCAPE,
+// ' ' ! " # $ % & ' ( ) * + , - . /
+ ESCAPE, PASS, ESCAPE, ESCAPE, PASS, ESCAPE, PASS, PASS, PASS, PASS, PASS, PASS, PASS, UNESCAPE, SPECIAL, PASS,
+// 0 1 2 3 4 5 6 7 8 9 : ; < = > ?
+ UNESCAPE, UNESCAPE, UNESCAPE, UNESCAPE, UNESCAPE, UNESCAPE, UNESCAPE, UNESCAPE, UNESCAPE, UNESCAPE, PASS, PASS, ESCAPE, PASS, ESCAPE, ESCAPE,
+// @ A B C D E F G H I J K L M N O
+ PASS, UNESCAPE, UNESCAPE, UNESCAPE, UNESCAPE, UNESCAPE, UNESCAPE, UNESCAPE, UNESCAPE, UNESCAPE, UNESCAPE, UNESCAPE, UNESCAPE, UNESCAPE, UNESCAPE, UNESCAPE,
+// P Q R S T U V W X Y Z [ \ ] ^ _
+ UNESCAPE, UNESCAPE, UNESCAPE, UNESCAPE, UNESCAPE, UNESCAPE, UNESCAPE, UNESCAPE, UNESCAPE, UNESCAPE, UNESCAPE, PASS, ESCAPE, PASS, ESCAPE, UNESCAPE,
+// ` a b c d e f g h i j k l m n o
+ ESCAPE, UNESCAPE, UNESCAPE, UNESCAPE, UNESCAPE, UNESCAPE, UNESCAPE, UNESCAPE, UNESCAPE, UNESCAPE, UNESCAPE, UNESCAPE, UNESCAPE, UNESCAPE, UNESCAPE, UNESCAPE,
+// p q r s t u v w x y z { | } ~ <NBSP>
+ UNESCAPE, UNESCAPE, UNESCAPE, UNESCAPE, UNESCAPE, UNESCAPE, UNESCAPE, UNESCAPE, UNESCAPE, UNESCAPE, UNESCAPE, ESCAPE, ESCAPE, ESCAPE, UNESCAPE, ESCAPE,
+// ...all the high-bit characters are escaped
+ ESCAPE, ESCAPE, ESCAPE, ESCAPE, ESCAPE, ESCAPE, ESCAPE, ESCAPE, ESCAPE, ESCAPE, ESCAPE, ESCAPE, ESCAPE, ESCAPE, ESCAPE, ESCAPE,
+ ESCAPE, ESCAPE, ESCAPE, ESCAPE, ESCAPE, ESCAPE, ESCAPE, ESCAPE, ESCAPE, ESCAPE, ESCAPE, ESCAPE, ESCAPE, ESCAPE, ESCAPE, ESCAPE,
+ ESCAPE, ESCAPE, ESCAPE, ESCAPE, ESCAPE, ESCAPE, ESCAPE, ESCAPE, ESCAPE, ESCAPE, ESCAPE, ESCAPE, ESCAPE, ESCAPE, ESCAPE, ESCAPE,
+ ESCAPE, ESCAPE, ESCAPE, ESCAPE, ESCAPE, ESCAPE, ESCAPE, ESCAPE, ESCAPE, ESCAPE, ESCAPE, ESCAPE, ESCAPE, ESCAPE, ESCAPE, ESCAPE,
+ ESCAPE, ESCAPE, ESCAPE, ESCAPE, ESCAPE, ESCAPE, ESCAPE, ESCAPE, ESCAPE, ESCAPE, ESCAPE, ESCAPE, ESCAPE, ESCAPE, ESCAPE, ESCAPE,
+ ESCAPE, ESCAPE, ESCAPE, ESCAPE, ESCAPE, ESCAPE, ESCAPE, ESCAPE, ESCAPE, ESCAPE, ESCAPE, ESCAPE, ESCAPE, ESCAPE, ESCAPE, ESCAPE,
+ ESCAPE, ESCAPE, ESCAPE, ESCAPE, ESCAPE, ESCAPE, ESCAPE, ESCAPE, ESCAPE, ESCAPE, ESCAPE, ESCAPE, ESCAPE, ESCAPE, ESCAPE, ESCAPE,
+ ESCAPE, ESCAPE, ESCAPE, ESCAPE, ESCAPE, ESCAPE, ESCAPE, ESCAPE, ESCAPE, ESCAPE, ESCAPE, ESCAPE, ESCAPE, ESCAPE, ESCAPE, ESCAPE};
+
+enum DotDisposition {
+ // The given dot is just part of a filename and is not special.
+ NOT_A_DIRECTORY,
+
+ // The given dot is the current directory.
+ DIRECTORY_CUR,
+
+ // The given dot is the first of a double dot that should take us up one.
+ DIRECTORY_UP
+};
+
+// When the path resolver finds a dot, this function is called with the
+// character following that dot to see what it is. The return value
+// indicates what type this dot is (see above). This code handles the case
+// where the dot is at the end of the input.
+//
+// |*consumedLength| will contain the number of characters in the input that
+// express what we found.
+//
+// If the input is "../foo", |afterDot| = 1, |end| = 6, and
+// at the end, |*consumedLength| = 2 for the "./" this function consumed. The
+// original dot length should be handled by the caller.
+template<typename CHAR>
+DotDisposition ClassifyAfterDot(const CHAR* spec, int afterDot, int end, int* consumedLength)
+{
+ if (afterDot == end) {
+ // Single dot at the end.
+ *consumedLength = 0;
+ return DIRECTORY_CUR;
+ }
+ if (URLParser::isURLSlash(spec[afterDot])) {
+ // Single dot followed by a slash.
+ *consumedLength = 1; // Consume the slash
+ return DIRECTORY_CUR;
+ }
+
+ int secondDotLength = isDot(spec, afterDot, end);
+ if (secondDotLength) {
+ int afterSecondDot = afterDot + secondDotLength;
+ if (afterSecondDot == end) {
+ // Double dot at the end.
+ *consumedLength = secondDotLength;
+ return DIRECTORY_UP;
+ }
+ if (URLParser::isURLSlash(spec[afterSecondDot])) {
+ // Double dot followed by a slash.
+ *consumedLength = secondDotLength + 1;
+ return DIRECTORY_UP;
+ }
+ }
+
+ // The dots are followed by something else, not a directory.
+ *consumedLength = 0;
+ return NOT_A_DIRECTORY;
+}
+
+// Rewinds the output to the previous slash. It is assumed that the output
+// ends with a slash and this doesn't count (we call this when we are
+// appending directory paths, so the previous path component has and ending
+// slash).
+//
+// This will stop at the first slash (assumed to be at position
+// |pathBeginInOutput| and not go any higher than that. Some web pages
+// do ".." too many times, so we need to handle that brokenness.
+//
+// It searches for a literal slash rather than including a backslash as well
+// because it is run only on the canonical output.
+//
+// The output is guaranteed to end in a slash when this function completes.
+void BackUpToPreviousSlash(int pathBeginInOutput, URLBuffer<char>& output)
+{
+ ASSERT(output.length() > 0);
+
+ int i = output.length() - 1;
+ ASSERT(output.at(i) == '/');
+ if (i == pathBeginInOutput)
+ return; // We're at the first slash, nothing to do.
+
+ // Now back up (skipping the trailing slash) until we find another slash.
+ i--;
+ while (output.at(i) != '/' && i > pathBeginInOutput)
+ i--;
+
+ // Now shrink the output to just include that last slash we found.
+ output.setLength(i + 1);
+}
+
+// Appends the given path to the output. It assumes that if the input path
+// starts with a slash, it should be copied to the output. If no path has
+// already been appended to the output (the case when not resolving
+// relative URLs), the path should begin with a slash.
+//
+// If there are already path components (this mode is used when appending
+// relative paths for resolving), it assumes that the output already has
+// a trailing slash and that if the input begins with a slash, it should be
+// copied to the output.
+//
+// We do not collapse multiple slashes in a row to a single slash. It seems
+// no web browsers do this, and we don't want incompababilities, even though
+// it would be correct for most systems.
+template<typename CharacterType, typename UCHAR>
+bool doPartialPath(const CharacterType* spec, const URLComponent& path, int pathBeginInOutput, URLBuffer<char>& output)
+{
+ int end = path.end();
+
+ bool success = true;
+ for (int i = path.begin(); i < end; ++i) {
+ UCHAR uch = static_cast<UCHAR>(spec[i]);
+ if (sizeof(CharacterType) > sizeof(char) && uch >= 0x80) {
+ // We only need to test wide input for having non-ASCII characters. For
+ // narrow input, we'll always just use the lookup table. We don't try to
+ // do anything tricky with decoding/validating UTF-8. This function will
+ // read one or two UTF-16 characters and append the output as UTF-8. This
+ // call will be removed in 8-bit mode.
+ success &= AppendUTF8EscapedChar(spec, &i, end, output);
+ } else {
+ // Normal ASCII character or 8-bit input, use the lookup table.
+ unsigned char outCh = static_cast<unsigned char>(uch);
+ unsigned char flags = kPathCharLookup[outCh];
+ if (flags & SPECIAL) {
+ // Needs special handling of some sort.
+ int dotlen;
+ if ((dotlen = isDot(spec, i, end)) > 0) {
+ // See if this dot was preceeded by a slash in the output. We
+ // assume that when canonicalizing paths, they will always
+ // start with a slash and not a dot, so we don't have to
+ // bounds check the output.
+ //
+ // Note that we check this in the case of dots so we don't have to
+ // special case slashes. Since slashes are much more common than
+ // dots, this actually increases performance measurably (though
+ // slightly).
+ ASSERT(output.length() > pathBeginInOutput);
+ if (output.length() > pathBeginInOutput && output.at(output.length() - 1) == '/') {
+ // Slash followed by a dot, check to see if this is means relative
+ int consumedLength;
+ switch (ClassifyAfterDot<CharacterType>(spec, i + dotlen, end, &consumedLength)) {
+ case NOT_A_DIRECTORY:
+ // Copy the dot to the output, it means nothing special.
+ output.append('.');
+ i += dotlen - 1;
+ break;
+ case DIRECTORY_CUR: // Current directory, just skip the input.
+ i += dotlen + consumedLength - 1;
+ break;
+ case DIRECTORY_UP:
+ BackUpToPreviousSlash(pathBeginInOutput, output);
+ i += dotlen + consumedLength - 1;
+ break;
+ }
+ } else {
+ // This dot is not preceeded by a slash, it is just part of some
+ // file name.
+ output.append('.');
+ i += dotlen - 1;
+ }
+ } else if (outCh == '\\') {
+ // Convert backslashes to forward slashes
+ output.append('/');
+ } else if (outCh == '%') {
+ // Handle escape sequences.
+ unsigned char unescapedValue;
+ if (DecodeEscaped(spec, &i, end, &unescapedValue)) {
+ // Valid escape sequence, see if we keep, reject, or unescape it.
+ char unescapedFlags = kPathCharLookup[unescapedValue];
+
+ if (unescapedFlags & UNESCAPE) {
+ // This escaped value shouldn't be escaped, copy it.
+ output.append(unescapedValue);
+ } else if (unescapedFlags & INVALID_BIT) {
+ // Invalid escaped character, copy it and remember the error.
+ output.append('%');
+ output.append(static_cast<char>(spec[i - 1]));
+ output.append(static_cast<char>(spec[i]));
+ success = false;
+ } else {
+ // Valid escaped character but we should keep it escaped. We
+ // don't want to change the case of any hex letters in case
+ // the server is sensitive to that, so we just copy the two
+ // characters without checking (DecodeEscape will have advanced
+ // to the last character of the pair).
+ output.append('%');
+ output.append(static_cast<char>(spec[i - 1]));
+ output.append(static_cast<char>(spec[i]));
+ }
+ } else {
+ // Invalid escape sequence. IE7 rejects any URLs with such
+ // sequences, while Firefox, IE6, and Safari all pass it through
+ // unchanged. We are more permissive unlike IE7. I don't think this
+ // can cause significant problems, if it does, we should change
+ // to be more like IE7.
+ output.append('%');
+ }
+
+ } else if (flags & INVALID_BIT) {
+ // For NULLs, etc. fail.
+ appendURLEscapedCharacter(outCh, output);
+ success = false;
+
+ } else if (flags & ESCAPE_BIT) {
+ // This character should be escaped.
+ appendURLEscapedCharacter(outCh, output);
+ }
+ } else {
+ // Nothing special about this character, just append it.
+ output.append(outCh);
+ }
+ }
+ }
+ return success;
+}
+
+template<typename CharacterType, typename UCHAR>
+bool doPath(const CharacterType* spec, const URLComponent& path, URLBuffer<char>& output, URLComponent& outputPath)
+{
+ bool success = true;
+ outputPath.setBegin(output.length());
+ if (path.length() > 0) {
+ // Write out an initial slash if the input has none. If we just parse a URL
+ // and then canonicalize it, it will of course have a slash already. This
+ // check is for the replacement and relative URL resolving cases of file
+ // URLs.
+ if (!URLParser::isURLSlash(spec[path.begin()]))
+ output.append('/');
+
+ success = doPartialPath<CharacterType, UCHAR>(spec, path, outputPath.begin(), output);
+ } else {
+ // No input, canonical path is a slash.
+ output.append('/');
+ }
+ outputPath.setLength(output.length() - outputPath.begin());
+ return success;
+}
+
+} // namespace
+
+bool CanonicalizePath(const char* spec, const URLComponent& path, URLBuffer<char>& output, URLComponent* outputPath)
+{
+ return doPath<char, unsigned char>(spec, path, output, *outputPath);
+}
+
+bool CanonicalizePath(const UChar* spec, const URLComponent& path, URLBuffer<char>& output, URLComponent* outputPath)
+{
+ return doPath<UChar, UChar>(spec, path, output, *outputPath);
+}
+
+bool CanonicalizePartialPath(const char* spec, const URLComponent& path, int pathBeginInOutput, URLBuffer<char>& output)
+{
+ return doPartialPath<char, unsigned char>(spec, path, pathBeginInOutput, output);
+}
+
+bool CanonicalizePartialPath(const UChar* spec, const URLComponent& path, int pathBeginInOutput, URLBuffer<char>& output)
+{
+ return doPartialPath<UChar, UChar>(spec, path, pathBeginInOutput, output);
+}
+
+} // namespace URLCanonicalizer
+
+} // namespace WTF
+
+#endif // USE(WTFURL)
diff --git a/Source/WTF/wtf/url/src/URLCanonPathurl.cpp b/Source/WTF/wtf/url/src/URLCanonPathurl.cpp
new file mode 100644
index 000000000..cea037c21
--- /dev/null
+++ b/Source/WTF/wtf/url/src/URLCanonPathurl.cpp
@@ -0,0 +1,122 @@
+/*
+ * Copyright 2007 Google Inc. All rights reserved.
+ * Copyright 2012 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:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * 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.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND 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 THE COPYRIGHT
+ * OWNER 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.
+ */
+
+// Functions for canonicalizing "path" URLs. Not to be confused with the path
+// of a URL, these are URLs that have no authority section, only a path. For
+// example, "javascript:" and "data:".
+
+#include "config.h"
+#include "URLCanon.h"
+
+#include "RawURLBuffer.h"
+#include "URLCanonInternal.h"
+
+#if USE(WTFURL)
+
+namespace WTF {
+
+namespace URLCanonicalizer {
+
+namespace {
+
+template<typename CharacterType, typename UCHAR>
+bool doCanonicalizePathURL(const URLComponentSource<CharacterType>& source, const URLSegments& parsed, URLBuffer<char>& output, URLSegments& ouputParsed)
+{
+ // Scheme: this will append the colon.
+ bool success = canonicalizeScheme(source.scheme, parsed.scheme, output, ouputParsed.scheme);
+
+ // We assume there's no authority for path URLs. Note that hosts should never
+ // have -1 length.
+ ouputParsed.username.reset();
+ ouputParsed.password.reset();
+ ouputParsed.host.reset();
+ ouputParsed.port.reset();
+
+ if (parsed.path.isValid()) {
+ // Copy the path using path URL's more lax escaping rules (think for
+ // javascript:). We convert to UTF-8 and escape non-ASCII, but leave all
+ // ASCII characters alone. This helps readability of JavaStript.
+ ouputParsed.path.setBegin(output.length());
+ int end = parsed.path.end();
+ for (int i = parsed.path.begin(); i < end; ++i) {
+ UCHAR uch = static_cast<UCHAR>(source.path[i]);
+ if (uch < 0x20 || uch >= 0x80)
+ success &= AppendUTF8EscapedChar(source.path, &i, end, output);
+ else
+ output.append(static_cast<char>(uch));
+ }
+ ouputParsed.path.setLength(output.length() - ouputParsed.path.begin());
+ } else {
+ // Empty path.
+ ouputParsed.path.reset();
+ }
+
+ // Assume there's no query or ref.
+ ouputParsed.query.reset();
+ ouputParsed.fragment.reset();
+
+ return success;
+}
+
+} // namespace
+
+bool canonicalizePathURL(const char* spec, const URLSegments& parsed, URLBuffer<char>& output, URLSegments& ouputParsed)
+{
+ return doCanonicalizePathURL<char, unsigned char>(URLComponentSource<char>(spec), parsed, output, ouputParsed);
+}
+
+bool canonicalizePathURL(const UChar* spec, const URLSegments& parsed, URLBuffer<char>& output, URLSegments& ouputParsed)
+{
+ return doCanonicalizePathURL<UChar, UChar>(URLComponentSource<UChar>(spec), parsed, output, ouputParsed);
+}
+
+bool ReplacePathURL(const char* base, const URLSegments& baseParsed, const Replacements<char>& replacements, URLBuffer<char>& output, URLSegments* ouputParsed)
+{
+ URLComponentSource<char> source(base);
+ URLSegments parsed(baseParsed);
+ SetupOverrideComponents(base, replacements, &source, &parsed);
+ return doCanonicalizePathURL<char, unsigned char>(source, parsed, output, *ouputParsed);
+}
+
+bool ReplacePathURL(const char* base, const URLSegments& baseParsed, const Replacements<UChar>& replacements, URLBuffer<char>& output, URLSegments* ouputParsed)
+{
+ RawURLBuffer<char> utf8;
+ URLComponentSource<char> source(base);
+ URLSegments parsed(baseParsed);
+ SetupUTF16OverrideComponents(base, replacements, utf8, &source, &parsed);
+ return doCanonicalizePathURL<char, unsigned char>(source, parsed, output, *ouputParsed);
+}
+
+} // namespace URLCanonicalizer
+
+} // namespace WTF
+
+#endif // USE(WTFURL)
diff --git a/Source/WTF/wtf/url/src/URLCanonQuery.cpp b/Source/WTF/wtf/url/src/URLCanonQuery.cpp
new file mode 100644
index 000000000..0b829ba5b
--- /dev/null
+++ b/Source/WTF/wtf/url/src/URLCanonQuery.cpp
@@ -0,0 +1,189 @@
+/*
+ * Copyright 2007 Google Inc. All rights reserved.
+ * Copyright 2012 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:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * 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.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND 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 THE COPYRIGHT
+ * OWNER 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 "URLCanon.h"
+
+#include "RawURLBuffer.h"
+#include "URLCanonInternal.h"
+#include "URLCharacterTypes.h"
+#include "URLQueryCharsetConverter.h"
+#include <wtf/text/ASCIIFastPath.h>
+
+// Query canonicalization in IE
+// ----------------------------
+// IE is very permissive for query parameters specified in links on the page
+// (in contrast to links that it constructs itself based on form data). It does
+// not unescape any character. It does not reject any escape sequence (be they
+// invalid like "%2y" or freaky like %00).
+//
+// IE only escapes spaces and nothing else. Embedded NULLs, tabs (0x09),
+// LF (0x0a), and CR (0x0d) are removed (this probably happens at an earlier
+// layer since they are removed from all portions of the URL). All other
+// characters are passed unmodified. Invalid UTF-16 sequences are preserved as
+// well, with each character in the input being converted to UTF-8. It is the
+// server's job to make sense of this invalid query.
+//
+// Invalid multibyte sequences (for example, invalid UTF-8 on a UTF-8 page)
+// are converted to the invalid character and sent as unescaped UTF-8 (0xef,
+// 0xbf, 0xbd). This may not be canonicalization, the parser may generate these
+// strings before the URL handler ever sees them.
+//
+// Our query canonicalization
+// --------------------------
+// We escape all non-ASCII characters and control characters, like Firefox.
+// This is more conformant to the URL spec, and there do not seem to be many
+// problems relating to Firefox's behavior.
+//
+// Like IE, we will never unescape (although the application may want to try
+// unescaping to present the user with a more understandable URL). We will
+// replace all invalid sequences (including invalid UTF-16 sequences, which IE
+// doesn't) with the "invalid character," and we will escape it.
+
+#if USE(WTFURL)
+
+namespace WTF {
+
+namespace URLCanonicalizer {
+
+namespace {
+
+// Returns true if the characters starting at |begin| and going until |end|
+// (non-inclusive) are all representable in 7-bits.
+template<typename CharacterType>
+bool isAllASCII(const CharacterType* spec, const URLComponent& query)
+{
+ return charactersAreAllASCII(spec + query.begin(), query.length());
+}
+
+// FIXME: Benjamin: get rid of this when everything is based on LChar.
+template<>
+bool isAllASCII<char>(const char* spec, const URLComponent& query)
+{
+ return charactersAreAllASCII(reinterpret_cast<const LChar*>(spec + query.begin()), query.length());
+}
+
+// Appends the given string to the output, escaping characters that do not
+// match the given |type| in SharedCharTypes. This version will accept 8 or 16
+// bit characters, but assumes that they have only 7-bit values. It also assumes
+// that all UTF-8 values are correct, so doesn't bother checking
+template<typename CharacterType>
+void appendRaw8BitQueryString(const CharacterType* source, int length, URLBuffer<char>& output)
+{
+ for (int i = 0; i < length; ++i) {
+ if (!URLCharacterTypes::isQueryChar(static_cast<unsigned char>(source[i])))
+ appendURLEscapedCharacter(static_cast<unsigned char>(source[i]), output);
+ else // Doesn't need escaping.
+ output.append(static_cast<char>(source[i]));
+ }
+}
+
+// Runs the converter on the given UTF-8 input. Since the converter expects
+// UTF-16, we have to convert first. The converter must be non-null.
+void runConverter(const char* spec, const URLComponent& query, URLQueryCharsetConverter* converter, URLBuffer<char>& output)
+{
+ // This function will replace any misencoded values with the invalid
+ // character. This is what we want so we don't have to check for error.
+ RawURLBuffer<UChar> utf16;
+ ConvertUTF8ToUTF16(&spec[query.begin()], query.length(), utf16);
+ converter->convertFromUTF16(utf16.data(), utf16.length(), output);
+}
+
+// Runs the converter with the given UTF-16 input. We don't have to do
+// anything, but this overriddden function allows us to use the same code
+// for both UTF-8 and UTF-16 input.
+void runConverter(const UChar* spec, const URLComponent& query, URLQueryCharsetConverter* converter, URLBuffer<char>& output)
+{
+ converter->convertFromUTF16(&spec[query.begin()], query.length(), output);
+}
+
+template<typename CharacterType>
+void doConvertToQueryEncoding(const CharacterType* spec, const URLComponent& query, URLQueryCharsetConverter* converter, URLBuffer<char>& output)
+{
+ if (isAllASCII(spec, query)) {
+ // Easy: the input can just appended with no character set conversions.
+ appendRaw8BitQueryString(&spec[query.begin()], query.length(), output);
+ } else {
+ // Harder: convert to the proper encoding first.
+ if (converter) {
+ // Run the converter to get an 8-bit string, then append it, escaping
+ // necessary values.
+ RawURLBuffer<char> eightBitQueryString;
+ runConverter(spec, query, converter, eightBitQueryString);
+ appendRaw8BitQueryString(eightBitQueryString.data(), eightBitQueryString.length(), output);
+ } else {
+ // No converter, do our own UTF-8 conversion.
+ appendStringOfType(&spec[query.begin()], query.length(), URLCharacterTypes::QueryCharacter, output);
+ }
+ }
+}
+
+template<typename CharacterType>
+void doCanonicalizeQuery(const CharacterType* spec, const URLComponent& query, URLQueryCharsetConverter* converter,
+ URLBuffer<char>& output, URLComponent& outputQueryComponent)
+{
+ if (query.length() < 0) {
+ outputQueryComponent = URLComponent();
+ return;
+ }
+
+ output.append('?');
+ outputQueryComponent.setBegin(output.length());
+
+ doConvertToQueryEncoding<CharacterType>(spec, query, converter, output);
+
+ outputQueryComponent.setLength(output.length() - outputQueryComponent.begin());
+}
+
+} // namespace
+
+void CanonicalizeQuery(const char* spec, const URLComponent& query, URLQueryCharsetConverter* converter,
+ URLBuffer<char>& output, URLComponent* outputQueryComponent)
+{
+ doCanonicalizeQuery(spec, query, converter, output, *outputQueryComponent);
+}
+
+void CanonicalizeQuery(const UChar* spec, const URLComponent& query, URLQueryCharsetConverter* converter,
+ URLBuffer<char>& output, URLComponent* outputQueryComponent)
+{
+ doCanonicalizeQuery(spec, query, converter, output, *outputQueryComponent);
+}
+
+void ConvertUTF16ToQueryEncoding(const UChar* input, const URLComponent& query, URLQueryCharsetConverter* converter, URLBuffer<char>& output)
+{
+ doConvertToQueryEncoding<UChar>(input, query, converter, output);
+}
+
+} // namespace URLCanonicalizer
+
+} // namespace WTF
+
+#endif // USE(WTFURL)
diff --git a/Source/WTF/wtf/url/src/URLCanonRelative.cpp b/Source/WTF/wtf/url/src/URLCanonRelative.cpp
new file mode 100644
index 000000000..7ef050064
--- /dev/null
+++ b/Source/WTF/wtf/url/src/URLCanonRelative.cpp
@@ -0,0 +1,572 @@
+/*
+ * Copyright 2007 Google Inc. All rights reserved.
+ * Copyright 2012 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:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * 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.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND 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 THE COPYRIGHT
+ * OWNER 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.
+ */
+
+// Canonicalizer functions for working with and resolving relative URLs.
+
+#include "config.h"
+#include "URLCanon.h"
+
+#include "URLCanonInternal.h"
+#include "URLFile.h"
+#include "URLParseInternal.h"
+#include "URLUtilInternal.h"
+
+#if USE(WTFURL)
+
+namespace WTF {
+
+namespace URLCanonicalizer {
+
+namespace {
+
+// Firefox does a case-sensitive compare (which is probably wrong--Mozilla bug
+// 379034), whereas IE is case-insensetive.
+//
+// We choose to be more permissive like IE. We don't need to worry about
+// unescaping or anything here: neither IE or Firefox allow this. We also
+// don't have to worry about invalid scheme characters since we are comparing
+// against the canonical scheme of the base.
+//
+// The base URL should always be canonical, therefore is ASCII.
+template<typename CHAR>
+bool AreSchemesEqual(const char* base,
+ const URLComponent& baseScheme,
+ const CHAR* cmp,
+ const URLComponent& cmpScheme)
+{
+ if (baseScheme.length() != cmpScheme.length())
+ return false;
+ for (int i = 0; i < baseScheme.length(); i++) {
+ // We assume the base is already canonical, so we don't have to
+ // canonicalize it.
+ if (canonicalSchemeChar(cmp[cmpScheme.begin() + i]) !=
+ base[baseScheme.begin() + i])
+ return false;
+ }
+ return true;
+}
+
+#if OS(WINDOWS)
+// Here, we also allow Windows paths to be represented as "/C:/" so we can be
+// consistent about URL paths beginning with slashes. This function is like
+// DoesBeginWindowsDrivePath except that it also requires a slash at the
+// beginning.
+template<typename CHAR>
+bool doesBeginSlashWindowsDriveSpec(const CHAR* spec, int startOffset, int specLength)
+{
+ if (startOffset >= specLength)
+ return false;
+ return URLParser::isURLSlash(spec[startOffset]) && URLParser::doesBeginWindowsDriveSpec(spec, startOffset + 1, specLength);
+}
+
+#endif // OS(WINDOWS)
+
+// See isRelativeURL in the header file for usage.
+template<typename CharacterType>
+bool doIsRelativeURL(const char* base, const URLSegments& baseParsed,
+ const CharacterType* url, int urlLength,
+ bool isBaseHierarchical,
+ bool& isRelative, URLComponent& relativeComponent)
+{
+ isRelative = false; // So we can default later to not relative.
+
+ // Trim whitespace and construct a new range for the substring.
+ int begin = 0;
+ URLParser::trimURL(url, begin, urlLength);
+ if (begin >= urlLength) {
+ // Empty URLs are relative, but do nothing.
+ relativeComponent = URLComponent(begin, 0);
+ isRelative = true;
+ return true;
+ }
+
+#if OS(WINDOWS)
+ // We special case paths like "C:\foo" so they can link directly to the
+ // file on Windows (IE compatability). The security domain stuff should
+ // prevent a link like this from actually being followed if its on a
+ // web page.
+ //
+ // We treat "C:/foo" as an absolute URL. We can go ahead and treat "/c:/"
+ // as relative, as this will just replace the path when the base scheme
+ // is a file and the answer will still be correct.
+ //
+ // We require strict backslashes when detecting UNC since two forward
+ // shashes should be treated a a relative URL with a hostname.
+ if (URLParser::doesBeginWindowsDriveSpec(url, begin, urlLength) || URLParser::doesBeginUNCPath(url, begin, urlLength, true))
+ return true;
+#endif // OS(WINDOWS)
+
+ // See if we've got a scheme, if not, we know this is a relative URL.
+ // BUT: Just because we have a scheme, doesn't make it absolute.
+ // "http:foo.html" is a relative URL with path "foo.html". If the scheme is
+ // empty, we treat it as relative (":foo") like IE does.
+ URLComponent scheme;
+ if (!URLParser::ExtractScheme(url, urlLength, &scheme) || !scheme.length()) {
+ // Don't allow relative URLs if the base scheme doesn't support it.
+ if (!isBaseHierarchical)
+ return false;
+
+ relativeComponent = URLComponent::fromRange(begin, urlLength);
+ isRelative = true;
+ return true;
+ }
+
+ // If the scheme isn't valid, then it's relative.
+ int schemeEnd = scheme.end();
+ for (int i = scheme.begin(); i < schemeEnd; i++) {
+ if (!canonicalSchemeChar(url[i])) {
+ relativeComponent = URLComponent::fromRange(begin, urlLength);
+ isRelative = true;
+ return true;
+ }
+ }
+
+ // If the scheme is not the same, then we can't count it as relative.
+ if (!AreSchemesEqual(base, baseParsed.scheme, url, scheme))
+ return true;
+
+ // When the scheme that they both share is not hierarchical, treat the
+ // incoming scheme as absolute (this way with the base of "data:foo",
+ // "data:bar" will be reported as absolute.
+ if (!isBaseHierarchical)
+ return true;
+
+ int colonOffset = scheme.end();
+
+ // If it's a filesystem URL, the only valid way to make it relative is not to
+ // supply a scheme. There's no equivalent to e.g. http:index.html.
+ if (URLUtilities::CompareSchemeComponent(url, scheme, "filesystem"))
+ return true;
+
+ // ExtractScheme guarantees that the colon immediately follows what it
+ // considers to be the scheme. countConsecutiveSlashes will handle the
+ // case where the begin offset is the end of the input.
+ int numSlashes = URLParser::countConsecutiveSlashes(url, colonOffset + 1, urlLength);
+
+ if (!numSlashes || numSlashes == 1) {
+ // No slashes means it's a relative path like "http:foo.html". One slash
+ // is an absolute path. "http:/home/foo.html"
+ isRelative = true;
+ relativeComponent = URLComponent::fromRange(colonOffset + 1, urlLength);
+ return true;
+ }
+
+ // Two or more slashes after the scheme we treat as absolute.
+ return true;
+}
+
+// Copies all characters in the range [begin, end) of |spec| to the output,
+// up until and including the last slash. There should be a slash in the
+// range, if not, nothing will be copied.
+//
+// The input is assumed to be canonical, so we search only for exact slashes
+// and not backslashes as well. We also know that it's ASCII.
+void CopyToLastSlash(const char* spec, int begin, int end, URLBuffer<char>& output)
+{
+ // Find the last slash.
+ int lastSlash = -1;
+ for (int i = end - 1; i >= begin; --i) {
+ if (spec[i] == '/') {
+ lastSlash = i;
+ break;
+ }
+ }
+ if (lastSlash < 0)
+ return; // No slash.
+
+ // Copy.
+ for (int i = begin; i <= lastSlash; ++i)
+ output.append(spec[i]);
+}
+
+// Copies a single component from the source to the output. This is used
+// when resolving relative URLs and a given component is unchanged. Since the
+// source should already be canonical, we don't have to do anything special,
+// and the input is ASCII.
+void CopyOneComponent(const char* source,
+ const URLComponent& sourceComponent,
+ URLBuffer<char>& output,
+ URLComponent* outputComponent)
+{
+ if (sourceComponent.length() < 0) {
+ // This component is not present.
+ *outputComponent = URLComponent();
+ return;
+ }
+
+ outputComponent->setBegin(output.length());
+ int sourceEnd = sourceComponent.end();
+ for (int i = sourceComponent.begin(); i < sourceEnd; i++)
+ output.append(source[i]);
+ outputComponent->setLength(output.length() - outputComponent->begin());
+}
+
+#if OS(WINDOWS)
+
+// Called on Windows when the base URL is a file URL, this will copy the "C:"
+// to the output, if there is a drive letter and if that drive letter is not
+// being overridden by the relative URL. Otherwise, do nothing.
+//
+// It will return the index of the beginning of the next character in the
+// base to be processed: if there is a "C:", the slash after it, or if
+// there is no drive letter, the slash at the beginning of the path, or
+// the end of the base. This can be used as the starting offset for further
+// path processing.
+template<typename CHAR>
+int CopyBaseDriveSpecIfNecessary(const char* baseURL,
+ int basePathBegin,
+ int basePathEnd,
+ const CHAR* relativeURL,
+ int pathStart,
+ int relativeUrlLength,
+ URLBuffer<char>& output)
+{
+ if (basePathBegin >= basePathEnd)
+ return basePathBegin; // No path.
+
+ // If the relative begins with a drive spec, don't do anything. The existing
+ // drive spec in the base will be replaced.
+ if (URLParser::doesBeginWindowsDriveSpec(relativeURL,
+ pathStart, relativeUrlLength)) {
+ return basePathBegin; // Relative URL path is "C:/foo"
+ }
+
+ // The path should begin with a slash (as all canonical paths do). We check
+ // if it is followed by a drive letter and copy it.
+ if (doesBeginSlashWindowsDriveSpec(baseURL, basePathBegin, basePathEnd)) {
+ // Copy the two-character drive spec to the output. It will now look like
+ // "file:///C:" so the rest of it can be treated like a standard path.
+ output.append('/');
+ output.append(baseURL[basePathBegin + 1]);
+ output.append(baseURL[basePathBegin + 2]);
+ return basePathBegin + 3;
+ }
+
+ return basePathBegin;
+}
+
+#endif // OS(WINDOWS)
+
+// A subroutine of doResolveRelativeURL, this resolves the URL knowning that
+// the input is a relative path or less (qyuery or ref).
+template<typename CHAR>
+bool doResolveRelativePath(const char* baseURL,
+ const URLSegments& baseParsed,
+ bool /* baseIsFile */,
+ const CHAR* relativeURL,
+ const URLComponent& relativeComponent,
+ URLQueryCharsetConverter* queryConverter,
+ URLBuffer<char>& output,
+ URLSegments* outputParsed)
+{
+ bool success = true;
+
+ // We know the authority section didn't change, copy it to the output. We
+ // also know we have a path so can copy up to there.
+ URLComponent path, query, ref;
+ URLParser::parsePathInternal(relativeURL,
+ relativeComponent,
+ &path,
+ &query,
+ &ref);
+ // Canonical URLs always have a path, so we can use that offset.
+ output.append(baseURL, baseParsed.path.begin());
+
+ if (path.length() > 0) {
+ // The path is replaced or modified.
+ int truePathBegin = output.length();
+
+ // For file: URLs on Windows, we don't want to treat the drive letter and
+ // colon as part of the path for relative file resolution when the
+ // incoming URL does not provide a drive spec. We save the true path
+ // beginning so we can fix it up after we are done.
+ int basePathBegin = baseParsed.path.begin();
+#if OS(WINDOWS)
+ if (baseIsFile) {
+ basePathBegin = CopyBaseDriveSpecIfNecessary(baseURL, baseParsed.path.begin(), baseParsed.path.end(),
+ relativeURL, relativeComponent.begin(), relativeComponent.end(),
+ output);
+ // Now the output looks like either "file://" or "file:///C:"
+ // and we can start appending the rest of the path. |basePathBegin|
+ // points to the character in the base that comes next.
+ }
+#endif // OS(WINDOWS)
+
+ if (URLParser::isURLSlash(relativeURL[path.begin()])) {
+ // Easy case: the path is an absolute path on the server, so we can
+ // just replace everything from the path on with the new versions.
+ // Since the input should be canonical hierarchical URL, we should
+ // always have a path.
+ success &= CanonicalizePath(relativeURL, path,
+ output, &outputParsed->path);
+ } else {
+ // Relative path, replace the query, and reference. We take the
+ // original path with the file part stripped, and append the new path.
+ // The canonicalizer will take care of resolving ".." and "."
+ int pathBegin = output.length();
+ CopyToLastSlash(baseURL, basePathBegin, baseParsed.path.end(),
+ output);
+ success &= CanonicalizePartialPath(relativeURL, path, pathBegin,
+ output);
+ outputParsed->path = URLComponent::fromRange(pathBegin, output.length());
+
+ // Copy the rest of the stuff after the path from the relative path.
+ }
+
+ // Finish with the query and reference part (these can't fail).
+ CanonicalizeQuery(relativeURL, query, queryConverter, output, &outputParsed->query);
+ canonicalizeFragment(relativeURL, ref, output, outputParsed->fragment);
+
+ // Fix the path beginning to add back the "C:" we may have written above.
+ outputParsed->path = URLComponent::fromRange(truePathBegin,
+ outputParsed->path.end());
+ return success;
+ }
+
+ // If we get here, the path is unchanged: copy to output.
+ CopyOneComponent(baseURL, baseParsed.path, output, &outputParsed->path);
+
+ if (query.isValid()) {
+ // Just the query specified, replace the query and reference (ignore
+ // failures for refs)
+ CanonicalizeQuery(relativeURL, query, queryConverter,
+ output, &outputParsed->query);
+ canonicalizeFragment(relativeURL, ref, output, outputParsed->fragment);
+ return success;
+ }
+
+ // If we get here, the query is unchanged: copy to output. Note that the
+ // range of the query parameter doesn't include the question mark, so we
+ // have to add it manually if there is a component.
+ if (baseParsed.query.isValid())
+ output.append('?');
+ CopyOneComponent(baseURL, baseParsed.query, output, &outputParsed->query);
+
+ if (ref.isValid()) {
+ // Just the reference specified: replace it (ignoring failures).
+ canonicalizeFragment(relativeURL, ref, output, outputParsed->fragment);
+ return success;
+ }
+
+ // We should always have something to do in this function, the caller checks
+ // that some component is being replaced.
+ ASSERT_NOT_REACHED();
+ return success;
+}
+
+// Resolves a relative URL that contains a host. Typically, these will
+// be of the form "//www.apple.com/foo/bar?baz#fragment" and the only thing which
+// should be kept from the original URL is the scheme.
+template<typename CHAR>
+bool doResolveRelativeHost(const char* baseURL,
+ const URLSegments& baseParsed,
+ const CHAR* relativeURL,
+ const URLComponent& relativeComponent,
+ URLQueryCharsetConverter* queryConverter,
+ URLBuffer<char>& output,
+ URLSegments* outputParsed)
+{
+ // Parse the relative URL, just like we would for anything following a
+ // scheme.
+ URLSegments relativeParsed; // Everything but the scheme is valid.
+ URLParser::parseAfterScheme(&relativeURL[relativeComponent.begin()],
+ relativeComponent.length(), relativeComponent.begin(),
+ relativeParsed);
+
+ // Now we can just use the replacement function to replace all the necessary
+ // parts of the old URL with the new one.
+ Replacements<CHAR> replacements;
+ replacements.SetUsername(relativeURL, relativeParsed.username);
+ replacements.SetPassword(relativeURL, relativeParsed.password);
+ replacements.SetHost(relativeURL, relativeParsed.host);
+ replacements.SetPort(relativeURL, relativeParsed.port);
+ replacements.SetPath(relativeURL, relativeParsed.path);
+ replacements.SetQuery(relativeURL, relativeParsed.query);
+ replacements.SetRef(relativeURL, relativeParsed.fragment);
+
+ return ReplaceStandardURL(baseURL, baseParsed, replacements,
+ queryConverter, output, outputParsed);
+}
+
+// Resolves a relative URL that happens to be an absolute file path. Examples
+// include: "//hostname/path", "/c:/foo", and "//hostname/c:/foo".
+template<typename CharacterType>
+bool doResolveAbsoluteFile(const CharacterType* relativeURL,
+ const URLComponent& relativeComponent,
+ URLQueryCharsetConverter* queryConverter,
+ URLBuffer<char>& output,
+ URLSegments& outputParsed)
+{
+ // Parse the file URL. The file URl parsing function uses the same logic
+ // as we do for determining if the file is absolute, in which case it will
+ // not bother to look for a scheme.
+ URLSegments relativeParsed;
+ URLParser::ParseFileURL(&relativeURL[relativeComponent.begin()],
+ relativeComponent.length(), &relativeParsed);
+
+ return CanonicalizeFileURL(&relativeURL[relativeComponent.begin()],
+ relativeComponent.length(), relativeParsed,
+ queryConverter, output, &outputParsed);
+}
+
+// TODO(brettw) treat two slashes as root like Mozilla for FTP?
+template<typename CHAR>
+bool doResolveRelativeURL(const char* baseURL,
+ const URLSegments& baseParsed,
+ bool baseIsFile,
+ const CHAR* relativeURL,
+ const URLComponent& relativeComponent,
+ URLQueryCharsetConverter* queryConverter,
+ URLBuffer<char>& output,
+ URLSegments* outputParsed)
+{
+ // Starting point for our output parsed. We'll fix what we change.
+ *outputParsed = baseParsed;
+
+ // Sanity check: the input should have a host or we'll break badly below.
+ // We can only resolve relative URLs with base URLs that have hosts and
+ // paths (even the default path of "/" is OK).
+ //
+ // We allow hosts with no length so we can handle file URLs, for example.
+ if (baseParsed.path.length() <= 0) {
+ // On error, return the input (resolving a relative URL on a non-relative
+ // base = the base).
+ int baseLength = baseParsed.length();
+ for (int i = 0; i < baseLength; i++)
+ output.append(baseURL[i]);
+ return false;
+ }
+
+ if (relativeComponent.length() <= 0) {
+ // Empty relative URL, leave unchanged, only removing the ref component.
+ int baseLength = baseParsed.length();
+ baseLength -= baseParsed.fragment.length() + 1;
+ outputParsed->fragment.reset();
+ output.append(baseURL, baseLength);
+ return true;
+ }
+
+ int numSlashes = URLParser::countConsecutiveSlashes(relativeURL, relativeComponent.begin(), relativeComponent.end());
+
+#if OS(WINDOWS)
+ // On Windows, two slashes for a file path (regardless of which direction
+ // they are) means that it's UNC. Two backslashes on any base scheme mean
+ // that it's an absolute UNC path (we use the baseIsFile flag to control
+ // how strict the UNC finder is).
+ //
+ // We also allow Windows absolute drive specs on any scheme (for example
+ // "c:\foo") like IE does. There must be no preceeding slashes in this
+ // case (we reject anything like "/c:/foo") because that should be treated
+ // as a path. For file URLs, we allow any number of slashes since that would
+ // be setting the path.
+ //
+ // This assumes the absolute path resolver handles absolute URLs like this
+ // properly. URLUtilities::DoCanonicalize does this.
+ int afterSlashes = relativeComponent.begin + numSlashes;
+ if (URLParser::doesBeginUNCPath(relativeURL, relativeComponent.begin(), relativeComponent.end(), !baseIsFile)
+ || ((!numSlashes || baseIsFile) && URLParser::doesBeginWindowsDriveSpec(relativeURL, afterSlashes, relativeComponent.end()))) {
+ return doResolveAbsoluteFile(relativeURL, relativeComponent,
+ queryConverter, output, *outputParsed);
+ }
+#else
+ // Other platforms need explicit handling for file: URLs with multiple
+ // slashes because the generic scheme parsing always extracts a host, but a
+ // file: URL only has a host if it has exactly 2 slashes. This also
+ // handles the special case where the URL is only slashes, since that
+ // doesn't have a host part either.
+ if (baseIsFile && (numSlashes > 2 || numSlashes == relativeComponent.length())) {
+ return doResolveAbsoluteFile(relativeURL, relativeComponent,
+ queryConverter, output, *outputParsed);
+ }
+#endif
+
+ // Any other double-slashes mean that this is relative to the scheme.
+ if (numSlashes >= 2) {
+ return doResolveRelativeHost(baseURL, baseParsed,
+ relativeURL, relativeComponent,
+ queryConverter, output, outputParsed);
+ }
+
+ // When we get here, we know that the relative URL is on the same host.
+ return doResolveRelativePath(baseURL, baseParsed, baseIsFile,
+ relativeURL, relativeComponent,
+ queryConverter, output, outputParsed);
+}
+
+} // namespace
+
+bool isRelativeURL(const char* base, const URLSegments& baseParsed,
+ const char* fragment, int fragmentLength,
+ bool isBaseHierarchical,
+ bool& isRelative, URLComponent& relativeComponent)
+{
+ return doIsRelativeURL<char>(base, baseParsed, fragment, fragmentLength, isBaseHierarchical, isRelative, relativeComponent);
+}
+
+bool isRelativeURL(const char* base, const URLSegments& baseParsed,
+ const UChar* fragment, int fragmentLength,
+ bool isBaseHierarchical,
+ bool& isRelative, URLComponent& relativeComponent)
+{
+ return doIsRelativeURL<UChar>(base, baseParsed, fragment, fragmentLength, isBaseHierarchical, isRelative, relativeComponent);
+}
+
+bool resolveRelativeURL(const char* baseURL,
+ const URLSegments& baseParsed,
+ bool baseIsFile,
+ const char* relativeURL,
+ const URLComponent& relativeComponent,
+ URLQueryCharsetConverter* queryConverter,
+ URLBuffer<char>& output,
+ URLSegments* outputParsed)
+{
+ return doResolveRelativeURL<char>(baseURL, baseParsed, baseIsFile, relativeURL,
+ relativeComponent, queryConverter, output, outputParsed);
+}
+
+bool resolveRelativeURL(const char* baseURL,
+ const URLSegments& baseParsed,
+ bool baseIsFile,
+ const UChar* relativeURL,
+ const URLComponent& relativeComponent,
+ URLQueryCharsetConverter* queryConverter,
+ URLBuffer<char>& output,
+ URLSegments* outputParsed)
+{
+ return doResolveRelativeURL<UChar>(baseURL, baseParsed, baseIsFile, relativeURL,
+ relativeComponent, queryConverter, output, outputParsed);
+}
+
+} // namespace URLCanonicalizer
+
+} // namespace WTF
+
+#endif // USE(WTFURL)
diff --git a/Source/WTF/wtf/url/src/URLCanonStdURL.cpp b/Source/WTF/wtf/url/src/URLCanonStdURL.cpp
new file mode 100644
index 000000000..5e2dd1cea
--- /dev/null
+++ b/Source/WTF/wtf/url/src/URLCanonStdURL.cpp
@@ -0,0 +1,210 @@
+/*
+ * Copyright 2007 Google Inc. All rights reserved.
+ * Copyright 2012 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:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * 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.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND 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 THE COPYRIGHT
+ * OWNER 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.
+ */
+
+// Functions to canonicalize "standard" URLs, which are ones that have an
+// authority section including a host name.
+
+#include "config.h"
+#include "URLCanon.h"
+
+#include "RawURLBuffer.h"
+#include "URLCanonInternal.h"
+
+#if USE(WTFURL)
+
+namespace WTF {
+
+namespace URLCanonicalizer {
+
+namespace {
+
+template<typename CHAR, typename UCHAR>
+bool doCanonicalizeStandardURL(const URLComponentSource<CHAR>& source,
+ const URLSegments& parsed,
+ URLQueryCharsetConverter* queryConverter,
+ URLBuffer<char>& output,
+ URLSegments& outputParsed)
+{
+ // Scheme: this will append the colon.
+ bool success = canonicalizeScheme(source.scheme, parsed.scheme, output, outputParsed.scheme);
+
+ // Authority (username, password, host, port)
+ bool haveAuthority;
+ if (parsed.username.isNonEmpty() || parsed.password.isValid() || parsed.host.isNonEmpty() || parsed.port.isValid()) {
+ haveAuthority = true;
+
+ // Only write the authority separators when we have a scheme.
+ if (parsed.scheme.isValid())
+ output.append("//", 2);
+
+ // User info: the canonicalizer will handle the : and @.
+ success &= canonicalizeUserInfo(source.username, parsed.username, source.password, parsed.password,
+ output, outputParsed.username, outputParsed.password);
+ success &= canonicalizeHost(source.host, parsed.host, output, outputParsed.host);
+
+ // Host must not be empty for standard URLs.
+ if (!parsed.host.isNonEmpty())
+ success = false;
+
+ // Port: the port canonicalizer will handle the colon.
+ int defaultPort = defaultPortForScheme(&output.data()[outputParsed.scheme.begin()], outputParsed.scheme.length());
+ success &= canonicalizePort(source.port, parsed.port, defaultPort, output, outputParsed.port);
+ } else {
+ // No authority, clear the components.
+ haveAuthority = false;
+ outputParsed.host.reset();
+ outputParsed.username.reset();
+ outputParsed.password.reset();
+ outputParsed.port.reset();
+ success = false; // Standard URLs must have an authority.
+ }
+
+ // Path
+ if (parsed.path.isNonEmpty())
+ success &= CanonicalizePath(source.path, parsed.path, output, &outputParsed.path);
+ else if (haveAuthority || parsed.query.isNonEmpty() || parsed.fragment.isNonEmpty()) {
+ // When we have an empty path, make up a path when we have an authority
+ // or something following the path. The only time we allow an empty
+ // output path is when there is nothing else.
+ outputParsed.path = URLComponent(output.length(), 1);
+ output.append('/');
+ } else
+ outputParsed.path.reset(); // No path at all
+
+ // Query
+ CanonicalizeQuery(source.query, parsed.query, queryConverter, output, &outputParsed.query);
+
+ // Ref: ignore failure for this, since the page can probably still be loaded.
+ canonicalizeFragment(source.ref, parsed.fragment, output, outputParsed.fragment);
+
+ return success;
+}
+
+} // namespace
+
+
+// Returns the default port for the given canonical scheme, or PORT_UNSPECIFIED
+// if the scheme is unknown.
+int defaultPortForScheme(const char* scheme, int schemeLength)
+{
+ int defaultPort = URLParser::PORT_UNSPECIFIED;
+ switch (schemeLength) {
+ case 4:
+ if (!strncmp(scheme, "http", schemeLength))
+ defaultPort = 80;
+ break;
+ case 5:
+ if (!strncmp(scheme, "https", schemeLength))
+ defaultPort = 443;
+ break;
+ case 3:
+ if (!strncmp(scheme, "ftp", schemeLength))
+ defaultPort = 21;
+ else if (!strncmp(scheme, "wss", schemeLength))
+ defaultPort = 443;
+ break;
+ case 6:
+ if (!strncmp(scheme, "gopher", schemeLength))
+ defaultPort = 70;
+ break;
+ case 2:
+ if (!strncmp(scheme, "ws", schemeLength))
+ defaultPort = 80;
+ break;
+ }
+ return defaultPort;
+}
+
+bool CanonicalizeStandardURL(const char* spec,
+ int /* specLength */,
+ const URLSegments& parsed,
+ URLQueryCharsetConverter* queryConverter,
+ URLBuffer<char>& output,
+ URLSegments* outputParsed)
+{
+ return doCanonicalizeStandardURL<char, unsigned char>(URLComponentSource<char>(spec), parsed, queryConverter,
+ output, *outputParsed);
+}
+
+bool CanonicalizeStandardURL(const UChar* spec,
+ int /* specLength */,
+ const URLSegments& parsed,
+ URLQueryCharsetConverter* queryConverter,
+ URLBuffer<char>& output,
+ URLSegments* outputParsed)
+{
+ return doCanonicalizeStandardURL<UChar, UChar>(URLComponentSource<UChar>(spec), parsed, queryConverter,
+ output, *outputParsed);
+}
+
+// It might be nice in the future to optimize this so unchanged components don't
+// need to be recanonicalized. This is especially true since the common case for
+// ReplaceComponents is removing things we don't want, like reference fragments
+// and usernames. These cases can become more efficient if we can assume the
+// rest of the URL is OK with these removed (or only the modified parts
+// recanonicalized). This would be much more complex to implement, however.
+//
+// You would also need to update DoReplaceComponents in URLUtilities.cc which
+// relies on this re-checking everything (see the comment there for why).
+bool ReplaceStandardURL(const char* base,
+ const URLSegments& baseParsed,
+ const Replacements<char>& replacements,
+ URLQueryCharsetConverter* queryConverter,
+ URLBuffer<char>& output,
+ URLSegments* outputParsed)
+{
+ URLComponentSource<char> source(base);
+ URLSegments parsed(baseParsed);
+ SetupOverrideComponents(base, replacements, &source, &parsed);
+ return doCanonicalizeStandardURL<char, unsigned char>(source, parsed, queryConverter, output, *outputParsed);
+}
+
+// For 16-bit replacements, we turn all the replacements into UTF-8 so the
+// regular codepath can be used.
+bool ReplaceStandardURL(const char* base,
+ const URLSegments& baseParsed,
+ const Replacements<UChar>& replacements,
+ URLQueryCharsetConverter* queryConverter,
+ URLBuffer<char>& output,
+ URLSegments* outputParsed)
+{
+ RawURLBuffer<char> utf8;
+ URLComponentSource<char> source(base);
+ URLSegments parsed(baseParsed);
+ SetupUTF16OverrideComponents(base, replacements, utf8, &source, &parsed);
+ return doCanonicalizeStandardURL<char, unsigned char>(source, parsed, queryConverter, output, *outputParsed);
+}
+
+} // namespace URLCanonicalizer
+
+} // namespace WTF
+
+#endif // USE(WTFURL)
diff --git a/Source/WTF/wtf/url/src/URLCharacterTypes.cpp b/Source/WTF/wtf/url/src/URLCharacterTypes.cpp
index f56e7207c..21dd22fcc 100644
--- a/Source/WTF/wtf/url/src/URLCharacterTypes.cpp
+++ b/Source/WTF/wtf/url/src/URLCharacterTypes.cpp
@@ -1,30 +1,32 @@
-// Copyright 2010, Google 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:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * 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.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND 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 THE COPYRIGHT
-// OWNER 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.
+/*
+ * Copyright 2010 Google 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:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * 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.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND 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 THE COPYRIGHT
+ * OWNER 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 "URLCharacterTypes.h"
@@ -32,7 +34,6 @@
#if USE(WTFURL)
namespace WTF {
-
const unsigned char URLCharacterTypes::characterTypeTable[0x100] = {
InvalidCharacter, InvalidCharacter, InvalidCharacter, InvalidCharacter,
InvalidCharacter, InvalidCharacter, InvalidCharacter, InvalidCharacter,
@@ -43,100 +44,100 @@ const unsigned char URLCharacterTypes::characterTypeTable[0x100] = {
InvalidCharacter, InvalidCharacter, InvalidCharacter, InvalidCharacter,
InvalidCharacter, InvalidCharacter, InvalidCharacter, InvalidCharacter, // 0x10 - 0x1f
InvalidCharacter, // 0x20 ' ' (escape spaces in queries)
- QueryCharacter | UserInfoCharacter, // 0x21 !
+ QueryCharacter | UserInfoCharacter | ComponentCharacter, // 0x21 !
InvalidCharacter, // 0x22 "
InvalidCharacter, // 0x23 # (invalid in query since it marks the ref)
QueryCharacter | UserInfoCharacter, // 0x24 $
QueryCharacter | UserInfoCharacter, // 0x25 %
QueryCharacter | UserInfoCharacter, // 0x26 &
- QueryCharacter | UserInfoCharacter, // 0x27 '
- QueryCharacter | UserInfoCharacter, // 0x28 (
- QueryCharacter | UserInfoCharacter, // 0x29 )
- QueryCharacter | UserInfoCharacter, // 0x2a *
+ QueryCharacter | UserInfoCharacter | ComponentCharacter, // 0x27 '
+ QueryCharacter | UserInfoCharacter | ComponentCharacter, // 0x28 (
+ QueryCharacter | UserInfoCharacter | ComponentCharacter, // 0x29 )
+ QueryCharacter | UserInfoCharacter | ComponentCharacter, // 0x2a *
QueryCharacter | UserInfoCharacter, // 0x2b +
QueryCharacter | UserInfoCharacter, // 0x2c ,
- QueryCharacter | UserInfoCharacter, // 0x2d -
- QueryCharacter | UserInfoCharacter | IPv4Character, // 0x2e .
+ QueryCharacter | UserInfoCharacter | ComponentCharacter, // 0x2d -
+ QueryCharacter | UserInfoCharacter | IPv4Character | ComponentCharacter, // 0x2e .
QueryCharacter, // 0x2f /
- QueryCharacter | UserInfoCharacter | IPv4Character | HexCharacter | DecimalCharacter | OctalCharacter, // 0x30 0
- QueryCharacter | UserInfoCharacter | IPv4Character | HexCharacter | DecimalCharacter | OctalCharacter, // 0x31 1
- QueryCharacter | UserInfoCharacter | IPv4Character | HexCharacter | DecimalCharacter | OctalCharacter, // 0x32 2
- QueryCharacter | UserInfoCharacter | IPv4Character | HexCharacter | DecimalCharacter | OctalCharacter, // 0x33 3
- QueryCharacter | UserInfoCharacter | IPv4Character | HexCharacter | DecimalCharacter | OctalCharacter, // 0x34 4
- QueryCharacter | UserInfoCharacter | IPv4Character | HexCharacter | DecimalCharacter | OctalCharacter, // 0x35 5
- QueryCharacter | UserInfoCharacter | IPv4Character | HexCharacter | DecimalCharacter | OctalCharacter, // 0x36 6
- QueryCharacter | UserInfoCharacter | IPv4Character | HexCharacter | DecimalCharacter | OctalCharacter, // 0x37 7
- QueryCharacter | UserInfoCharacter | IPv4Character | HexCharacter | DecimalCharacter, // 0x38 8
- QueryCharacter | UserInfoCharacter | IPv4Character | HexCharacter | DecimalCharacter, // 0x39 9
+ QueryCharacter | UserInfoCharacter | IPv4Character | HexadecimalCharacter | DecimalCharacter | OctalCharacter | ComponentCharacter, // 0x30 0
+ QueryCharacter | UserInfoCharacter | IPv4Character | HexadecimalCharacter | DecimalCharacter | OctalCharacter | ComponentCharacter, // 0x31 1
+ QueryCharacter | UserInfoCharacter | IPv4Character | HexadecimalCharacter | DecimalCharacter | OctalCharacter | ComponentCharacter, // 0x32 2
+ QueryCharacter | UserInfoCharacter | IPv4Character | HexadecimalCharacter | DecimalCharacter | OctalCharacter | ComponentCharacter, // 0x33 3
+ QueryCharacter | UserInfoCharacter | IPv4Character | HexadecimalCharacter | DecimalCharacter | OctalCharacter | ComponentCharacter, // 0x34 4
+ QueryCharacter | UserInfoCharacter | IPv4Character | HexadecimalCharacter | DecimalCharacter | OctalCharacter | ComponentCharacter, // 0x35 5
+ QueryCharacter | UserInfoCharacter | IPv4Character | HexadecimalCharacter | DecimalCharacter | OctalCharacter | ComponentCharacter, // 0x36 6
+ QueryCharacter | UserInfoCharacter | IPv4Character | HexadecimalCharacter | DecimalCharacter | OctalCharacter | ComponentCharacter, // 0x37 7
+ QueryCharacter | UserInfoCharacter | IPv4Character | HexadecimalCharacter | DecimalCharacter | ComponentCharacter, // 0x38 8
+ QueryCharacter | UserInfoCharacter | IPv4Character | HexadecimalCharacter | DecimalCharacter | ComponentCharacter, // 0x39 9
QueryCharacter, // 0x3a :
QueryCharacter, // 0x3b ;
- InvalidCharacter, // 0x3c <
+ InvalidCharacter, // 0x3c < (Try to prevent certain types of XSS.)
QueryCharacter, // 0x3d =
- InvalidCharacter, // 0x3e >
+ InvalidCharacter, // 0x3e > (Try to prevent certain types of XSS.)
QueryCharacter, // 0x3f ?
QueryCharacter, // 0x40 @
- QueryCharacter | UserInfoCharacter | IPv4Character | HexCharacter, // 0x41 A
- QueryCharacter | UserInfoCharacter | IPv4Character | HexCharacter, // 0x42 B
- QueryCharacter | UserInfoCharacter | IPv4Character | HexCharacter, // 0x43 C
- QueryCharacter | UserInfoCharacter | IPv4Character | HexCharacter, // 0x44 D
- QueryCharacter | UserInfoCharacter | IPv4Character | HexCharacter, // 0x45 E
- QueryCharacter | UserInfoCharacter | IPv4Character | HexCharacter, // 0x46 F
- QueryCharacter | UserInfoCharacter, // 0x47 G
- QueryCharacter | UserInfoCharacter, // 0x48 H
- QueryCharacter | UserInfoCharacter, // 0x49 I
- QueryCharacter | UserInfoCharacter, // 0x4a J
- QueryCharacter | UserInfoCharacter, // 0x4b K
- QueryCharacter | UserInfoCharacter, // 0x4c L
- QueryCharacter | UserInfoCharacter, // 0x4d M
- QueryCharacter | UserInfoCharacter, // 0x4e N
- QueryCharacter | UserInfoCharacter, // 0x4f O
- QueryCharacter | UserInfoCharacter, // 0x50 P
- QueryCharacter | UserInfoCharacter, // 0x51 Q
- QueryCharacter | UserInfoCharacter, // 0x52 R
- QueryCharacter | UserInfoCharacter, // 0x53 S
- QueryCharacter | UserInfoCharacter, // 0x54 T
- QueryCharacter | UserInfoCharacter, // 0x55 U
- QueryCharacter | UserInfoCharacter, // 0x56 V
- QueryCharacter | UserInfoCharacter, // 0x57 W
- QueryCharacter | UserInfoCharacter | IPv4Character, // 0x58 X
- QueryCharacter | UserInfoCharacter, // 0x59 Y
- QueryCharacter | UserInfoCharacter, // 0x5a Z
+ QueryCharacter | UserInfoCharacter | IPv4Character | HexadecimalCharacter | ComponentCharacter, // 0x41 A
+ QueryCharacter | UserInfoCharacter | IPv4Character | HexadecimalCharacter | ComponentCharacter, // 0x42 B
+ QueryCharacter | UserInfoCharacter | IPv4Character | HexadecimalCharacter | ComponentCharacter, // 0x43 C
+ QueryCharacter | UserInfoCharacter | IPv4Character | HexadecimalCharacter | ComponentCharacter, // 0x44 D
+ QueryCharacter | UserInfoCharacter | IPv4Character | HexadecimalCharacter | ComponentCharacter, // 0x45 E
+ QueryCharacter | UserInfoCharacter | IPv4Character | HexadecimalCharacter | ComponentCharacter, // 0x46 F
+ QueryCharacter | UserInfoCharacter | ComponentCharacter, // 0x47 G
+ QueryCharacter | UserInfoCharacter | ComponentCharacter, // 0x48 H
+ QueryCharacter | UserInfoCharacter | ComponentCharacter, // 0x49 I
+ QueryCharacter | UserInfoCharacter | ComponentCharacter, // 0x4a J
+ QueryCharacter | UserInfoCharacter | ComponentCharacter, // 0x4b K
+ QueryCharacter | UserInfoCharacter | ComponentCharacter, // 0x4c L
+ QueryCharacter | UserInfoCharacter | ComponentCharacter, // 0x4d M
+ QueryCharacter | UserInfoCharacter | ComponentCharacter, // 0x4e N
+ QueryCharacter | UserInfoCharacter | ComponentCharacter, // 0x4f O
+ QueryCharacter | UserInfoCharacter | ComponentCharacter, // 0x50 P
+ QueryCharacter | UserInfoCharacter | ComponentCharacter, // 0x51 Q
+ QueryCharacter | UserInfoCharacter | ComponentCharacter, // 0x52 R
+ QueryCharacter | UserInfoCharacter | ComponentCharacter, // 0x53 S
+ QueryCharacter | UserInfoCharacter | ComponentCharacter, // 0x54 T
+ QueryCharacter | UserInfoCharacter | ComponentCharacter, // 0x55 U
+ QueryCharacter | UserInfoCharacter | ComponentCharacter, // 0x56 V
+ QueryCharacter | UserInfoCharacter | ComponentCharacter, // 0x57 W
+ QueryCharacter | UserInfoCharacter | IPv4Character | ComponentCharacter, // 0x58 X
+ QueryCharacter | UserInfoCharacter | ComponentCharacter, // 0x59 Y
+ QueryCharacter | UserInfoCharacter | ComponentCharacter, // 0x5a Z
QueryCharacter, // 0x5b [
QueryCharacter, // 0x5c '\'
QueryCharacter, // 0x5d ]
QueryCharacter, // 0x5e ^
- QueryCharacter | UserInfoCharacter, // 0x5f _
+ QueryCharacter | UserInfoCharacter | ComponentCharacter, // 0x5f _
QueryCharacter, // 0x60 `
- QueryCharacter | UserInfoCharacter | IPv4Character | HexCharacter, // 0x61 a
- QueryCharacter | UserInfoCharacter | IPv4Character | HexCharacter, // 0x62 b
- QueryCharacter | UserInfoCharacter | IPv4Character | HexCharacter, // 0x63 c
- QueryCharacter | UserInfoCharacter | IPv4Character | HexCharacter, // 0x64 d
- QueryCharacter | UserInfoCharacter | IPv4Character | HexCharacter, // 0x65 e
- QueryCharacter | UserInfoCharacter | IPv4Character | HexCharacter, // 0x66 f
- QueryCharacter | UserInfoCharacter, // 0x67 g
- QueryCharacter | UserInfoCharacter, // 0x68 h
- QueryCharacter | UserInfoCharacter, // 0x69 i
- QueryCharacter | UserInfoCharacter, // 0x6a j
- QueryCharacter | UserInfoCharacter, // 0x6b k
- QueryCharacter | UserInfoCharacter, // 0x6c l
- QueryCharacter | UserInfoCharacter, // 0x6d m
- QueryCharacter | UserInfoCharacter, // 0x6e n
- QueryCharacter | UserInfoCharacter, // 0x6f o
- QueryCharacter | UserInfoCharacter, // 0x70 p
- QueryCharacter | UserInfoCharacter, // 0x71 q
- QueryCharacter | UserInfoCharacter, // 0x72 r
- QueryCharacter | UserInfoCharacter, // 0x73 s
- QueryCharacter | UserInfoCharacter, // 0x74 t
- QueryCharacter | UserInfoCharacter, // 0x75 u
- QueryCharacter | UserInfoCharacter, // 0x76 v
- QueryCharacter | UserInfoCharacter, // 0x77 w
- QueryCharacter | UserInfoCharacter | IPv4Character, // 0x78 x
- QueryCharacter | UserInfoCharacter, // 0x79 y
- QueryCharacter | UserInfoCharacter, // 0x7a z
+ QueryCharacter | UserInfoCharacter | IPv4Character | HexadecimalCharacter | ComponentCharacter, // 0x61 a
+ QueryCharacter | UserInfoCharacter | IPv4Character | HexadecimalCharacter | ComponentCharacter, // 0x62 b
+ QueryCharacter | UserInfoCharacter | IPv4Character | HexadecimalCharacter | ComponentCharacter, // 0x63 c
+ QueryCharacter | UserInfoCharacter | IPv4Character | HexadecimalCharacter | ComponentCharacter, // 0x64 d
+ QueryCharacter | UserInfoCharacter | IPv4Character | HexadecimalCharacter | ComponentCharacter, // 0x65 e
+ QueryCharacter | UserInfoCharacter | IPv4Character | HexadecimalCharacter | ComponentCharacter, // 0x66 f
+ QueryCharacter | UserInfoCharacter | ComponentCharacter, // 0x67 g
+ QueryCharacter | UserInfoCharacter | ComponentCharacter, // 0x68 h
+ QueryCharacter | UserInfoCharacter | ComponentCharacter, // 0x69 i
+ QueryCharacter | UserInfoCharacter | ComponentCharacter, // 0x6a j
+ QueryCharacter | UserInfoCharacter | ComponentCharacter, // 0x6b k
+ QueryCharacter | UserInfoCharacter | ComponentCharacter, // 0x6c l
+ QueryCharacter | UserInfoCharacter | ComponentCharacter, // 0x6d m
+ QueryCharacter | UserInfoCharacter | ComponentCharacter, // 0x6e n
+ QueryCharacter | UserInfoCharacter | ComponentCharacter, // 0x6f o
+ QueryCharacter | UserInfoCharacter | ComponentCharacter, // 0x70 p
+ QueryCharacter | UserInfoCharacter | ComponentCharacter, // 0x71 q
+ QueryCharacter | UserInfoCharacter | ComponentCharacter, // 0x72 r
+ QueryCharacter | UserInfoCharacter | ComponentCharacter, // 0x73 s
+ QueryCharacter | UserInfoCharacter | ComponentCharacter, // 0x74 t
+ QueryCharacter | UserInfoCharacter | ComponentCharacter, // 0x75 u
+ QueryCharacter | UserInfoCharacter | ComponentCharacter, // 0x76 v
+ QueryCharacter | UserInfoCharacter | ComponentCharacter, // 0x77 w
+ QueryCharacter | UserInfoCharacter | IPv4Character | ComponentCharacter, // 0x78 x
+ QueryCharacter | UserInfoCharacter | ComponentCharacter, // 0x79 y
+ QueryCharacter | UserInfoCharacter | ComponentCharacter, // 0x7a z
QueryCharacter, // 0x7b {
QueryCharacter, // 0x7c |
QueryCharacter, // 0x7d }
- QueryCharacter | UserInfoCharacter, // 0x7e ~
+ QueryCharacter | UserInfoCharacter | ComponentCharacter, // 0x7e ~
InvalidCharacter, // 0x7f
InvalidCharacter, InvalidCharacter, InvalidCharacter, InvalidCharacter,
InvalidCharacter, InvalidCharacter, InvalidCharacter, InvalidCharacter,
diff --git a/Source/WTF/wtf/url/src/URLCharacterTypes.h b/Source/WTF/wtf/url/src/URLCharacterTypes.h
index 6edb98ca2..6652105e8 100644
--- a/Source/WTF/wtf/url/src/URLCharacterTypes.h
+++ b/Source/WTF/wtf/url/src/URLCharacterTypes.h
@@ -1,30 +1,32 @@
-// Copyright 2010, Google 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:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * 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.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND 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 THE COPYRIGHT
-// OWNER 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.
+/*
+ * Copyright 2010 Google 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:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * 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.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND 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 THE COPYRIGHT
+ * OWNER 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 URLCharacterTypes_h
#define URLCharacterTypes_h
@@ -35,27 +37,29 @@ namespace WTF {
class URLCharacterTypes {
public:
- static inline bool isQueryChar(unsigned char c) { return isCharOfType(c, QueryCharacter); }
- static inline bool isIPv4Char(unsigned char c) { return isCharOfType(c, IPv4Character); }
- static inline bool isHexChar(unsigned char c) { return isCharOfType(c, HexCharacter); }
-
-private:
- enum CharTypes {
+ enum CharacterTypes {
InvalidCharacter = 0,
QueryCharacter = 1 << 0,
UserInfoCharacter = 1 << 1,
IPv4Character = 1 << 2,
- HexCharacter = 1 << 3,
+ HexadecimalCharacter = 1 << 3,
DecimalCharacter = 1 << 4,
OctalCharacter = 1 << 5,
+ ComponentCharacter = 1 << 6,
};
- static const unsigned char characterTypeTable[0x100];
+ static inline bool isComponentChar(unsigned char character) { return isCharacterOfType(character, ComponentCharacter); }
+ static inline bool isHexChar(unsigned char character) { return isCharacterOfType(character, HexadecimalCharacter); }
+ static inline bool isIPv4Char(unsigned char character) { return isCharacterOfType(character, IPv4Character); }
+ static inline bool isQueryChar(unsigned char character) { return isCharacterOfType(character, QueryCharacter); }
- static inline bool isCharOfType(unsigned char c, CharTypes type)
+ static inline bool isCharacterOfType(unsigned char HexCharacter, CharacterTypes type)
{
- return !!(characterTypeTable[c] & type);
+ return !!(characterTypeTable[HexCharacter] & type);
}
+
+private:
+ static const unsigned char characterTypeTable[0x100];
};
}
diff --git a/Source/WTF/wtf/url/src/URLComponent.h b/Source/WTF/wtf/url/src/URLComponent.h
index 747a80b80..308cc0b5e 100644
--- a/Source/WTF/wtf/url/src/URLComponent.h
+++ b/Source/WTF/wtf/url/src/URLComponent.h
@@ -1,30 +1,32 @@
-// Copyright 2010, Google 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:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * 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.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND 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 THE COPYRIGHT
-// OWNER 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.
+/*
+ * Copyright 2010 Google 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:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * 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.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND 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 THE COPYRIGHT
+ * OWNER 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 URLComponent_h
#define URLComponent_h
diff --git a/Source/WTF/wtf/url/src/URLEscape.cpp b/Source/WTF/wtf/url/src/URLEscape.cpp
deleted file mode 100644
index 5acdcde24..000000000
--- a/Source/WTF/wtf/url/src/URLEscape.cpp
+++ /dev/null
@@ -1,43 +0,0 @@
-// Copyright 2010, Google 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:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * 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.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND 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 THE COPYRIGHT
-// OWNER 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 "URLEscape.h"
-
-#if USE(WTFURL)
-
-namespace WTF {
-
-const char hexCharacterTable[16] = {
- '0', '1', '2', '3', '4', '5', '6', '7',
- '8', '9', 'A', 'B', 'C', 'D', 'E', 'F',
-};
-
-}
-
-#endif // USE(WTFURL)
diff --git a/Source/WTF/wtf/url/src/URLEscape.h b/Source/WTF/wtf/url/src/URLEscape.h
deleted file mode 100644
index e010012a3..000000000
--- a/Source/WTF/wtf/url/src/URLEscape.h
+++ /dev/null
@@ -1,53 +0,0 @@
-// Copyright 2010, Google 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:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * 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.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND 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 THE COPYRIGHT
-// OWNER 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 URLEscape_h
-#define URLEscape_h
-
-#if USE(WTFURL)
-
-#include "URLBuffer.h"
-
-namespace WTF {
-
-extern const char hexCharacterTable[16];
-
-template<typename InChar, typename OutChar>
-inline void appendURLEscapedCharacter(InChar ch, URLBuffer<OutChar>& buffer)
-{
- buffer.append('%');
- buffer.append(hexCharacterTable[ch >> 4]);
- buffer.append(hexCharacterTable[ch & 0xf]);
-}
-
-}
-
-#endif // USE(WTFURL)
-
-#endif
diff --git a/Source/WTF/wtf/url/src/URLFile.h b/Source/WTF/wtf/url/src/URLFile.h
new file mode 100644
index 000000000..48b12ebdf
--- /dev/null
+++ b/Source/WTF/wtf/url/src/URLFile.h
@@ -0,0 +1,116 @@
+/*
+ * Copyright 2007 Google Inc. All rights reserved.
+ * Copyright 2012 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:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * 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.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND 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 THE COPYRIGHT
+ * OWNER 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.
+ */
+
+// Provides shared functions used by the internals of the parser and
+// canonicalizer for file URLs. Do not use outside of these modules.
+
+#ifndef URLFile_h
+#define URLFile_h
+
+#include "URLParseInternal.h"
+#include <wtf/unicode/Unicode.h>
+
+#if USE(WTFURL)
+
+namespace WTF {
+
+namespace URLParser {
+
+#if OS(WINDOWS)
+// We allow both "c:" and "c|" as drive identifiers.
+inline bool isWindowsDriveSeparator(UChar character)
+{
+ return character == ':' || character == '|';
+}
+inline bool isWindowsDriveLetter(UChar character)
+{
+ return (character >= 'A' && character <= 'Z') || (character >= 'a' && character <= 'z');
+}
+#endif // OS(WINDOWS)
+
+// Returns the index of the next slash in the input after the given index, or
+// specLength if the end of the input is reached.
+template<typename CharacterType>
+inline int findNextSlash(const CharacterType* spec, int beginIndex, int specLength)
+{
+ int idx = beginIndex;
+ while (idx < specLength && !isURLSlash(spec[idx]))
+ ++idx;
+ return idx;
+}
+
+#if OS(WINDOWS)
+// Returns true if the startOffset in the given spec looks like it begins a
+// drive spec, for example "c:". This function explicitly handles startOffset
+// values that are equal to or larger than the specLength to simplify callers.
+//
+// If this returns true, the spec is guaranteed to have a valid drive letter
+// plus a colon starting at |startOffset|.
+template<typename CharacterType>
+inline bool doesBeginWindowsDriveSpec(const CharacterType* spec, int startOffset, int specLength)
+{
+ int remainingLength = specLength - startOffset;
+ if (remainingLength < 2)
+ return false; // Not enough room.
+ if (!isWindowsDriveLetter(spec[startOffset]))
+ return false; // Doesn't start with a valid drive letter.
+ if (!isWindowsDriveSeparator(spec[startOffset + 1]))
+ return false; // Isn't followed with a drive separator.
+ return true;
+}
+
+// Returns true if the startOffset in the given text looks like it begins a
+// UNC path, for example "\\". This function explicitly handles startOffset
+// values that are equal to or larger than the specLength to simplify callers.
+//
+// When strictSlashes is set, this function will only accept backslashes as is
+// standard for Windows. Otherwise, it will accept forward slashes as well
+// which we use for a lot of URL handling.
+template<typename CharacterType>
+inline bool doesBeginUNCPath(const CharacterType* text, int startOffset, int length, bool strictSlashes)
+{
+ int remainingLength = length - startOffset;
+ if (remainingLength < 2)
+ return false;
+
+ if (strictSlashes)
+ return text[startOffset] == '\\' && text[startOffset + 1] == '\\';
+ return isURLSlash(text[startOffset]) && isURLSlash(text[startOffset + 1]);
+}
+#endif // OS(WINDOWS)
+
+} // namespace URLParser
+
+} // namespace WTF
+
+#endif // USE(WTFURL)
+
+#endif // URLFile_h
diff --git a/Source/WTF/wtf/url/src/URLParse.cpp b/Source/WTF/wtf/url/src/URLParse.cpp
new file mode 100644
index 000000000..1d7e42edd
--- /dev/null
+++ b/Source/WTF/wtf/url/src/URLParse.cpp
@@ -0,0 +1,787 @@
+/* Based on nsURLParsers.cc from Mozilla
+ * -------------------------------------
+ * Copyright (C) 1998 Netscape Communications Corporation.
+ * Copyright 2012, Google Inc. All rights reserved.
+ * Copyright (C) 2012 Apple Inc. All rights reserved.
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is mozilla.org code.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Darin Fisher (original author)
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ */
+
+#include "config.h"
+#include "URLParse.h"
+
+#include "URLParseInternal.h"
+#include "URLUtil.h"
+#include "URLUtilInternal.h"
+#include <stdlib.h>
+#include <wtf/ASCIICType.h>
+
+#if USE(WTFURL)
+
+namespace WTF {
+
+namespace URLParser {
+
+namespace {
+
+// Returns the offset of the next authority terminator in the input starting
+// from startOffset. If no terminator is found, the return value will be equal
+// to specLength.
+template<typename CharacterType>
+int findNextAuthorityTerminator(const CharacterType* spec, int startOffset, int specLength)
+{
+ for (int i = startOffset; i < specLength; i++) {
+ if (IsAuthorityTerminator(spec[i]))
+ return i;
+ }
+ return specLength; // Not found.
+}
+
+template<typename CharacterType>
+void parseUserInfo(const CharacterType* spec, const URLComponent& user, URLComponent& username, URLComponent& password)
+{
+ // Find the first colon in the user section, which separates the username and
+ // password.
+ int colonOffset = 0;
+ while (colonOffset < user.length() && spec[user.begin() + colonOffset] != ':')
+ ++colonOffset;
+
+ if (colonOffset < user.length()) {
+ // Found separator: <username>:<password>
+ username = URLComponent(user.begin(), colonOffset);
+ password = URLComponent::fromRange(user.begin() + colonOffset + 1, user.end());
+ } else {
+ // No separator, treat everything as the username
+ username = user;
+ password = URLComponent();
+ }
+}
+
+template<typename CharacterType>
+void parseServerInfo(const CharacterType* spec, const URLComponent& serverInfo, URLComponent& hostname, URLComponent& port)
+{
+ if (!serverInfo.length()) {
+ // No server info, host name is empty.
+ hostname = URLComponent();
+ port = URLComponent();
+ return;
+ }
+
+ // If the host starts with a left-bracket, assume the entire host is an
+ // IPv6 literal. Otherwise, assume none of the host is an IPv6 literal.
+ // This assumption will be overridden if we find a right-bracket.
+ //
+ // Our IPv6 address canonicalization code requires both brackets to exist,
+ // but the ability to locate an incomplete address can still be useful.
+ int ipv6Terminator = spec[serverInfo.begin()] == '[' ? serverInfo.end() : -1;
+ int colon = -1;
+
+ // Find the last right-bracket, and the last colon.
+ for (int i = serverInfo.begin(); i < serverInfo.end(); ++i) {
+ switch (spec[i]) {
+ case ']':
+ ipv6Terminator = i;
+ break;
+ case ':':
+ colon = i;
+ break;
+ }
+ }
+
+ if (colon > ipv6Terminator) {
+ // Found a port number: <hostname>:<port>
+ hostname = URLComponent::fromRange(serverInfo.begin(), colon);
+ if (!hostname.length())
+ hostname.reset();
+ port = URLComponent::fromRange(colon + 1, serverInfo.end());
+ } else {
+ // No port: <hostname>
+ hostname = serverInfo;
+ port = URLComponent();
+ }
+}
+
+// Given an already-identified auth section, breaks it into its consituent
+// parts. The port number will be parsed and the resulting integer will be
+// filled into the given *port variable, or -1 if there is no port number or it
+// is invalid.
+template<typename CharacterType>
+void doParseAuthority(const CharacterType* spec, const URLComponent& authority, URLComponent& username, URLComponent& password, URLComponent& hostname, URLComponent& port)
+{
+ ASSERT_WITH_MESSAGE(authority.isValid(), "We should always get an authority");
+ if (!authority.length()) {
+ username = URLComponent();
+ password = URLComponent();
+ hostname = URLComponent();
+ port = URLComponent();
+ return;
+ }
+
+ // Search backwards for @, which is the separator between the user info and
+ // the server info.
+ int i = authority.end() - 1;
+ while (i > authority.begin() && spec[i] != '@')
+ --i;
+
+ if (spec[i] == '@') {
+ // Found user info: <user-info>@<server-info>
+ parseUserInfo(spec, URLComponent(authority.begin(), i - authority.begin()), username, password);
+ parseServerInfo(spec, URLComponent::fromRange(i + 1, authority.end()), hostname, port);
+ } else {
+ // No user info, everything is server info.
+ username = URLComponent();
+ password = URLComponent();
+ parseServerInfo(spec, authority, hostname, port);
+ }
+}
+
+template<typename CharacterType>
+void parsePath(const CharacterType* spec, const URLComponent& hierarchicalidentifiers, URLComponent& resourcePath, URLComponent& query, URLComponent& fragment)
+{
+ // path = [/]<segment1>/<segment2>/<...>/<segmentN>;<param>?<query>#<ref>
+
+ // Special case when there is no path.
+ if (hierarchicalidentifiers.length() == -1) {
+ resourcePath = URLComponent();
+ query = URLComponent();
+ fragment = URLComponent();
+ return;
+ }
+ ASSERT_WITH_MESSAGE(hierarchicalidentifiers.length() > 0, "We should never have 0 length paths");
+
+ // Search for first occurrence of either ? or #.
+ int pathEnd = hierarchicalidentifiers.end();
+
+ int querySeparator = -1; // Index of the '?'
+ int fragmentSeparator = -1; // Index of the '#'
+ for (int i = hierarchicalidentifiers.begin(); i < pathEnd; ++i) {
+ switch (spec[i]) {
+ case '?':
+ // Only match the query string if it precedes the reference fragment
+ // and when we haven't found one already.
+ if (fragmentSeparator < 0 && querySeparator < 0)
+ querySeparator = i;
+ break;
+ case '#':
+ // Record the first # sign only.
+ if (fragmentSeparator < 0)
+ fragmentSeparator = i;
+ break;
+ }
+ }
+
+ // Markers pointing to the character after each of these corresponding
+ // components. The code below words from the end back to the beginning,
+ // and will update these indices as it finds components that exist.
+ int resourcePathEnd = -1;
+ int queryEnd = -1;
+
+ // Ref fragment: from the # to the end of the path.
+ if (fragmentSeparator >= 0) {
+ resourcePathEnd = queryEnd = fragmentSeparator;
+ fragment = URLComponent::fromRange(fragmentSeparator + 1, pathEnd);
+ } else {
+ resourcePathEnd = queryEnd = pathEnd;
+ fragment = URLComponent();
+ }
+
+ // Query fragment: everything from the ? to the next boundary (either the end
+ // of the path or the ref fragment).
+ if (querySeparator >= 0) {
+ resourcePathEnd = querySeparator;
+ query = URLComponent::fromRange(querySeparator + 1, queryEnd);
+ } else
+ query = URLComponent();
+
+ // File path: treat an empty file path as no file path.
+ if (resourcePathEnd != hierarchicalidentifiers.begin())
+ resourcePath = URLComponent::fromRange(hierarchicalidentifiers.begin(), resourcePathEnd);
+ else
+ resourcePath = URLComponent();
+}
+
+template<typename CharacterType>
+bool doExtractScheme(const CharacterType* url, int urlLength, URLComponent& scheme)
+{
+ // Skip leading whitespace and control characters.
+ int begin = 0;
+ while (begin < urlLength && shouldTrimFromURL(url[begin]))
+ ++begin;
+
+ if (begin == urlLength)
+ return false; // Input is empty or all whitespace.
+
+ // Find the first colon character.
+ for (int i = begin; i < urlLength; ++i) {
+ if (url[i] == ':') {
+ scheme = URLComponent::fromRange(begin, i);
+ return true;
+ }
+ }
+ return false; // No colon found: no scheme
+}
+
+// Fills in all members of the Parsed structure except for the scheme.
+//
+// |spec| is the full spec being parsed, of length |specLength|.
+// |afterScheme| is the character immediately following the scheme (after the
+// colon) where we'll begin parsing.
+//
+// Compatability data points. I list "host", "path" extracted:
+// Input IE6 Firefox Us
+// ----- -------------- -------------- --------------
+// http://foo.com/ "foo.com", "/" "foo.com", "/" "foo.com", "/"
+// http:foo.com/ "foo.com", "/" "foo.com", "/" "foo.com", "/"
+// http:/foo.com/ fail(*) "foo.com", "/" "foo.com", "/"
+// http:\foo.com/ fail(*) "\foo.com", "/"(fail) "foo.com", "/"
+// http:////foo.com/ "foo.com", "/" "foo.com", "/" "foo.com", "/"
+//
+// (*) Interestingly, although IE fails to load these URLs, its history
+// canonicalizer handles them, meaning if you've been to the corresponding
+// "http://foo.com/" link, it will be colored.
+template <typename CharacterType>
+void doParseAfterScheme(const CharacterType* spec, int specLength, int afterScheme, URLSegments& parsed)
+{
+ int slashesCount = countConsecutiveSlashes(spec, afterScheme, specLength);
+ int afterSlashes = afterScheme + slashesCount;
+
+ // First split into two main parts, the authority (username, password, host,
+ // and port) and the full path (path, query, and reference).
+ URLComponent authority;
+ URLComponent fullPath;
+
+ // Found "//<some data>", looks like an authority section. Treat everything
+ // from there to the next slash (or end of spec) to be the authority. Note
+ // that we ignore the number of slashes and treat it as the authority.
+ int endAuth = findNextAuthorityTerminator(spec, afterSlashes, specLength);
+ authority = URLComponent::fromRange(afterSlashes, endAuth);
+
+ if (endAuth == specLength) // No beginning of path found.
+ fullPath = URLComponent();
+ else // Everything starting from the slash to the end is the path.
+ fullPath = URLComponent::fromRange(endAuth, specLength);
+
+ // Now parse those two sub-parts.
+ doParseAuthority(spec, authority, parsed.username, parsed.password, parsed.host, parsed.port);
+ parsePath(spec, fullPath, parsed.path, parsed.query, parsed.fragment);
+}
+
+// The main parsing function for standard URLs. Standard URLs have a scheme,
+// host, path, etc.
+template<typename CharacterType>
+void doParseStandardURL(const CharacterType* spec, int specLength, URLSegments& parsed)
+{
+ ASSERT(specLength >= 0);
+
+ // Strip leading & trailing spaces and control characters.
+ int begin = 0;
+ trimURL(spec, begin, specLength);
+
+ int afterScheme = -1;
+ if (doExtractScheme(spec, specLength, parsed.scheme))
+ afterScheme = parsed.scheme.end() + 1; // Skip past the colon.
+ else {
+ // Say there's no scheme when there is no colon. We could also say that
+ // everything is the scheme. Both would produce an invalid URL, but this way
+ // seems less wrong in more cases.
+ parsed.scheme.reset();
+ afterScheme = begin;
+ }
+ doParseAfterScheme(spec, specLength, afterScheme, parsed);
+}
+
+template<typename CharacterType>
+void doParseFileSystemURL(const CharacterType* spec, int specLength, URLSegments& parsed)
+{
+ ASSERT(specLength >= 0);
+
+ // Get the unused parts of the URL out of the way.
+ parsed.username.reset();
+ parsed.password.reset();
+ parsed.host.reset();
+ parsed.port.reset();
+ parsed.path.reset(); // May use this; reset for convenience.
+ parsed.fragment.reset(); // May use this; reset for convenience.
+ parsed.query.reset(); // May use this; reset for convenience.
+ parsed.clearInnerURLSegments(); // May use this; reset for convenience.
+
+ // Strip leading & trailing spaces and control characters.
+ int begin = 0;
+ trimURL(spec, begin, specLength);
+
+ // Handle empty specs or ones that contain only whitespace or control chars.
+ if (begin == specLength) {
+ parsed.scheme.reset();
+ return;
+ }
+
+ int innerStart = -1;
+
+ // Extract the scheme. We also handle the case where there is no scheme.
+ if (doExtractScheme(&spec[begin], specLength - begin, parsed.scheme)) {
+ // Offset the results since we gave ExtractScheme a substring.
+ parsed.scheme.setBegin(parsed.scheme.begin() + begin);
+
+ if (parsed.scheme.end() == specLength - 1)
+ return;
+
+ innerStart = parsed.scheme.end() + 1;
+ } else {
+ // No scheme found; that's not valid for filesystem URLs.
+ parsed.scheme.reset();
+ return;
+ }
+
+ URLComponent innerScheme;
+ const CharacterType* innerSpec = &spec[innerStart];
+ int innerSpecLength = specLength - innerStart;
+
+ if (doExtractScheme(innerSpec, innerSpecLength, innerScheme)) {
+ // Offset the results since we gave ExtractScheme a substring.
+ innerScheme.setBegin(innerScheme.begin() + innerStart);
+
+ if (innerScheme.end() == specLength - 1)
+ return;
+ } else {
+ // No scheme found; that's not valid for filesystem URLs.
+ // The best we can do is return "filesystem://".
+ return;
+ }
+
+ URLSegments innerParsed;
+ if (URLUtilities::CompareSchemeComponent(spec, innerScheme, URLUtilities::kFileScheme)) {
+ // File URLs are special.
+ ParseFileURL(innerSpec, innerSpecLength, &innerParsed);
+ } else if (URLUtilities::CompareSchemeComponent(spec, innerScheme, URLUtilities::kFileSystemScheme)) {
+ // Filesystem URLs don't nest.
+ return;
+ } else if (URLUtilities::isStandard(spec, innerScheme)) {
+ // All "normal" URLs.
+ doParseStandardURL(innerSpec, innerSpecLength, innerParsed);
+ } else
+ return;
+
+ // All members of innerParsed need to be offset by innerStart.
+ // If we had any scheme that supported nesting more than one level deep,
+ // we'd have to recurse into the innerParsed's innerParsed when
+ // adjusting by innerStart.
+ innerParsed.scheme.setBegin(innerParsed.scheme.begin() + innerStart);
+ innerParsed.username.setBegin(innerParsed.username.begin() + innerStart);
+ innerParsed.password.setBegin(innerParsed.password.begin() + innerStart);
+ innerParsed.host.setBegin(innerParsed.host.begin() + innerStart);
+ innerParsed.port.setBegin(innerParsed.port.begin() + innerStart);
+ innerParsed.query.setBegin(innerParsed.query.begin() + innerStart);
+ innerParsed.fragment.setBegin(innerParsed.fragment.begin() + innerStart);
+ innerParsed.path.setBegin(innerParsed.path.begin() + innerStart);
+
+ // Query and ref move from innerParsed to parsed.
+ parsed.query = innerParsed.query;
+ innerParsed.query.reset();
+ parsed.fragment = innerParsed.fragment;
+ innerParsed.fragment.reset();
+
+ parsed.setInnerURLSegments(innerParsed);
+ if (!innerParsed.scheme.isValid() || !innerParsed.path.isValid() || innerParsed.innerURLSegments())
+ return;
+
+ // The path in innerParsed should start with a slash, then have a filesystem
+ // type followed by a slash. From the first slash up to but excluding the
+ // second should be what it keeps; the rest goes to parsed. If the path ends
+ // before the second slash, it's still pretty clear what the user meant, so
+ // we'll let that through.
+ if (!isURLSlash(spec[innerParsed.path.begin()]))
+ return;
+
+ int innerPathEnd = innerParsed.path.begin() + 1; // skip the leading slash
+ while (innerPathEnd < specLength && !isURLSlash(spec[innerPathEnd]))
+ ++innerPathEnd;
+ parsed.path.setBegin(innerPathEnd);
+ int newInnerPathLength = innerPathEnd - innerParsed.path.begin();
+ parsed.path.setLength(innerParsed.path.length() - newInnerPathLength);
+ innerParsed.path.setLength(newInnerPathLength);
+ parsed.setInnerURLSegments(innerParsed);
+}
+
+// Initializes a path URL which is merely a scheme followed by a path. Examples
+// include "about:foo" and "javascript:alert('bar');"
+template<typename CharacterType>
+void doParsePathURL(const CharacterType* spec, int specLength, URLSegments& parsed)
+{
+ // Get the non-path and non-scheme parts of the URL out of the way, we never
+ // use them.
+ parsed.username.reset();
+ parsed.password.reset();
+ parsed.host.reset();
+ parsed.port.reset();
+ parsed.query.reset();
+ parsed.fragment.reset();
+
+ // Strip leading & trailing spaces and control characters.
+ int begin = 0;
+ trimURL(spec, begin, specLength);
+
+ // Handle empty specs or ones that contain only whitespace or control chars.
+ if (begin == specLength) {
+ parsed.scheme.reset();
+ parsed.path.reset();
+ return;
+ }
+
+ // Extract the scheme, with the path being everything following. We also
+ // handle the case where there is no scheme.
+ if (ExtractScheme(&spec[begin], specLength - begin, &parsed.scheme)) {
+ // Offset the results since we gave ExtractScheme a substring.
+ parsed.scheme.setBegin(parsed.scheme.begin() + begin);
+
+ // For compatability with the standard URL parser, we treat no path as
+ // -1, rather than having a length of 0 (we normally wouldn't care so
+ // much for these non-standard URLs).
+ if (parsed.scheme.end() == specLength - 1)
+ parsed.path.reset();
+ else
+ parsed.path = URLComponent::fromRange(parsed.scheme.end() + 1, specLength);
+ } else {
+ // No scheme found, just path.
+ parsed.scheme.reset();
+ parsed.path = URLComponent::fromRange(begin, specLength);
+ }
+}
+
+template<typename CharacterType>
+void doParseMailtoURL(const CharacterType* spec, int specLength, URLSegments& parsed)
+{
+ ASSERT(specLength >= 0);
+
+ // Get the non-path and non-scheme parts of the URL out of the way, we never
+ // use them.
+ parsed.username.reset();
+ parsed.password.reset();
+ parsed.host.reset();
+ parsed.port.reset();
+ parsed.fragment.reset();
+ parsed.query.reset(); // May use this; reset for convenience.
+
+ // Strip leading & trailing spaces and control characters.
+ int begin = 0;
+ trimURL(spec, begin, specLength);
+
+ // Handle empty specs or ones that contain only whitespace or control chars.
+ if (begin == specLength) {
+ parsed.scheme.reset();
+ parsed.path.reset();
+ return;
+ }
+
+ int pathBegin = -1;
+ int pathEnd = -1;
+
+ // Extract the scheme, with the path being everything following. We also
+ // handle the case where there is no scheme.
+ if (ExtractScheme(&spec[begin], specLength - begin, &parsed.scheme)) {
+ // Offset the results since we gave ExtractScheme a substring.
+ parsed.scheme.setBegin(parsed.scheme.begin() + begin);
+
+ if (parsed.scheme.end() != specLength - 1) {
+ pathBegin = parsed.scheme.end() + 1;
+ pathEnd = specLength;
+ }
+ } else {
+ // No scheme found, just path.
+ parsed.scheme.reset();
+ pathBegin = begin;
+ pathEnd = specLength;
+ }
+
+ // Split [pathBegin, pathEnd) into a path + query.
+ for (int i = pathBegin; i < pathEnd; ++i) {
+ if (spec[i] == '?') {
+ parsed.query = URLComponent::fromRange(i + 1, pathEnd);
+ pathEnd = i;
+ break;
+ }
+ }
+
+ // For compatability with the standard URL parser, treat no path as
+ // -1, rather than having a length of 0
+ if (pathBegin == pathEnd)
+ parsed.path.reset();
+ else
+ parsed.path = URLComponent::fromRange(pathBegin, pathEnd);
+}
+
+// Converts a port number in a string to an integer. We'd like to just call
+// sscanf but our input is not null-terminated, which sscanf requires. Instead,
+// we copy the digits to a small stack buffer (since we know the maximum number
+// of digits in a valid port number) that we can null terminate.
+template<typename CharacterType>
+int doParsePort(const CharacterType* spec, const URLComponent& component)
+{
+ // Easy success case when there is no port.
+ const int kMaxDigits = 5;
+ if (!component.isNonEmpty())
+ return PORT_UNSPECIFIED;
+
+ // Skip over any leading 0s.
+ URLComponent digitComponent(component.end(), 0);
+ for (int i = 0; i < component.length(); i++) {
+ if (spec[component.begin() + i] != '0') {
+ digitComponent = URLComponent::fromRange(component.begin() + i, component.end());
+ break;
+ }
+ }
+ if (!digitComponent.length())
+ return 0; // All digits were 0.
+
+ // Verify we don't have too many digits (we'll be copying to our buffer so
+ // we need to double-check).
+ if (digitComponent.length() > kMaxDigits)
+ return PORT_INVALID;
+
+ // Copy valid digits to the buffer.
+ char digits[kMaxDigits + 1]; // +1 for null terminator
+ for (int i = 0; i < digitComponent.length(); i++) {
+ CharacterType ch = spec[digitComponent.begin() + i];
+ if (!isASCIIDigit(ch)) {
+ // Invalid port digit, fail.
+ return PORT_INVALID;
+ }
+ digits[i] = static_cast<char>(ch);
+ }
+
+ // Null-terminate the string and convert to integer. Since we guarantee
+ // only digits, atoi's lack of error handling is OK.
+ digits[digitComponent.length()] = 0;
+ int port = atoi(digits);
+ if (port > 65535)
+ return PORT_INVALID; // Out of range.
+ return port;
+}
+
+template<typename CharacterType>
+void doExtractFileName(const CharacterType* spec, const URLComponent& path, URLComponent& fileName)
+{
+ // Handle empty paths: they have no file names.
+ if (!path.isNonEmpty()) {
+ fileName = URLComponent();
+ return;
+ }
+
+ // Search backwards for a parameter, which is a normally unused field in a
+ // URL delimited by a semicolon. We parse the parameter as part of the
+ // path, but here, we don't want to count it. The last semicolon is the
+ // parameter. The path should start with a slash, so we don't need to check
+ // the first one.
+ int fileEnd = path.end();
+ for (int i = path.end() - 1; i > path.begin(); --i) {
+ if (spec[i] == ';') {
+ fileEnd = i;
+ break;
+ }
+ }
+
+ // Now search backwards from the filename end to the previous slash
+ // to find the beginning of the filename.
+ for (int i = fileEnd - 1; i >= path.begin(); --i) {
+ if (isURLSlash(spec[i])) {
+ // File name is everything following this character to the end
+ fileName = URLComponent::fromRange(i + 1, fileEnd);
+ return;
+ }
+ }
+
+ // No slash found, this means the input was degenerate (generally paths
+ // will start with a slash). Let's call everything the file name.
+ fileName = URLComponent::fromRange(path.begin(), fileEnd);
+ return;
+}
+
+template<typename CharacterType>
+bool doExtractQueryKeyValue(const CharacterType* spec, URLComponent& query, URLComponent& key, URLComponent& value)
+{
+ if (!query.isNonEmpty())
+ return false;
+
+ int start = query.begin();
+ int current = start;
+ int end = query.end();
+
+ // We assume the beginning of the input is the beginning of the "key" and we
+ // skip to the end of it.
+ key.setBegin(current);
+ while (current < end && spec[current] != '&' && spec[current] != '=')
+ ++current;
+ key.setLength(current - key.begin());
+
+ // Skip the separator after the key (if any).
+ if (current < end && spec[current] == '=')
+ ++current;
+
+ // Find the value part.
+ value.setBegin(current);
+ while (current < end && spec[current] != '&')
+ ++current;
+ value.setLength(current - value.begin());
+
+ // Finally skip the next separator if any
+ if (current < end && spec[current] == '&')
+ ++current;
+
+ // Save the new query
+ query = URLComponent::fromRange(current, end);
+ return true;
+}
+
+} // namespace
+
+bool ExtractScheme(const char* url, int urlLength, URLComponent* scheme)
+{
+ return doExtractScheme(url, urlLength, *scheme);
+}
+
+bool ExtractScheme(const UChar* url, int urlLength, URLComponent* scheme)
+{
+ return doExtractScheme(url, urlLength, *scheme);
+}
+
+// This handles everything that may be an authority terminator, including
+// backslash. For special backslash handling see DoParseAfterScheme.
+bool IsAuthorityTerminator(UChar character)
+{
+ return isURLSlash(character) || character == '?' || character == '#';
+}
+
+void ExtractFileName(const char* url, const URLComponent& path, URLComponent* fileName)
+{
+ doExtractFileName(url, path, *fileName);
+}
+
+void ExtractFileName(const UChar* url, const URLComponent& path, URLComponent* fileName)
+{
+ doExtractFileName(url, path, *fileName);
+}
+
+bool ExtractQueryKeyValue(const char* url, URLComponent* query, URLComponent* key, URLComponent* value)
+{
+ return doExtractQueryKeyValue(url, *query, *key, *value);
+}
+
+bool ExtractQueryKeyValue(const UChar* url, URLComponent* query, URLComponent* key, URLComponent* value)
+{
+ return doExtractQueryKeyValue(url, *query, *key, *value);
+}
+
+void ParseAuthority(const char* spec, const URLComponent& auth, URLComponent* username, URLComponent* password, URLComponent* hostname, URLComponent* portNumber)
+{
+ doParseAuthority(spec, auth, *username, *password, *hostname, *portNumber);
+}
+
+void ParseAuthority(const UChar* spec, const URLComponent& auth, URLComponent* username, URLComponent* password, URLComponent* hostname, URLComponent* portNumber)
+{
+ doParseAuthority(spec, auth, *username, *password, *hostname, *portNumber);
+}
+
+int ParsePort(const char* url, const URLComponent& port)
+{
+ return doParsePort(url, port);
+}
+
+int ParsePort(const UChar* url, const URLComponent& port)
+{
+ return doParsePort(url, port);
+}
+
+void ParseStandardURL(const char* url, int urlLength, URLSegments* parsed)
+{
+ doParseStandardURL(url, urlLength, *parsed);
+}
+
+void ParseStandardURL(const UChar* url, int urlLength, URLSegments* parsed)
+{
+ doParseStandardURL(url, urlLength, *parsed);
+}
+
+void ParsePathURL(const char* url, int urlLength, URLSegments* parsed)
+{
+ doParsePathURL(url, urlLength, *parsed);
+}
+
+void ParsePathURL(const UChar* url, int urlLength, URLSegments* parsed)
+{
+ doParsePathURL(url, urlLength, *parsed);
+}
+
+void ParseFileSystemURL(const char* url, int urlLength, URLSegments* parsed)
+{
+ doParseFileSystemURL(url, urlLength, *parsed);
+}
+
+void ParseFileSystemURL(const UChar* url, int urlLength, URLSegments* parsed)
+{
+ doParseFileSystemURL(url, urlLength, *parsed);
+}
+
+void ParseMailtoURL(const char* url, int urlLength, URLSegments* parsed)
+{
+ doParseMailtoURL(url, urlLength, *parsed);
+}
+
+void ParseMailtoURL(const UChar* url, int urlLength, URLSegments* parsed)
+{
+ doParseMailtoURL(url, urlLength, *parsed);
+}
+
+void parsePathInternal(const char* spec, const URLComponent& path, URLComponent* filepath, URLComponent* query, URLComponent* fragment)
+{
+ parsePath(spec, path, *filepath, *query, *fragment);
+}
+
+void parsePathInternal(const UChar* spec, const URLComponent& path, URLComponent* filepath, URLComponent* query, URLComponent* fragment)
+{
+ parsePath(spec, path, *filepath, *query, *fragment);
+}
+
+void parseAfterScheme(const char* spec, int specLength, int afterScheme, URLSegments& parsed)
+{
+ doParseAfterScheme(spec, specLength, afterScheme, parsed);
+}
+
+void parseAfterScheme(const UChar* spec, int specLength, int afterScheme, URLSegments& parsed)
+{
+ doParseAfterScheme(spec, specLength, afterScheme, parsed);
+}
+
+} // namespace URLParser
+
+} // namespace WTF
+
+#endif // USE(WTFURL)
diff --git a/Source/WTF/wtf/url/src/URLParse.h b/Source/WTF/wtf/url/src/URLParse.h
new file mode 100644
index 000000000..c97b10a91
--- /dev/null
+++ b/Source/WTF/wtf/url/src/URLParse.h
@@ -0,0 +1,167 @@
+/*
+ * Copyright 2007 Google Inc. All rights reserved.
+ * Copyright 2012 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:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * 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.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND 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 THE COPYRIGHT
+ * OWNER 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 URLParse_h
+#define URLParse_h
+
+#include "URLComponent.h"
+#include "URLSegments.h"
+#include <wtf/unicode/Unicode.h>
+
+#if USE(WTFURL)
+
+namespace WTF {
+
+namespace URLParser {
+
+// Initialization functions ---------------------------------------------------
+//
+// These functions parse the given URL, filling in all of the structure's
+// components. These functions can not fail, they will always do their best
+// at interpreting the input given.
+//
+// The string length of the URL MUST be specified, we do not check for NULLs
+// at any point in the process, and will actually handle embedded NULLs.
+//
+// IMPORTANT: These functions do NOT hang on to the given pointer or copy it
+// in any way. See the comment above the struct.
+//
+// The 8-bit versions require UTF-8 encoding.
+
+// StandardURL is for when the scheme is known to be one that has an
+// authority (host) like "http". This function will not handle weird ones
+// like "about:" and "javascript:", or do the right thing for "file:" URLs.
+void ParseStandardURL(const char* url, int urlLength, URLSegments* parsed);
+void ParseStandardURL(const UChar* url, int urlLength, URLSegments* parsed);
+
+// PathURL is for when the scheme is known not to have an authority (host)
+// section but that aren't file URLs either. The scheme is parsed, and
+// everything after the scheme is considered as the path. This is used for
+// things like "about:" and "javascript:"
+void ParsePathURL(const char* url, int urlLength, URLSegments* parsed);
+void ParsePathURL(const UChar* url, int urlLength, URLSegments* parsed);
+
+// FileURL is for file URLs. There are some special rules for interpreting
+// these.
+void ParseFileURL(const char* url, int urlLength, URLSegments* parsed);
+void ParseFileURL(const UChar* url, int urlLength, URLSegments* parsed);
+
+// Filesystem URLs are structured differently than other URLs.
+void ParseFileSystemURL(const char* url, int urlLength, URLSegments* parsed);
+void ParseFileSystemURL(const UChar* url, int urlLength, URLSegments* parsed);
+
+// MailtoURL is for mailto: urls. They are made up scheme,path,query
+void ParseMailtoURL(const char* url, int urlLength, URLSegments* parsed);
+void ParseMailtoURL(const UChar* url, int urlLength, URLSegments* parsed);
+
+// Helper functions -----------------------------------------------------------
+
+// Locates the scheme according to the URL parser's rules. This function is
+// designed so the caller can find the scheme and call the correct Init*
+// function according to their known scheme types.
+//
+// It also does not perform any validation on the scheme.
+//
+// This function will return true if the scheme is found and will put the
+// scheme's range into *scheme. False means no scheme could be found. Note
+// that a URL beginning with a colon has a scheme, but it is empty, so this
+// function will return true but *scheme will = (0,0).
+//
+// The scheme is found by skipping spaces and control characters at the
+// beginning, and taking everything from there to the first colon to be the
+// scheme. The character at scheme.end() will be the colon (we may enhance
+// this to handle full width colons or something, so don't count on the
+// actual character value). The character at scheme.end()+1 will be the
+// beginning of the rest of the URL, be it the authority or the path (or the
+// end of the string).
+//
+// The 8-bit version requires UTF-8 encoding.
+bool ExtractScheme(const char* url, int urlLength, URLComponent* scheme);
+bool ExtractScheme(const UChar* url, int urlLength, URLComponent* scheme);
+
+// Returns true if ch is a character that terminates the authority segment of a URL.
+bool IsAuthorityTerminator(UChar);
+
+// Does a best effort parse of input |spec|, in range |auth|. If a particular
+// component is not found, it will be set to invalid.
+void ParseAuthority(const char* spec, const URLComponent& auth,
+ URLComponent* username, URLComponent* password, URLComponent* hostname, URLComponent* portNumber);
+void ParseAuthority(const UChar* spec, const URLComponent& auth,
+ URLComponent* username, URLComponent* password, URLComponent* hostname, URLComponent* portNumber);
+
+// Computes the integer port value from the given port component. The port
+// component should have been identified by one of the init functions on
+// |Parsed| for the given input url.
+//
+// The return value will be a positive integer between 0 and 64K, or one of
+// the two special values below.
+enum SpecialPort { PORT_UNSPECIFIED = -1, PORT_INVALID = -2 };
+int ParsePort(const char* url, const URLComponent& port);
+int ParsePort(const UChar* url, const URLComponent& port);
+
+// Extracts the range of the file name in the given url. The path must
+// already have been computed by the parse function, and the matching URL
+// and extracted path are provided to this function. The filename is
+// defined as being everything from the last slash/backslash of the path
+// to the end of the path.
+//
+// The file name will be empty if the path is empty or there is nothing
+// following the last slash.
+//
+// The 8-bit version requires UTF-8 encoding.
+void ExtractFileName(const char* url, const URLComponent& path, URLComponent* fileName);
+void ExtractFileName(const UChar* url, const URLComponent& path, URLComponent* fileName);
+
+// Extract the first key/value from the range defined by |*query|. Updates
+// |*query| to start at the end of the extracted key/value pair. This is
+// designed for use in a loop: you can keep calling it with the same query
+// object and it will iterate over all items in the query.
+//
+// Some key/value pairs may have the key, the value, or both be empty (for
+// example, the query string "?&"). These will be returned. Note that an empty
+// last parameter "foo.com?" or foo.com?a&" will not be returned, this case
+// is the same as "done."
+//
+// The initial query component should not include the '?' (this is the default
+// for parsed URLs).
+//
+// If no key/value are found |*key| and |*value| will be unchanged and it will
+// return false.
+bool ExtractQueryKeyValue(const char* url, URLComponent* query, URLComponent* key, URLComponent* value);
+bool ExtractQueryKeyValue(const UChar* url, URLComponent* query, URLComponent* key, URLComponent* value);
+
+} // namespace URLParser
+
+} // namespace WTF
+
+#endif // USE(WTFURL)
+
+#endif // URLParse_h
diff --git a/Source/WTF/wtf/url/src/URLParseFile.cpp b/Source/WTF/wtf/url/src/URLParseFile.cpp
new file mode 100644
index 000000000..455ef5559
--- /dev/null
+++ b/Source/WTF/wtf/url/src/URLParseFile.cpp
@@ -0,0 +1,251 @@
+/*
+ * Copyright 2007 Google Inc. All rights reserved.
+ * Copyright 2012 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:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * 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.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND 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 THE COPYRIGHT
+ * OWNER 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 "URLParse.h"
+
+#include "URLFile.h"
+#include "URLParseInternal.h"
+
+// Interesting IE file:isms...
+//
+// INPUT OUTPUT
+// ========================= ==============================
+// file:/foo/bar file:///foo/bar
+// The result here seems totally invalid!?!? This isn't UNC.
+//
+// file:/
+// file:// or any other number of slashes
+// IE6 doesn't do anything at all if you click on this link. No error:
+// nothing. IE6's history system seems to always color this link, so I'm
+// guessing that it maps internally to the empty URL.
+//
+// C:\ file:///C:/
+// When on a file: URL source page, this link will work. When over HTTP,
+// the file: URL will appear in the status bar but the link will not work
+// (security restriction for all file URLs).
+//
+// file:foo/ file:foo/ (invalid?!?!?)
+// file:/foo/ file:///foo/ (invalid?!?!?)
+// file://foo/ file://foo/ (UNC to server "foo")
+// file:///foo/ file:///foo/ (invalid, seems to be a file)
+// file:////foo/ file://foo/ (UNC to server "foo")
+// Any more than four slashes is also treated as UNC.
+//
+// file:C:/ file://C:/
+// file:/C:/ file://C:/
+// The number of slashes after "file:" don't matter if the thing following
+// it looks like an absolute drive path. Also, slashes and backslashes are
+// equally valid here.
+
+#if USE(WTFURL)
+
+namespace WTF {
+
+namespace URLParser {
+
+namespace {
+
+// A subcomponent of DoInitFileURL, the input of this function should be a UNC
+// path name, with the index of the first character after the slashes following
+// the scheme given in |afterSlashes|. This will initialize the host, path,
+// query, and ref, and leave the other output components untouched
+// (DoInitFileURL handles these for us).
+template<typename CharacterType>
+void doParseUNC(const CharacterType* spec, int afterSlashes, int specLength, URLSegments& parsed)
+{
+ int nextSlash = findNextSlash(spec, afterSlashes, specLength);
+ if (nextSlash == specLength) {
+ // No additional slash found, as in "file://foo", treat the text as the
+ // host with no path (this will end up being UNC to server "foo").
+ int hostLength = specLength - afterSlashes;
+ if (hostLength)
+ parsed.host = URLComponent(afterSlashes, hostLength);
+ else
+ parsed.host.reset();
+ parsed.path.reset();
+ return;
+ }
+
+#if OS(WINDOWS)
+ // See if we have something that looks like a path following the first
+ // component. As in "file://localhost/c:/", we get "c:/" out. We want to
+ // treat this as a having no host but the path given. Works on Windows only.
+ if (doesBeginWindowsDriveSpec(spec, nextSlash + 1, specLength)) {
+ parsed.host.reset();
+ parsePathInternal(spec, MakeRange(nextSlash, specLength),
+ &parsed.path, &parsed.query, &parsed.ref);
+ return;
+ }
+#endif
+
+ // Otherwise, everything up until that first slash we found is the host name,
+ // which will end up being the UNC host. For example "file://foo/bar.txt"
+ // will get a server name of "foo" and a path of "/bar". Later, on Windows,
+ // this should be treated as the filename "\\foo\bar.txt" in proper UNC
+ // notation.
+ int hostLength = nextSlash - afterSlashes;
+ if (hostLength)
+ parsed.host = URLComponent::fromRange(afterSlashes, nextSlash);
+ else
+ parsed.host.reset();
+ if (nextSlash < specLength) {
+ parsePathInternal(spec, URLComponent::fromRange(nextSlash, specLength),
+ &parsed.path, &parsed.query, &parsed.fragment);
+ } else
+ parsed.path.reset();
+}
+
+// A subcomponent of DoParseFileURL, the input should be a local file, with the
+// beginning of the path indicated by the index in |pathBegin|. This will
+// initialize the host, path, query, and ref, and leave the other output
+// components untouched (DoInitFileURL handles these for us).
+template<typename CharacterType>
+void doParseLocalFile(const CharacterType* spec, int pathBegin, int specLength, URLSegments& parsed)
+{
+ parsed.host.reset();
+ parsePathInternal(spec, URLComponent::fromRange(pathBegin, specLength),
+ &parsed.path, &parsed.query, &parsed.fragment);
+}
+
+// Backend for the external functions that operates on either char type.
+// We are handed the character after the "file:" at the beginning of the spec.
+// Usually this is a slash, but needn't be; we allow paths like "file:c:\foo".
+template<typename CharacterType>
+void doParseFileURL(const CharacterType* spec, int specLength, URLSegments& parsed)
+{
+ ASSERT(specLength >= 0);
+
+ // Get the parts we never use for file URLs out of the way.
+ parsed.username.reset();
+ parsed.password.reset();
+ parsed.port.reset();
+
+ // Many of the code paths don't set these, so it's convenient to just clear
+ // them. We'll write them in those cases we need them.
+ parsed.query.reset();
+ parsed.fragment.reset();
+
+ // Strip leading & trailing spaces and control characters.
+ int begin = 0;
+ trimURL(spec, begin, specLength);
+
+ // Find the scheme.
+ int numSlashes;
+ int afterScheme;
+ int afterSlashes;
+#if OS(WINDOWS)
+ // See how many slashes there are. We want to handle cases like UNC but also
+ // "/c:/foo". This is when there is no scheme, so we can allow pages to do
+ // links like "c:/foo/bar" or "//foo/bar". This is also called by the
+ // relative URL resolver when it determines there is an absolute URL, which
+ // may give us input like "/c:/foo".
+ numSlashes = countConsecutiveSlashes(spec, begin, specLength);
+ afterSlashes = begin + numSlashes;
+ if (doesBeginWindowsDriveSpec(spec, afterSlashes, specLength)) {
+ // Windows path, don't try to extract the scheme (for example, "c:\foo").
+ parsed.scheme.reset();
+ afterScheme = afterSlashes;
+ } else if (doesBeginUNCPath(spec, begin, specLength, false)) {
+ // Windows UNC path: don't try to extract the scheme, but keep the slashes.
+ parsed.scheme.reset();
+ afterScheme = begin;
+ } else
+#endif
+ {
+ if (ExtractScheme(&spec[begin], specLength - begin, &parsed.scheme)) {
+ // Offset the results since we gave ExtractScheme a substring.
+ parsed.scheme.setBegin(parsed.scheme.begin() + begin);
+ afterScheme = parsed.scheme.end() + 1;
+ } else {
+ // No scheme found, remember that.
+ parsed.scheme.reset();
+ afterScheme = begin;
+ }
+ }
+
+ // Handle empty specs ones that contain only whitespace or control chars,
+ // or that are just the scheme (for example "file:").
+ if (afterScheme == specLength) {
+ parsed.host.reset();
+ parsed.path.reset();
+ return;
+ }
+
+ numSlashes = countConsecutiveSlashes(spec, afterScheme, specLength);
+
+ afterSlashes = afterScheme + numSlashes;
+#if OS(WINDOWS)
+ // Check whether the input is a drive again. We checked above for windows
+ // drive specs, but that's only at the very beginning to see if we have a
+ // scheme at all. This test will be duplicated in that case, but will
+ // additionally handle all cases with a real scheme such as "file:///C:/".
+ if (!doesBeginWindowsDriveSpec(spec, afterSlashes, specLength) && numSlashes != 3) {
+ // Anything not beginning with a drive spec ("c:\") on Windows is treated
+ // as UNC, with the exception of three slashes which always means a file.
+ // Even IE7 treats file:///foo/bar as "/foo/bar", which then fails.
+ doParseUNC(spec, afterSlashes, specLength, parsed);
+ return;
+ }
+#else
+ // file: URL with exactly 2 slashes is considered to have a host component.
+ if (numSlashes == 2) {
+ doParseUNC(spec, afterSlashes, specLength, parsed);
+ return;
+ }
+#endif // OS(WINDOWS)
+
+ // Easy and common case, the full path immediately follows the scheme
+ // (modulo slashes), as in "file://c:/foo". Just treat everything from
+ // there to the end as the path. Empty hosts have 0 length instead of -1.
+ // We include the last slash as part of the path if there is one.
+ doParseLocalFile(spec,
+ numSlashes > 0 ? afterScheme + numSlashes - 1 : afterScheme,
+ specLength, parsed);
+}
+
+} // namespace
+
+void ParseFileURL(const char* url, int urlLength, URLSegments* parsed)
+{
+ doParseFileURL(url, urlLength, *parsed);
+}
+
+void ParseFileURL(const UChar* url, int urlLength, URLSegments* parsed)
+{
+ doParseFileURL(url, urlLength, *parsed);
+}
+
+} // namespace URLParser
+
+} // namespace WTF
+
+#endif // USE(WTFURL)
diff --git a/Source/WTF/wtf/url/src/URLParseInternal.h b/Source/WTF/wtf/url/src/URLParseInternal.h
new file mode 100644
index 000000000..de27aedd0
--- /dev/null
+++ b/Source/WTF/wtf/url/src/URLParseInternal.h
@@ -0,0 +1,119 @@
+/*
+ * Copyright 2007 Google Inc. All rights reserved.
+ * Copyright 2012 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:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * 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.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND 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 THE COPYRIGHT
+ * OWNER 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.
+ */
+
+// Contains common inline helper functions used by the URL parsing routines.
+
+#ifndef URLParseInternal_h
+#define URLParseInternal_h
+
+#include "URLParse.h"
+#include <wtf/unicode/Unicode.h>
+
+#if USE(WTFURL)
+
+namespace WTF {
+
+namespace URLParser {
+
+// We treat slashes and backslashes the same for IE compatability.
+inline bool isURLSlash(UChar ch)
+{
+ return ch == '/' || ch == '\\';
+}
+
+// Returns true if we should trim this character from the URL because it is a
+// space or a control character.
+inline bool shouldTrimFromURL(UChar ch)
+{
+ return ch <= ' ';
+}
+
+// Given an already-initialized begin index and length, this shrinks the range
+// to eliminate "should-be-trimmed" characters. Note that the length does *not*
+// indicate the length of untrimmed data from |*begin|, but rather the position
+// in the input string (so the string starts at character |*begin| in the spec,
+// and goes until |*len|).
+template<typename CharacterType>
+inline void trimURL(const CharacterType* spec, int& begin, int& length)
+{
+ // Strip leading whitespace and control characters.
+ while (begin < length && shouldTrimFromURL(spec[begin]))
+ ++begin;
+
+ // Strip trailing whitespace and control characters. We need the >i test for
+ // when the input string is all blanks; we don't want to back past the input.
+ while (length > begin && shouldTrimFromURL(spec[length - 1]))
+ --length;
+}
+
+// Counts the number of consecutive slashes starting at the given offset
+// in the given string of the given length.
+template<typename CharacterType>
+inline int countConsecutiveSlashes(const CharacterType *str, int begin_offset, int strLength)
+{
+ int count = 0;
+ while (begin_offset + count < strLength && isURLSlash(str[begin_offset + count]))
+ ++count;
+ return count;
+}
+
+// Internal functions in URLParser.cc that parse the path, that is, everything
+// following the authority section. The input is the range of everything
+// following the authority section, and the output is the identified ranges.
+//
+// This is designed for the file URL parser or other consumers who may do
+// special stuff at the beginning, but want regular path parsing, it just
+// maps to the internal parsing function for paths.
+void parsePathInternal(const char* spec,
+ const URLComponent& path,
+ URLComponent* filepath,
+ URLComponent* query,
+ URLComponent* fragment);
+void parsePathInternal(const UChar* spec,
+ const URLComponent& path,
+ URLComponent* filepath,
+ URLComponent* query,
+ URLComponent* fragment);
+
+
+// Given a spec and a pointer to the character after the colon following the
+// scheme, this parses it and fills in the structure, Every item in the parsed
+// structure is filled EXCEPT for the scheme, which is untouched.
+void parseAfterScheme(const char* spec, int specLength, int afterScheme, URLSegments& parsed);
+void parseAfterScheme(const UChar* spec, int specLength, int afterScheme, URLSegments& parsed);
+
+} // namespace URLParser
+
+} // namespace WTF
+
+#endif // USE(WTFURL)
+
+#endif // URLParseInternal_h
diff --git a/Source/WTF/wtf/url/src/URLParser.h b/Source/WTF/wtf/url/src/URLParser.h
deleted file mode 100644
index 2b4d598a3..000000000
--- a/Source/WTF/wtf/url/src/URLParser.h
+++ /dev/null
@@ -1,596 +0,0 @@
-/* Based on nsURLParsers.cc from Mozilla
- * -------------------------------------
- * Copyright (C) 1998 Netscape Communications Corporation.
- * Copyright (C) 2012 Apple Inc. All rights reserved.
- *
- * Other contributors:
- * Darin Fisher (original author)
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * Alternatively, the contents of this file may be used under the terms
- * of either the Mozilla Public License Version 1.1, found at
- * http://www.mozilla.org/MPL/ (the "MPL") or the GNU General Public
- * License Version 2.0, found at http://www.fsf.org/copyleft/gpl.html
- * (the "GPL"), in which case the provisions of the MPL or the GPL are
- * applicable instead of those above. If you wish to allow use of your
- * version of this file only under the terms of one of those two
- * licenses (the MPL or the GPL) and not to allow others to use your
- * version of this file under the LGPL, indicate your decision by
- * deletingthe provisions above and replace them with the notice and
- * other provisions required by the MPL or the GPL, as the case may be.
- * If you do not delete the provisions above, a recipient may use your
- * version of this file under any of the LGPL, the MPL or the GPL.
- */
-
-#ifndef URLParser_h
-#define URLParser_h
-
-#include "URLComponent.h"
-#include "URLSegments.h"
-#include "UnusedParam.h"
-
-#if USE(WTFURL)
-
-namespace WTF {
-
-template<typename CharacterType, typename BaseCharacterType = CharacterType>
-class URLParser {
-public:
- enum SpecialPort {
- UnspecifiedPort = -1,
- InvalidPort = -2,
- };
-
- // This handles everything that may be an authority terminator, including
- // backslash. For special backslash handling see parseAfterScheme.
- static bool isPossibleAuthorityTerminator(CharacterType ch)
- {
- return isURLSlash(ch) || ch == '?' || ch == '#' || ch == ';';
- }
-
- // Given an already-identified auth section, breaks it into its constituent
- // parts. The port number will be parsed and the resulting integer will be
- // filled into the given *port variable, or -1 if there is no port number
- // or it is invalid.
- static void parseAuthority(const CharacterType* spec, const URLComponent& auth, URLComponent& username, URLComponent& password, URLComponent& host, URLComponent& port)
- {
- // FIXME: add ASSERT(auth.isValid()); // We should always get an authority.
- if (!auth.length()) {
- username.reset();
- password.reset();
- host.reset();
- port.reset();
- return;
- }
-
- // Search backwards for @, which is the separator between the user info
- // and the server info. RFC 3986 forbids @ from occuring in auth, but
- // someone might include it in a password unescaped.
- int i = auth.begin() + auth.length() - 1;
- while (i > auth.begin() && spec[i] != '@')
- --i;
-
- if (spec[i] == '@') {
- // Found user info: <user-info>@<server-info>
- parseUserInfo(spec, URLComponent(auth.begin(), i - auth.begin()), username, password);
- parseServerInfo(spec, URLComponent::fromRange(i + 1, auth.begin() + auth.length()), host, port);
- } else {
- // No user info, everything is server info.
- username.reset();
- password.reset();
- parseServerInfo(spec, auth, host, port);
- }
- }
-
- static bool extractScheme(const CharacterType* spec, int specLength, URLComponent& scheme)
- {
- // Skip leading whitespace and control characters.
- int begin = 0;
- while (begin < specLength && shouldTrimFromURL(spec[begin]))
- begin++;
- if (begin == specLength)
- return false; // Input is empty or all whitespace.
-
- // Find the first colon character.
- for (int i = begin; i < specLength; i++) {
- if (spec[i] == ':') {
- scheme = URLComponent::fromRange(begin, i);
- return true;
- }
- }
- return false; // No colon found: no scheme
- }
-
- // Fills in all members of the URLSegments structure (except for the
- // scheme) for standard URLs.
- //
- // |spec| is the full spec being parsed, of length |specLength|.
- // |afterScheme| is the character immediately following the scheme (after
- // the colon) where we'll begin parsing.
- static void parseAfterScheme(const CharacterType* spec, int specLength, int afterScheme, URLSegments& parsed)
- {
- int numberOfSlashes = consecutiveSlashes(spec, afterScheme, specLength);
- int afterSlashes = afterScheme + numberOfSlashes;
-
- // First split into two main parts, the authority (username, password,
- // host, and port) and the full path (path, query, and reference).
- URLComponent authority;
- URLComponent fullPath;
-
- // Found "//<some data>", looks like an authority section. Treat
- // everything from there to the next slash (or end of spec) to be the
- // authority. Note that we ignore the number of slashes and treat it as
- // the authority.
- int authEnd = nextAuthorityTerminator(spec, afterSlashes, specLength);
- authority = URLComponent(afterSlashes, authEnd - afterSlashes);
-
- if (authEnd == specLength) // No beginning of path found.
- fullPath = URLComponent();
- else // Everything starting from the slash to the end is the path.
- fullPath = URLComponent(authEnd, specLength - authEnd);
-
- // Now parse those two sub-parts.
- parseAuthority(spec, authority, parsed.username, parsed.password, parsed.host, parsed.port);
- parsePath(spec, fullPath, parsed.path, parsed.query, parsed.fragment);
- }
-
- // The main parsing function for standard URLs. Standard URLs have a scheme,
- // host, path, etc.
- static void parseStandardURL(const CharacterType* spec, int specLength, URLSegments& parsed)
- {
- // FIXME: add ASSERT(specLength >= 0);
-
- // Strip leading & trailing spaces and control characters.
- int begin = 0;
- trimURL(spec, begin, specLength);
-
- int afterScheme;
- if (extractScheme(spec, specLength, parsed.scheme))
- afterScheme = parsed.scheme.end() + 1; // Skip past the colon.
- else {
- // Say there's no scheme when there is a colon. We could also say
- // that everything is the scheme. Both would produce an invalid
- // URL, but this way seems less wrong in more cases.
- parsed.scheme.reset();
- afterScheme = begin;
- }
- parseAfterScheme(spec, specLength, afterScheme, parsed);
- }
-
- // The main parsing function for (may be) relative URLs.
- static void parseURLWithBase(const CharacterType* spec, int specLength,
- const BaseCharacterType* baseStringSpec, int baseStringSpecLength, const URLSegments& baseStringSegments,
- URLBuffer<char>&outputBuffer, URLSegments& parsed)
- {
- UNUSED_PARAM(baseStringSpec);
- UNUSED_PARAM(baseStringSpecLength);
- UNUSED_PARAM(baseStringSegments);
- UNUSED_PARAM(spec);
- UNUSED_PARAM(specLength);
- UNUSED_PARAM(outputBuffer);
- UNUSED_PARAM(parsed);
- // FIXME: To implement.
- }
-
- static void parsePath(const CharacterType* spec, const URLComponent& path, URLComponent& filepath, URLComponent& query, URLComponent& fragment)
- {
- // path = [/]<segment1>/<segment2>/<...>/<segmentN>;<param>?<query>#<fragment>
-
- // Special case when there is no path.
- if (!path.isValid()) {
- filepath.reset();
- query.reset();
- fragment.reset();
- return;
- }
- // FIXME: add ASSERT(path.length() > 0); // We should never have 0 length paths.
-
- // Search for first occurrence of either ? or #.
- int pathEnd = path.begin() + path.length();
-
- int querySeparator = -1; // Index of the '?'
- int refSeparator = -1; // Index of the '#'
- for (int i = path.begin(); i < pathEnd; i++) {
- switch (spec[i]) {
- case '?':
- if (querySeparator < 0)
- querySeparator = i;
- break;
- case '#':
- refSeparator = i;
- i = pathEnd; // Break out of the loop.
- break;
- default:
- break;
- }
- }
-
- // Markers pointing to the character after each of these corresponding
- // components. The code below works from the end back to the beginning,
- // and will update these indices as it finds components that exist.
- int fileEnd, queryEnd;
-
- // Fragment: from the # to the end of the path.
- if (refSeparator >= 0) {
- fileEnd = refSeparator;
- queryEnd = refSeparator;
- fragment = URLComponent::fromRange(refSeparator + 1, pathEnd);
- } else {
- fileEnd = pathEnd;
- queryEnd = pathEnd;
- fragment.reset();
- }
-
- // Query fragment: everything from the ? to the next boundary (either
- // the end of the path or the fragment fragment).
- if (querySeparator >= 0) {
- fileEnd = querySeparator;
- query = URLComponent::fromRange(querySeparator + 1, queryEnd);
- } else
- query.reset();
-
- // File path: treat an empty file path as no file path.
- if (fileEnd != path.begin())
- filepath = URLComponent::fromRange(path.begin(), fileEnd);
- else
- filepath.reset();
- }
-
- // Initializes a path URL which is merely a scheme followed by a path.
- // Examples include "about:foo" and "javascript:alert('bar');"
- static void parsePathURL(const CharacterType* spec, int specLength, URLSegments& parsed)
- {
- // Get the non-path and non-scheme parts of the URL out of the way, we
- // never use them.
- parsed.username.reset();
- parsed.password.reset();
- parsed.host.reset();
- parsed.port.reset();
- parsed.query.reset();
- parsed.fragment.reset();
-
- // Strip leading & trailing spaces and control characters.
- // FIXME: Perhaps this is unnecessary?
- int begin = 0;
- trimURL(spec, begin, specLength);
-
- // Handle empty specs or ones that contain only whitespace or control
- // chars.
- if (begin == specLength) {
- parsed.scheme.reset();
- parsed.path.reset();
- return;
- }
-
- // Extract the scheme, with the path being everything following. We also
- // handle the case where there is no scheme.
- if (extractScheme(&spec[begin], specLength - begin, parsed.scheme)) {
- // Offset the results since we gave extractScheme a substring.
- parsed.scheme.setBegin(parsed.scheme.begin() + begin);
-
- // For compatibility with the standard URL parser, we treat no path
- // as -1, rather than having a length of 0 (we normally wouldn't
- // care so much for these non-standard URLs).
- if (parsed.scheme.end() == specLength - 1)
- parsed.path.reset();
- else
- parsed.path = URLComponent::fromRange(parsed.scheme.end() + 1, specLength);
- } else {
- // No scheme found, just path.
- parsed.scheme.reset();
- parsed.path = URLComponent::fromRange(begin, specLength);
- }
- }
-
- static void parseMailtoURL(const CharacterType* spec, int specLength, URLSegments& parsed)
- {
- // FIXME: add ASSERT(specLength >= 0);
-
- // Get the non-path and non-scheme parts of the URL out of the way, we
- // never use them.
- parsed.username.reset();
- parsed.password.reset();
- parsed.host.reset();
- parsed.port.reset();
- parsed.fragment.reset();
- parsed.query.reset(); // May use this; reset for convenience.
-
- // Strip leading & trailing spaces and control characters.
- int begin = 0;
- trimURL(spec, begin, specLength);
-
- // Handle empty specs or ones that contain only whitespace or control
- // chars.
- if (begin == specLength) {
- parsed.scheme.reset();
- parsed.path.reset();
- return;
- }
-
- int pathBegin = -1;
- int pathEnd = -1;
-
- // Extract the scheme, with the path being everything following. We also
- // handle the case where there is no scheme.
- if (extractScheme(&spec[begin], specLength - begin, parsed.scheme)) {
- // Offset the results since we gave extractScheme a substring.
- parsed.scheme.setBegin(parsed.scheme.begin() + begin);
-
- if (parsed.scheme.end() != specLength - 1) {
- pathBegin = parsed.scheme.end() + 1;
- pathEnd = specLength;
- }
- } else {
- // No scheme found, just path.
- parsed.scheme.reset();
- pathBegin = begin;
- pathEnd = specLength;
- }
-
- // Split [pathBegin, pathEnd) into a path + query.
- for (int i = pathBegin; i < pathEnd; ++i) {
- if (spec[i] == '?') {
- parsed.query = URLComponent::fromRange(i + 1, pathEnd);
- pathEnd = i;
- break;
- }
- }
-
- // For compatibility with the standard URL parser, treat no path as
- // -1, rather than having a length of 0
- if (pathBegin == pathEnd)
- parsed.path.reset();
- else
- parsed.path = URLComponent::fromRange(pathBegin, pathEnd);
- }
-
- static int parsePort(const CharacterType* spec, const URLComponent& component)
- {
- // Easy success case when there is no port.
- const int maxDigits = 5;
- if (component.isEmptyOrInvalid())
- return UnspecifiedPort;
-
- URLComponent nonZeroDigits(component.end(), 0);
- for (int i = 0; i < component.length(); ++i) {
- if (spec[component.begin() + i] != '0') {
- nonZeroDigits = URLComponent::fromRange(component.begin() + i, component.end());
- break;
- }
- }
- if (!nonZeroDigits.length())
- return 0; // All digits were 0.
-
- if (nonZeroDigits.length() > maxDigits)
- return InvalidPort;
-
- int port = 0;
- for (int i = 0; i < nonZeroDigits.length(); ++i) {
- CharacterType ch = spec[nonZeroDigits.begin() + i];
- if (!isPortDigit(ch))
- return InvalidPort;
- port *= 10;
- port += static_cast<char>(ch) - '0';
- }
- if (port > 65535)
- return InvalidPort;
- return port;
- }
-
- static void extractFileName(const CharacterType* spec, const URLComponent& path, URLComponent& fileName)
- {
- // Handle empty paths: they have no file names.
- if (path.isEmptyOrInvalid()) {
- fileName.reset();
- return;
- }
-
- // Search backwards for a parameter, which is a normally unused field
- // in a URL delimited by a semicolon. We parse the parameter as part of
- // the path, but here, we don't want to count it. The last semicolon is
- // the parameter.
- int fileEnd = path.end();
- for (int i = path.end() - 1; i > path.begin(); --i) {
- if (spec[i] == ';') {
- fileEnd = i;
- break;
- }
- }
-
- // Now search backwards from the filename end to the previous slash
- // to find the beginning of the filename.
- for (int i = fileEnd - 1; i >= path.begin(); --i) {
- if (isURLSlash(spec[i])) {
- // File name is everything following this character to the end
- fileName = URLComponent::fromRange(i + 1, fileEnd);
- return;
- }
- }
-
- // No slash found, this means the input was degenerate (generally paths
- // will start with a slash). Let's call everything the file name.
- fileName = URLComponent::fromRange(path.begin(), fileEnd);
- }
-
- static bool extractQueryKeyValue(const CharacterType* spec, URLComponent& query, URLComponent& key, URLComponent& value)
- {
- if (query.isEmptyOrInvalid())
- return false;
-
- int start = query.begin();
- int current = start;
- int end = query.end();
-
- // We assume the beginning of the input is the beginning of the "key"
- // and we skip to the end of it.
- key.setBegin(current);
- while (current < end && spec[current] != '&' && spec[current] != '=')
- ++current;
- key.setLength(current - key.begin());
-
- // Skip the separator after the key (if any).
- if (current < end && spec[current] == '=')
- ++current;
-
- // Find the value part.
- value.setBegin(current);
- while (current < end && spec[current] != '&')
- ++current;
- value.setLength(current - value.begin());
-
- // Finally skip the next separator if any
- if (current < end && spec[current] == '&')
- ++current;
-
- // Save the new query
- query = URLComponent::fromRange(current, end);
- return true;
- }
-
-// FIXME: This should be protected or private.
-public:
- // We treat slashes and backslashes the same for IE compatibility.
- static inline bool isURLSlash(CharacterType ch)
- {
- return ch == '/' || ch == '\\';
- }
-
- // Returns true if we should trim this character from the URL because it is
- // a space or a control character.
- static inline bool shouldTrimFromURL(CharacterType ch)
- {
- return ch <= ' ';
- }
-
- // Given an already-initialized begin index and end index (the index after
- // the last CharacterType in spec), this shrinks the range to eliminate
- // "should-be-trimmed" characters.
- static inline void trimURL(const CharacterType* spec, int& begin, int& end)
- {
- // Strip leading whitespace and control characters.
- while (begin < end && shouldTrimFromURL(spec[begin]))
- ++begin;
-
- // Strip trailing whitespace and control characters. We need the >i
- // test for when the input string is all blanks; we don't want to back
- // past the input.
- while (end > begin && shouldTrimFromURL(spec[end - 1]))
- --end;
- }
-
- // Counts the number of consecutive slashes starting at the given offset
- // in the given string of the given length.
- static inline int consecutiveSlashes(const CharacterType *string, int beginOffset, int stringLength)
- {
- int count = 0;
- while (beginOffset + count < stringLength && isURLSlash(string[beginOffset + count]))
- ++count;
- return count;
- }
-
-private:
- // URLParser cannot be constructed.
- URLParser();
-
- // Returns true if the given character is a valid digit to use in a port.
- static inline bool isPortDigit(CharacterType ch)
- {
- return ch >= '0' && ch <= '9';
- }
-
- // Returns the offset of the next authority terminator in the input starting
- // from startOffset. If no terminator is found, the return value will be equal
- // to specLength.
- static int nextAuthorityTerminator(const CharacterType* spec, int startOffset, int specLength)
- {
- for (int i = startOffset; i < specLength; i++) {
- if (isPossibleAuthorityTerminator(spec[i]))
- return i;
- }
- return specLength; // Not found.
- }
-
- static void parseUserInfo(const CharacterType* spec, const URLComponent& user, URLComponent& username, URLComponent& password)
- {
- // Find the first colon in the user section, which separates the
- // username and password.
- int colonOffset = 0;
- while (colonOffset < user.length() && spec[user.begin() + colonOffset] != ':')
- ++colonOffset;
-
- if (colonOffset < user.length()) {
- // Found separator: <username>:<password>
- username = URLComponent(user.begin(), colonOffset);
- password = URLComponent::fromRange(user.begin() + colonOffset + 1, user.begin() + user.length());
- } else {
- // No separator, treat everything as the username
- username = user;
- password = URLComponent();
- }
- }
-
- static void parseServerInfo(const CharacterType* spec, const URLComponent& serverInfo, URLComponent& host, URLComponent& port)
- {
- if (!serverInfo.length()) {
- // No server info, host name is empty.
- host.reset();
- port.reset();
- return;
- }
-
- // If the host starts with a left-bracket, assume the entire host is an
- // IPv6 literal. Otherwise, assume none of the host is an IPv6 literal.
- // This assumption will be overridden if we find a right-bracket.
- //
- // Our IPv6 address canonicalization code requires both brackets to
- // exist, but the ability to locate an incomplete address can still be
- // useful.
- int ipv6Terminator = spec[serverInfo.begin()] == '[' ? serverInfo.end() : -1;
- int colon = -1;
-
- // Find the last right-bracket, and the last colon.
- for (int i = serverInfo.begin(); i < serverInfo.end(); i++) {
- switch (spec[i]) {
- case ']':
- ipv6Terminator = i;
- break;
- case ':':
- colon = i;
- break;
- default:
- break;
- }
- }
-
- if (colon > ipv6Terminator) {
- // Found a port number: <hostname>:<port>
- host = URLComponent::fromRange(serverInfo.begin(), colon);
- if (!host.length())
- host.reset();
- port = URLComponent::fromRange(colon + 1, serverInfo.end());
- } else {
- // No port: <hostname>
- host = serverInfo;
- port.reset();
- }
- }
-};
-
-} // namespace WTF
-
-#endif // USE(WTFURL)
-
-#endif // URLParser_h
diff --git a/Source/WTF/wtf/url/src/URLQueryCanonicalizer.h b/Source/WTF/wtf/url/src/URLQueryCanonicalizer.h
deleted file mode 100644
index 467c497fd..000000000
--- a/Source/WTF/wtf/url/src/URLQueryCanonicalizer.h
+++ /dev/null
@@ -1,109 +0,0 @@
-// Copyright 2010, Google 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:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * 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.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND 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 THE COPYRIGHT
-// OWNER 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 URLQueryCanonicalizer_h
-#define URLQueryCanonicalizer_h
-
-#if USE(WTFURL)
-
-#include "RawURLBuffer.h"
-#include "URLBuffer.h"
-#include "URLCharacterTypes.h"
-#include "URLComponent.h"
-#include "URLEscape.h"
-
-namespace WTF {
-
-template<typename InChar, typename OutChar, void convertCharset(const InChar*, int length, URLBuffer<char>&)>
-class URLQueryCanonicalizer {
-public:
- static void canonicalize(const InChar* spec, const URLComponent& query, URLBuffer<OutChar>& buffer, URLComponent& resultQuery)
- {
- if (query.length() < 0) {
- resultQuery = URLComponent();
- return;
- }
-
- buffer->append('?');
- resultQuery.setBegin(buffer->length());
- convertToQueryEncoding(spec, query, buffer);
- resultQuery.setLength(buffer->length() - resultQuery.begin());
- }
-
-private:
- static bool isAllASCII(const InChar* spec, const URLComponent& query)
- {
- int end = query.end();
- for (int i = query.begin(); i < end; ++i) {
- if (static_cast<unsigned>(spec[i]) >= 0x80)
- return false;
- }
- return true;
- }
-
-#ifndef NDEBUG
- static bool isRaw8Bit(const InChar* source, int length)
- {
- for (int i = source; i < length; ++i) {
- if (source[i] & 0xFF != source[i])
- return false;
- }
- return true;
- }
-#endif
-
- static void appendRaw8BitQueryString(const InChar* source, int length, URLBuffer<OutChar>* buffer)
- {
- ASSERT(isRaw8Bit(source, length));
- for (int i = 0; i < length; ++i) {
- if (!URLCharacterTypes::isQueryChar(source[i]))
- appendURLEscapedCharacter(static_cast<unsigned char>(source[i]), buffer);
- else
- buffer->append(static_cast<char>(source[i]));
- }
- }
-
- static void convertToQueryEncoding(const InChar* spec, const URLComponent& query, URLBuffer<OutChar>& buffer)
- {
- if (isAllASCII(spec, query)) {
- appendRaw8BitQueryString(&spec[query.begin()], query.length(), buffer);
- return;
- }
-
- RawURLBuffer<char, 1024> convertedQuery;
- convertCharset(spec, query, convertedQuery);
- appendRaw8BitQueryString(convertedQuery.data(), convertedQuery.length(), buffer);
- }
-};
-
-}
-
-#endif // USE(WTFURL)
-
-#endif
diff --git a/Source/WTF/wtf/url/src/URLSegments.cpp b/Source/WTF/wtf/url/src/URLSegments.cpp
index 158e5d9d4..8d973cc2a 100644
--- a/Source/WTF/wtf/url/src/URLSegments.cpp
+++ b/Source/WTF/wtf/url/src/URLSegments.cpp
@@ -13,7 +13,7 @@
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
@@ -25,7 +25,7 @@
* http://www.mozilla.org/MPL/ (the "MPL") or the GNU General Public
* License Version 2.0, found at http://www.fsf.org/copyleft/gpl.html
* (the "GPL"), in which case the provisions of the MPL or the GPL are
- * applicable instead of those above. If you wish to allow use of your
+ * applicable instead of those above. If you wish to allow use of your
* version of this file only under the terms of one of those two
* licenses (the MPL or the GPL) and not to allow others to use your
* version of this file under the LGPL, indicate your decision by
diff --git a/Source/WTF/wtf/url/src/URLSegments.h b/Source/WTF/wtf/url/src/URLSegments.h
index 9f17228d6..9e5ae6bd0 100644
--- a/Source/WTF/wtf/url/src/URLSegments.h
+++ b/Source/WTF/wtf/url/src/URLSegments.h
@@ -1,41 +1,47 @@
-// Copyright 2007, Google Inc. All rights reserved.
-// Copyright 2012 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:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * 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.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND 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 THE COPYRIGHT
-// OWNER 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.
+/*
+ * Copyright 2007 Google Inc. All rights reserved.
+ * Copyright 2012 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:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * 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.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND 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 THE COPYRIGHT
+ * OWNER 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 URLSegments_h
#define URLSegments_h
#include "URLComponent.h"
+#include <wtf/OwnPtr.h>
+#include <wtf/PassOwnPtr.h>
#if USE(WTFURL)
namespace WTF {
+class URLSegments;
+
// A structure that holds the identified parts of an input URL. This structure
// does NOT store the URL itself. The caller will have to store the URL text
// and its corresponding Parsed structure separately.
@@ -59,6 +65,26 @@ public:
URLSegments() { }
+ URLSegments(const URLSegments& otherSegment)
+ {
+ *this = otherSegment;
+ }
+
+ URLSegments& operator=(const URLSegments& otherSegment)
+ {
+ scheme = otherSegment.scheme;
+ username = otherSegment.username;
+ password = otherSegment.password;
+ host = otherSegment.host;
+ port = otherSegment.port;
+ path = otherSegment.path;
+ query = otherSegment.query;
+ fragment = otherSegment.fragment;
+ if (otherSegment.m_innerURLSegments)
+ m_innerURLSegments = adoptPtr(new URLSegments(*otherSegment.m_innerURLSegments));
+ return *this;
+ }
+
// Returns the length of the URL (the end of the last component).
//
// Note that for some invalid, non-canonical URLs, this may not be the length
@@ -105,6 +131,16 @@ public:
URLComponent path;
URLComponent query;
URLComponent fragment;
+
+ // FIXME: this is a damn ugly API and is basically untested.
+ const URLSegments* innerURLSegments() const { return m_innerURLSegments.get(); }
+ void setInnerURLSegments(const URLSegments& urlSegments) { m_innerURLSegments = adoptPtr(new URLSegments(urlSegments)); }
+ void clearInnerURLSegments() { return m_innerURLSegments.clear(); }
+
+private:
+ // The Filesystem API describe a URL format with an internal URL. E.g.: filesystem:http://www.apple.com/
+ // The inner URL segment contains the parsed inner URL of a filesystem: URL.
+ OwnPtr<URLSegments> m_innerURLSegments;
};
} // namespace WTF
diff --git a/Source/WTF/wtf/url/src/URLUtil.cpp b/Source/WTF/wtf/url/src/URLUtil.cpp
new file mode 100644
index 000000000..d0535138d
--- /dev/null
+++ b/Source/WTF/wtf/url/src/URLUtil.cpp
@@ -0,0 +1,494 @@
+/*
+ * Copyright 2007 Google Inc. All rights reserved.
+ * Copyright 2012 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:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * 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.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND 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 THE COPYRIGHT
+ * OWNER 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 "URLUtil.h"
+
+#include "RawURLBuffer.h"
+#include "URLCanonInternal.h"
+#include "URLFile.h"
+#include "URLUtilInternal.h"
+#include <wtf/ASCIICType.h>
+
+#if USE(WTFURL)
+
+namespace WTF {
+
+namespace URLUtilities {
+
+const char kFileScheme[] = "file";
+const char kFileSystemScheme[] = "filesystem";
+const char kMailtoScheme[] = "mailto";
+
+namespace {
+
+// Backend for LowerCaseEqualsASCII.
+template<typename Iter>
+inline bool doLowerCaseEqualsASCII(Iter aBegin, Iter aEnd, const char* b)
+{
+ for (Iter it = aBegin; it != aEnd; ++it, ++b) {
+ if (!*b || toASCIILower(*it) != *b)
+ return false;
+ }
+ return !(*b);
+}
+
+const int kNumStandardURLSchemes = 8;
+const char* kStandardURLSchemes[kNumStandardURLSchemes] = {
+ "http",
+ "https",
+ kFileScheme, // Yes, file urls can have a hostname!
+ "ftp",
+ "gopher",
+ "ws", // WebSocket.
+ "wss", // WebSocket secure.
+ kFileSystemScheme
+};
+
+// Given a string and a range inside the string, compares it to the given
+// lower-case |compareTo| buffer.
+template<typename CharacterType>
+inline bool doCompareSchemeComponent(const CharacterType* spec, const URLComponent& component, const char* compareTo)
+{
+ if (!component.isNonEmpty())
+ return !compareTo[0]; // When component is empty, match empty scheme.
+ return LowerCaseEqualsASCII(&spec[component.begin()], &spec[component.end()], compareTo);
+}
+
+// Returns true if the given scheme identified by |scheme| within |spec| is one
+// of the registered "standard" schemes.
+template<typename CharacterType>
+bool doIsStandard(const CharacterType* spec, const URLComponent& scheme)
+{
+ if (!scheme.isNonEmpty())
+ return false; // Empty or invalid schemes are non-standard.
+
+ for (size_t i = 0; i < kNumStandardURLSchemes; ++i) {
+ if (LowerCaseEqualsASCII(&spec[scheme.begin()], &spec[scheme.end()], kStandardURLSchemes[i]))
+ return true;
+ }
+ return false;
+}
+
+template<typename CharacterType>
+bool doFindAndCompareScheme(const CharacterType* str, int strLength, const char* compare, URLComponent* foundScheme)
+{
+ // Before extracting scheme, canonicalize the URL to remove any whitespace.
+ // This matches the canonicalization done in doCanonicalize function.
+ RawURLBuffer<CharacterType> whitespaceBuffer;
+ int specLength;
+ const CharacterType* spec = URLCanonicalizer::removeURLWhitespace(str, strLength, whitespaceBuffer, specLength);
+
+ URLComponent ourScheme;
+ if (!URLParser::ExtractScheme(spec, specLength, &ourScheme)) {
+ // No scheme.
+ if (foundScheme)
+ *foundScheme = URLComponent();
+ return false;
+ }
+ if (foundScheme)
+ *foundScheme = ourScheme;
+ return doCompareSchemeComponent(spec, ourScheme, compare);
+}
+
+template<typename CharacterType>
+bool doCanonicalize(const CharacterType* inSpec, int inSpecLength,
+ URLQueryCharsetConverter* charsetConverter,
+ URLBuffer<char>& output, URLSegments& ouputParsed)
+{
+ // Remove any whitespace from the middle of the relative URL, possibly
+ // copying to the new buffer.
+ RawURLBuffer<CharacterType> whitespaceBuffer;
+ int specLength;
+ const CharacterType* spec = URLCanonicalizer::removeURLWhitespace(inSpec, inSpecLength, whitespaceBuffer, specLength);
+
+ URLSegments parsedInput;
+#if OS(WINDOWS)
+ // For Windows, we allow things that look like absolute Windows paths to be
+ // fixed up magically to file URLs. This is done for IE compatability. For
+ // example, this will change "c:/foo" into a file URL rather than treating
+ // it as a URL with the protocol "c". It also works for UNC ("\\foo\bar.txt").
+ // There is similar logic in URLCanonicalizer_relative.cc for
+ //
+ // For Max & Unix, we don't do this (the equivalent would be "/foo/bar" which
+ // has no meaning as an absolute path name. This is because browsers on Mac
+ // & Unix don't generally do this, so there is no compatibility reason for
+ // doing so.
+ if (URLParser::doesBeginUNCPath(spec, 0, specLength, false)
+ || URLParser::doesBeginWindowsDriveSpec(spec, 0, specLength)) {
+ URLParser::ParseFileURL(spec, specLength, &parsedInput);
+ return URLCanonicalizer::CanonicalizeFileURL(spec, specLength, parsedInput,
+ charsetConverter,
+ output, *ouputParsed);
+ }
+#endif
+
+ URLComponent scheme;
+ if (!URLParser::ExtractScheme(spec, specLength, &scheme))
+ return false;
+
+ // This is the parsed version of the input URL, we have to canonicalize it
+ // before storing it in our object.
+ bool success;
+ if (doCompareSchemeComponent(spec, scheme, kFileScheme)) {
+ // File URLs are special.
+ URLParser::ParseFileURL(spec, specLength, &parsedInput);
+ success = URLCanonicalizer::CanonicalizeFileURL(spec, specLength, parsedInput,
+ charsetConverter, output,
+ &ouputParsed);
+ } else if (doCompareSchemeComponent(spec, scheme, kFileSystemScheme)) {
+ // Filesystem URLs are special.
+ URLParser::ParseFileSystemURL(spec, specLength, &parsedInput);
+ success = URLCanonicalizer::canonicalizeFileSystemURL(spec, parsedInput,
+ charsetConverter,
+ output, ouputParsed);
+
+ } else if (doIsStandard(spec, scheme)) {
+ // All "normal" URLs.
+ URLParser::ParseStandardURL(spec, specLength, &parsedInput);
+ success = URLCanonicalizer::CanonicalizeStandardURL(spec, specLength, parsedInput,
+ charsetConverter,
+ output, &ouputParsed);
+
+ } else if (doCompareSchemeComponent(spec, scheme, kMailtoScheme)) {
+ // Mailto are treated like a standard url with only a scheme, path, query
+ URLParser::ParseMailtoURL(spec, specLength, &parsedInput);
+ success = URLCanonicalizer::canonicalizeMailtoURL(spec, parsedInput, output, ouputParsed);
+
+ } else {
+ // "Weird" URLs like data: and javascript:
+ URLParser::ParsePathURL(spec, specLength, &parsedInput);
+ success = URLCanonicalizer::canonicalizePathURL(spec, parsedInput, output, ouputParsed);
+ }
+ return success;
+}
+
+template<typename CharacterType>
+bool doResolveRelative(const char* baseSpec, const URLSegments& baseParsed,
+ const CharacterType* inRelative, int inRelativeLength,
+ URLQueryCharsetConverter* charsetConverter,
+ URLBuffer<char>& output, URLSegments* ouputParsed)
+{
+ // Remove any whitespace from the middle of the relative URL, possibly
+ // copying to the new buffer.
+ RawURLBuffer<CharacterType> whitespaceBuffer;
+ int relativeLength;
+ const CharacterType* relative = URLCanonicalizer::removeURLWhitespace(inRelative, inRelativeLength, whitespaceBuffer, relativeLength);
+
+ // See if our base URL should be treated as "standard".
+ bool standardBaseScheme = baseParsed.scheme.isNonEmpty() && doIsStandard(baseSpec, baseParsed.scheme);
+
+ bool isRelative;
+ URLComponent relativeComponent;
+ if (!URLCanonicalizer::isRelativeURL(baseSpec, baseParsed,
+ relative, relativeLength,
+ standardBaseScheme,
+ isRelative, relativeComponent))
+ return false; // Error resolving.
+
+ if (isRelative) {
+ // Relative, resolve and canonicalize.
+ bool fileBaseScheme = baseParsed.scheme.isNonEmpty() && doCompareSchemeComponent(baseSpec, baseParsed.scheme, kFileScheme);
+ return URLCanonicalizer::resolveRelativeURL(baseSpec, baseParsed,
+ fileBaseScheme, relative,
+ relativeComponent, charsetConverter,
+ output, ouputParsed);
+ }
+
+ // Not relative, canonicalize the input.
+ return doCanonicalize(relative, relativeLength, charsetConverter, output, *ouputParsed);
+}
+
+template<typename CharacterType>
+bool doReplaceComponents(const char* spec,
+ int specLength,
+ const URLSegments& parsed,
+ const URLCanonicalizer::Replacements<CharacterType>& replacements,
+ URLQueryCharsetConverter* charsetConverter,
+ URLBuffer<char>& output,
+ URLSegments& outputParsed)
+{
+ // If the scheme is overridden, just do a simple string substitution and
+ // reparse the whole thing. There are lots of edge cases that we really don't
+ // want to deal with. Like what happens if I replace "http://e:8080/foo"
+ // with a file. Does it become "file:///E:/8080/foo" where the port number
+ // becomes part of the path? Parsing that string as a file URL says "yes"
+ // but almost no sane rule for dealing with the components individually would
+ // come up with that.
+ //
+ // Why allow these crazy cases at all? Programatically, there is almost no
+ // case for replacing the scheme. The most common case for hitting this is
+ // in JS when building up a URL using the location object. In this case, the
+ // JS code expects the string substitution behavior:
+ // http://www.w3.org/TR/2008/WD-html5-20080610/structured.html#common3
+ if (replacements.IsSchemeOverridden()) {
+ // Canonicalize the new scheme so it is 8-bit and can be concatenated with
+ // the existing spec.
+ RawURLBuffer<char, 128> scheme_replaced;
+ URLComponent schemeReplacedParsed;
+ URLCanonicalizer::canonicalizeScheme(replacements.sources().scheme,
+ replacements.components().scheme,
+ scheme_replaced, schemeReplacedParsed);
+
+ // We can assume that the input is canonicalized, which means it always has
+ // a colon after the scheme (or where the scheme would be).
+ int specAfterColon = parsed.scheme.isValid() ? parsed.scheme.end() + 1
+ : 1;
+ if (specLength - specAfterColon > 0) {
+ scheme_replaced.append(&spec[specAfterColon],
+ specLength - specAfterColon);
+ }
+
+ // We now need to completely re-parse the resulting string since its meaning
+ // may have changed with the different scheme.
+ RawURLBuffer<char, 128> recanonicalized;
+ URLSegments recanonicalizedParsed;
+ doCanonicalize(scheme_replaced.data(), scheme_replaced.length(),
+ charsetConverter,
+ recanonicalized, recanonicalizedParsed);
+
+ // Recurse using the version with the scheme already replaced. This will now
+ // use the replacement rules for the new scheme.
+ //
+ // Warning: this code assumes that ReplaceComponents will re-check all
+ // components for validity. This is because we can't fail if DoCanonicalize
+ // failed above since theoretically the thing making it fail could be
+ // getting replaced here. If ReplaceComponents didn't re-check everything,
+ // we wouldn't know if something *not* getting replaced is a problem.
+ // If the scheme-specific replacers are made more intelligent so they don't
+ // re-check everything, we should instead recanonicalize the whole thing
+ // after this call to check validity (this assumes replacing the scheme is
+ // much much less common than other types of replacements, like clearing the
+ // ref).
+ URLCanonicalizer::Replacements<CharacterType> replacementsNoScheme = replacements;
+ replacementsNoScheme.SetScheme(0, URLComponent());
+ return doReplaceComponents(recanonicalized.data(), recanonicalized.length(),
+ recanonicalizedParsed, replacementsNoScheme,
+ charsetConverter, output, outputParsed);
+ }
+
+ // If we get here, then we know the scheme doesn't need to be replaced, so can
+ // just key off the scheme in the spec to know how to do the replacements.
+ if (doCompareSchemeComponent(spec, parsed.scheme, kFileScheme)) {
+ return URLCanonicalizer::ReplaceFileURL(spec, parsed, replacements,
+ charsetConverter, output, &outputParsed);
+ }
+ if (doCompareSchemeComponent(spec, parsed.scheme, kFileSystemScheme)) {
+ return URLCanonicalizer::ReplaceFileSystemURL(spec, parsed, replacements,
+ charsetConverter, output,
+ &outputParsed);
+ }
+ if (doIsStandard(spec, parsed.scheme)) {
+ return URLCanonicalizer::ReplaceStandardURL(spec, parsed, replacements,
+ charsetConverter, output, &outputParsed);
+ }
+ if (doCompareSchemeComponent(spec, parsed.scheme, kMailtoScheme))
+ return URLCanonicalizer::replaceMailtoURL(spec, parsed, replacements, output, outputParsed);
+
+ // Default is a path URL.
+ return URLCanonicalizer::ReplacePathURL(spec, parsed, replacements, output, &outputParsed);
+}
+
+} // namespace
+
+bool isStandard(const char* spec, const URLComponent& scheme)
+{
+ return doIsStandard(spec, scheme);
+}
+
+bool isStandard(const UChar* spec, const URLComponent& scheme)
+{
+ return doIsStandard(spec, scheme);
+}
+
+bool FindAndCompareScheme(const char* str, int strLength, const char* compare, URLComponent* foundScheme)
+{
+ return doFindAndCompareScheme(str, strLength, compare, foundScheme);
+}
+
+bool FindAndCompareScheme(const UChar* str, int strLength, const char* compare, URLComponent* foundScheme)
+{
+ return doFindAndCompareScheme(str, strLength, compare, foundScheme);
+}
+
+bool canonicalize(const char* spec, int specLength,
+ URLQueryCharsetConverter* charsetConverter,
+ URLBuffer<char>& output, URLSegments& ouputParsed)
+{
+ return doCanonicalize(spec, specLength, charsetConverter, output, ouputParsed);
+}
+
+bool canonicalize(const UChar* spec, int specLength,
+ URLQueryCharsetConverter* charsetConverter,
+ URLBuffer<char>& output, URLSegments& ouputParsed)
+{
+ return doCanonicalize(spec, specLength, charsetConverter, output, ouputParsed);
+}
+
+bool resolveRelative(const char* baseSpec, const URLSegments& baseParsed,
+ const char* relative, int relativeLength,
+ URLQueryCharsetConverter* charsetConverter,
+ URLBuffer<char>& output, URLSegments* ouputParsed)
+{
+ return doResolveRelative(baseSpec, baseParsed,
+ relative, relativeLength,
+ charsetConverter, output, ouputParsed);
+}
+
+bool resolveRelative(const char* baseSpec, const URLSegments& baseParsed,
+ const UChar* relative, int relativeLength,
+ URLQueryCharsetConverter* charsetConverter,
+ URLBuffer<char>& output, URLSegments* ouputParsed)
+{
+ return doResolveRelative(baseSpec, baseParsed,
+ relative, relativeLength,
+ charsetConverter, output, ouputParsed);
+}
+
+bool ReplaceComponents(const char* spec,
+ int specLength,
+ const URLSegments& parsed,
+ const URLCanonicalizer::Replacements<char>& replacements,
+ URLQueryCharsetConverter* charsetConverter,
+ URLBuffer<char>& output,
+ URLSegments* outputParsed)
+{
+ return doReplaceComponents(spec, specLength, parsed, replacements,
+ charsetConverter, output, *outputParsed);
+}
+
+bool ReplaceComponents(const char* spec,
+ int specLength,
+ const URLSegments& parsed,
+ const URLCanonicalizer::Replacements<UChar>& replacements,
+ URLQueryCharsetConverter* charsetConverter,
+ URLBuffer<char>& output,
+ URLSegments* outputParsed)
+{
+ return doReplaceComponents(spec, specLength, parsed, replacements,
+ charsetConverter, output, *outputParsed);
+}
+
+// Front-ends for LowerCaseEqualsASCII.
+bool LowerCaseEqualsASCII(const char* aBegin, const char* aEnd, const char* b)
+{
+ return doLowerCaseEqualsASCII(aBegin, aEnd, b);
+}
+
+bool LowerCaseEqualsASCII(const char* aBegin, const char* aEnd, const char* bBegin, const char* bEnd)
+{
+ while (aBegin != aEnd && bBegin != bEnd && toASCIILower(*aBegin) == *bBegin) {
+ aBegin++;
+ bBegin++;
+ }
+ return aBegin == aEnd && bBegin == bEnd;
+}
+
+bool LowerCaseEqualsASCII(const UChar* aBegin, const UChar* aEnd, const char* b)
+{
+ return doLowerCaseEqualsASCII(aBegin, aEnd, b);
+}
+
+void DecodeURLEscapeSequences(const char* input, int length, URLBuffer<UChar>& output)
+{
+ RawURLBuffer<char> unescapedChars;
+ for (int i = 0; i < length; ++i) {
+ if (input[i] == '%') {
+ unsigned char ch;
+ if (URLCanonicalizer::DecodeEscaped(input, &i, length, &ch))
+ unescapedChars.append(ch);
+ else {
+ // Invalid escape sequence, copy the percent literal.
+ unescapedChars.append('%');
+ }
+ } else {
+ // Regular non-escaped 8-bit character.
+ unescapedChars.append(input[i]);
+ }
+ }
+
+ // Convert that 8-bit to UTF-16. It's not clear IE does this at all to
+ // JavaScript URLs, but Firefox and Safari do.
+ for (int i = 0; i < unescapedChars.length(); i++) {
+ unsigned char uch = static_cast<unsigned char>(unescapedChars.at(i));
+ if (uch < 0x80) {
+ // Non-UTF-8, just append directly
+ output.append(uch);
+ } else {
+ // next_ch will point to the last character of the decoded
+ // character.
+ int nextCharacter = i;
+ unsigned codePoint;
+ if (URLCanonicalizer::readUTFChar(unescapedChars.data(), &nextCharacter,
+ unescapedChars.length(), &codePoint)) {
+ // Valid UTF-8 character, convert to UTF-16.
+ URLCanonicalizer::AppendUTF16Value(codePoint, output);
+ i = nextCharacter;
+ } else {
+ // If there are any sequences that are not valid UTF-8, we keep
+ // invalid code points and promote to UTF-16. We copy all characters
+ // from the current position to the end of the identified sequence.
+ while (i < nextCharacter) {
+ output.append(static_cast<unsigned char>(unescapedChars.at(i)));
+ i++;
+ }
+ output.append(static_cast<unsigned char>(unescapedChars.at(i)));
+ }
+ }
+ }
+}
+
+void EncodeURIComponent(const char* input, int length, URLBuffer<char>& output)
+{
+ for (int i = 0; i < length; ++i) {
+ unsigned char c = static_cast<unsigned char>(input[i]);
+ if (URLCharacterTypes::isComponentChar(c))
+ output.append(c);
+ else
+ URLCanonicalizer::appendURLEscapedCharacter(c, output);
+ }
+}
+
+bool CompareSchemeComponent(const char* spec, const URLComponent& component, const char* compareTo)
+{
+ return doCompareSchemeComponent(spec, component, compareTo);
+}
+
+bool CompareSchemeComponent(const UChar* spec, const URLComponent& component, const char* compareTo)
+{
+ return doCompareSchemeComponent(spec, component, compareTo);
+}
+
+} // namespace URLUtilities
+
+} // namespace WTF
+
+#endif // USE(WTFURL)
diff --git a/Source/WTF/wtf/url/src/URLUtil.h b/Source/WTF/wtf/url/src/URLUtil.h
new file mode 100644
index 000000000..a73924177
--- /dev/null
+++ b/Source/WTF/wtf/url/src/URLUtil.h
@@ -0,0 +1,137 @@
+/*
+ * Copyright 2007 Google Inc. All rights reserved.
+ * Copyright 2012 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:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * 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.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND 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 THE COPYRIGHT
+ * OWNER 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 URLUtil_h
+#define URLUtil_h
+
+#include "URLBuffer.h"
+#include "URLCanon.h"
+#include "URLParse.h"
+#include <wtf/unicode/Unicode.h>
+
+#if USE(WTFURL)
+
+namespace WTF {
+
+class URLQueryCharsetConverter;
+
+namespace URLUtilities {
+
+// Locates the scheme in the given string and places it into |foundScheme|,
+// which may be 0 to indicate the caller does not care about the range.
+//
+// Returns whether the given |compare| scheme matches the scheme found in the
+// input (if any). The |compare| scheme must be a valid canonical scheme or
+// the result of the comparison is undefined.
+bool FindAndCompareScheme(const char* str, int strLength, const char* compare, URLComponent* foundScheme);
+bool FindAndCompareScheme(const UChar* str, int strLength, const char* compare, URLComponent* foundScheme);
+
+// Returns true if the given string represents a standard URL. This means that
+// either the scheme is in the list of known standard schemes.
+bool isStandard(const char* spec, const URLComponent& scheme);
+bool isStandard(const UChar* spec, const URLComponent& scheme);
+
+// URL library wrappers -------------------------------------------------------
+
+// Parses the given spec according to the extracted scheme type. Normal users
+// should use the URL object, although this may be useful if performance is
+// critical and you don't want to do the heap allocation for the std::string.
+//
+// As with the URLCanonicalizer::Canonicalize* functions, the charset converter can
+// be 0 to use UTF-8 (it will be faster in this case).
+//
+// Returns true if a valid URL was produced, false if not. On failure, the
+// output and parsed structures will still be filled and will be consistent,
+// but they will not represent a loadable URL.
+bool canonicalize(const char* spec, int specLength, URLQueryCharsetConverter*,
+ URLBuffer<char>&, URLSegments& ouputParsed);
+bool canonicalize(const UChar* spec, int specLength, URLQueryCharsetConverter*,
+ URLBuffer<char>&, URLSegments& ouputParsed);
+
+// Resolves a potentially relative URL relative to the given parsed base URL.
+// The base MUST be valid. The resulting canonical URL and parsed information
+// will be placed in to the given out variables.
+//
+// The relative need not be relative. If we discover that it's absolute, this
+// will produce a canonical version of that URL. See Canonicalize() for more
+// about the charsetConverter.
+//
+// Returns true if the output is valid, false if the input could not produce
+// a valid URL.
+bool resolveRelative(const char* baseSpec, const URLSegments& baseParsed,
+ const char* relative, int relativeLength,
+ URLQueryCharsetConverter*,
+ URLBuffer<char>&, URLSegments* ouputParsed);
+bool resolveRelative(const char* baseSpec, const URLSegments& baseParsed,
+ const UChar* relative, int relativeLength,
+ URLQueryCharsetConverter*,
+ URLBuffer<char>&, URLSegments* ouputParsed);
+
+// Replaces components in the given VALID input url. The new canonical URL info
+// is written to output and outputParsed.
+//
+// Returns true if the resulting URL is valid.
+bool ReplaceComponents(const char* spec, int specLength, const URLSegments& parsed,
+ const URLCanonicalizer::Replacements<char>&,
+ URLQueryCharsetConverter*,
+ URLBuffer<char>&, URLSegments* outputParsed);
+bool ReplaceComponents(const char* spec, int specLength, const URLSegments& parsed,
+ const URLCanonicalizer::Replacements<UChar>&,
+ URLQueryCharsetConverter*,
+ URLBuffer<char>&, URLSegments* outputParsed);
+
+// String helper functions ----------------------------------------------------
+
+// Compare the lower-case form of the given string against the given ASCII
+// string. This is useful for doing checking if an input string matches some
+// token, and it is optimized to avoid intermediate string copies.
+//
+// The versions of this function that don't take a bEnd assume that the b
+// string is zero terminated.
+bool LowerCaseEqualsASCII(const char* aBegin, const char* aEnd, const char* b);
+bool LowerCaseEqualsASCII(const char* aBegin, const char* aEnd, const char* bBegin, const char* bEnd);
+bool LowerCaseEqualsASCII(const UChar* aBegin, const UChar* aEnd, const char* b);
+
+// Unescapes the given string using URL escaping rules.
+void DecodeURLEscapeSequences(const char* input, int length, URLBuffer<UChar>&);
+
+// Escapes the given string as defined by the JS method encodeURIComponent.
+// See https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/encodeURIComponent
+void EncodeURIComponent(const char* input, int length, URLBuffer<char>&);
+
+
+} // namespace URLUtilities
+
+} // namespace WTF
+
+#endif // USE(WTFURL)
+
+#endif // URLUtil_h
diff --git a/Source/WTF/wtf/url/src/URLUtilInternal.h b/Source/WTF/wtf/url/src/URLUtilInternal.h
new file mode 100644
index 000000000..0840aec86
--- /dev/null
+++ b/Source/WTF/wtf/url/src/URLUtilInternal.h
@@ -0,0 +1,58 @@
+/*
+ * Copyright 2011 Google Inc. All rights reserved.
+ * Copyright 2012 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:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * 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.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND 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 THE COPYRIGHT
+ * OWNER 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 URLUtilInternal_h
+#define URLUtilInternal_h
+
+#include "URLParse.h"
+
+#if USE(WTFURL)
+
+namespace WTF {
+
+namespace URLUtilities {
+
+extern const char kFileScheme[];
+extern const char kFileSystemScheme[];
+extern const char kMailtoScheme[];
+
+// Given a string and a range inside the string, compares it to the given
+// lower-case |compareTo| buffer.
+bool CompareSchemeComponent(const char* spec, const URLComponent&, const char* compareTo);
+bool CompareSchemeComponent(const UChar* spec, const URLComponent&, const char* compareTo);
+
+} // namespace URLUtilities
+
+} // namespace WTF
+
+#endif // USE(WTFURL)
+
+#endif // URLUtilInternal_h
diff --git a/Source/WebCore/CMakeLists.txt b/Source/WebCore/CMakeLists.txt
index 4b0250629..5d06bb550 100644
--- a/Source/WebCore/CMakeLists.txt
+++ b/Source/WebCore/CMakeLists.txt
@@ -1125,6 +1125,7 @@ SET(WebCore_SOURCES
dom/DocumentFragment.cpp
dom/DocumentParser.cpp
dom/DocumentOrderedMap.cpp
+ dom/DocumentStyleSheetCollection.cpp
dom/DocumentType.cpp
dom/DynamicNodeList.cpp
dom/EditingText.cpp
diff --git a/Source/WebCore/ChangeLog b/Source/WebCore/ChangeLog
index c4321a62b..50675f666 100644
--- a/Source/WebCore/ChangeLog
+++ b/Source/WebCore/ChangeLog
@@ -1,3 +1,1627 @@
+2012-09-25 Vsevolod Vlasov <vsevik@chromium.org>
+
+ Web Inspector: ResourceScriptMapping should no steal scripts from other mappings.
+ https://bugs.webkit.org/show_bug.cgi?id=97453
+
+ Reviewed by Pavel Feldman.
+
+ Exposed sourceMapping getter on Script so that resource mapping could check it.
+
+ * inspector/front-end/ResourceScriptMapping.js:
+ (WebInspector.ResourceScriptMapping):
+ (WebInspector.ResourceScriptMapping.prototype._scriptsForSourceURL):
+ (WebInspector.ResourceScriptMapping.prototype._reset):
+
+2012-09-25 Keishi Hattori <keishi@webkit.org>
+
+ REGRESSION(r129448): multiple fields time input UI doesn't use system time format settings on Chromium-Mac
+ https://bugs.webkit.org/show_bug.cgi?id=97517
+
+ Reviewed by Kent Tamura.
+
+ We need to locale [NSLocale currentLocale] if browser language/@lang equals [[NSLocal currentLocale] localeIdentifier]. Otherwise it won't use the custom time format that the user has set.
+
+ No new tests. Unable to test because we need to change system locale settings.
+
+ * platform/text/mac/LocaleMac.h:
+ (LocaleMac):
+ * platform/text/mac/LocaleMac.mm:
+ (WebCore::languageFromLocale): Moved to top.
+ (WebCore):
+ (WebCore::determineLocale): Modified so it takes a locale as an argument.
+ (WebCore::Localizer::create):
+ (WebCore::LocaleMac::LocaleMac): Added checks for invalid locales to this constructor and removed the other one so we don't have duplicated code.
+ (WebCore::LocaleMac::create):
+ (WebCore::LocaleMac::currentLocale):
+
+2012-09-20 Alexander Pavlov <apavlov@chromium.org>
+
+ Web Inspector: Relative URL Link Tooltips do not respect <base>
+ https://bugs.webkit.org/show_bug.cgi?id=43434
+
+ Reviewed by Pavel Feldman.
+
+ New "baseURL" field added into the DOM.Node payload for document nodes and is made use of while resolving and completing URLs.
+
+ * inspector/Inspector.json:
+ * inspector/InspectorDOMAgent.cpp:
+ (WebCore::documentBaseURLString):
+ (WebCore):
+ (WebCore::InspectorDOMAgent::buildObjectForNode):
+ * inspector/front-end/AuditRules.js:
+ (WebInspector.AuditRules.ImageDimensionsRule.prototype.doRun):
+ (WebInspector.AuditRules.CssInHeadRule.prototype.doRun.externalStylesheetsReceived):
+ (WebInspector.AuditRules.StylesScriptsOrderRule.prototype.doRun.cssBeforeInlineReceived):
+ * inspector/front-end/DOMAgent.js:
+ (WebInspector.DOMNode.prototype.resolveURL):
+ (WebInspector.DOMDocument):
+
+2012-09-25 Peter Wang <peter.wang@torchmobile.com.cn>
+
+ Web Inspector: The JS code injected by worker inspector shouldn't be evaluated through JSMainThreadExecState
+ https://bugs.webkit.org/show_bug.cgi?id=95341
+
+ Reviewed by Yury Semikhatsky.
+
+ Add extra code to "JSC::InjectedScriptManager" and "JSC::ScriptFunctionCall" to make sure the
+ interfaces of JSMainThreadExecState are invoked only in main thread.
+
+ No new test case for this bug. Without this patch, opening worker inspector will meet failed assert statements.
+
+ * bindings/js/JSInjectedScriptManager.cpp:
+ (WebCore::InjectedScriptManager::createInjectedScript):
+ * bindings/js/ScriptFunctionCall.cpp:
+ (WebCore::ScriptFunctionCall::call):
+
+2012-09-25 Andreas Kling <kling@webkit.org>
+
+ CSSParserString: Avoid pointless String refcount churn in init().
+ <http://webkit.org/b/94748>
+
+ Reviewed by Sam Weinig.
+
+ Have CSSParserString::init() take a const String& instead of a String.
+
+ * css/CSSParserValues.h:
+ (WebCore::CSSParserString::init):
+
+2012-09-25 Alexander Pavlov <apavlov@chromium.org>
+
+ Web Inspector: [Styles] For group selectors, transmit their segments with the "matches" flag
+ https://bugs.webkit.org/show_bug.cgi?id=96999
+
+ Reviewed by Pavel Feldman.
+
+ The CSSRule protocol object has been modified to include a SelectorList object that contains selector-related data.
+ CSSAgent methods that return CSS rule matches will return RuleMatch objects that encapsulate matching CSSRules
+ with indices of matching selectors on the associated selector list, so the additional backend roundtrips
+ from StylesSidebarPane are no longer necessary.
+
+ * inspector/Inspector.json:
+ * inspector/InspectorCSSAgent.cpp:
+ (WebCore::InspectorCSSAgent::getMatchedStylesForNode):
+ (WebCore::InspectorCSSAgent::buildObjectForRule):
+ (WebCore):
+ (WebCore::InspectorCSSAgent::buildArrayForRuleList):
+ (WebCore::InspectorCSSAgent::buildArrayForMatchedRuleList):
+ * inspector/InspectorCSSAgent.h:
+ (InspectorCSSAgent):
+ * inspector/InspectorStyleSheet.cpp:
+ (WebCore::InspectorStyleSheet::buildObjectForSelectorList):
+ (WebCore):
+ (WebCore::InspectorStyleSheet::buildObjectForRule):
+ * inspector/InspectorStyleSheet.h:
+ (InspectorStyleSheet):
+ * inspector/front-end/CSSStyleModel.js:
+ (WebInspector.CSSStyleModel.parseRuleMatchArrayPayload):
+ (WebInspector.CSSStyleModel.prototype.getMatchedStylesAsync):
+ (WebInspector.CSSRule):
+ (WebInspector.CSSRule.parsePayload):
+ * inspector/front-end/StylesSidebarPane.js:
+ (WebInspector.StylesSidebarPane.prototype._innerRebuildUpdate):
+ (WebInspector.StylesSidebarPane.prototype._rebuildSectionsForStyleRules):
+ (WebInspector.StylePropertiesSection.prototype._markSelectorMatches):
+ (WebInspector.StylePropertiesSection.prototype._moveEditorFromSelector):
+ (WebInspector.StylePropertiesSection.prototype.editingSelectorCancelled):
+
+2012-09-25 MORITA Hajime <morrita@google.com>
+
+ adoptNode() shouldn't reset ownerDocument if the source node failed to remove itself
+ https://bugs.webkit.org/show_bug.cgi?id=97527
+
+ Reviewed by Ryosuke Niwa.
+
+ Document::adoptNode() overlooked an error which can happen in Node::removeChild().
+ Which results an assertion failure. This change adds an error check for that code path.
+
+ Test: fast/dom/adopt-node-prevented.html
+
+ * dom/Document.cpp:
+ (WebCore::Document::adoptNode):
+
+2012-09-21 Ilya Tikhonovsky <loislo@chromium.org>
+
+ Web Inspector: extract Vector instrumentation from core NMI code into MemoryInstrumentationVector.h header.
+ https://bugs.webkit.org/show_bug.cgi?id=96650
+
+ Reviewed by Vsevolod Vlasov.
+
+ addInstrumentedVector and addInstrumentedVectorPtr were replaced with addMember.
+ The same thing happens with addVector and addVectorPtr.
+
+ * css/CSSGradientValue.cpp:
+ (WebCore::CSSGradientValue::reportBaseClassMemoryUsage):
+ * css/CSSImageSetValue.cpp:
+ (WebCore::CSSImageSetValue::reportDescendantMemoryUsage):
+ * css/CSSMediaRule.cpp:
+ (WebCore::CSSMediaRule::reportDescendantMemoryUsage):
+ * css/CSSRuleList.cpp:
+ (WebCore::StaticCSSRuleList::reportMemoryUsage):
+ * css/CSSStyleSheet.cpp:
+ (WebCore::CSSStyleSheet::reportMemoryUsage):
+ * css/CSSValueList.cpp:
+ (WebCore::CSSValueList::reportDescendantMemoryUsage):
+ * css/MediaList.cpp:
+ (WebCore::MediaQuerySet::reportMemoryUsage):
+ * css/MediaQuery.cpp:
+ (WebCore::MediaQuery::reportMemoryUsage):
+ * css/StyleResolver.cpp:
+ (WebCore::StyleResolver::collectMatchingRulesForList):
+ * css/StyleRule.cpp:
+ (WebCore::StyleRuleBlock::reportDescendantMemoryUsage):
+ * css/StyleSheetContents.cpp:
+ (WebCore::StyleSheetContents::reportMemoryUsage):
+ * css/WebKitCSSKeyframesRule.cpp:
+ (WebCore::StyleRuleKeyframes::reportDescendantMemoryUsage):
+ (WebCore::WebKitCSSKeyframesRule::reportDescendantMemoryUsage):
+ * css/WebKitCSSRegionRule.cpp:
+ (WebCore::WebKitCSSRegionRule::reportDescendantMemoryUsage):
+ * dom/Document.cpp:
+ (WebCore::Document::reportMemoryUsage):
+ * loader/DocumentLoader.cpp:
+ (WebCore::DocumentLoader::reportMemoryUsage):
+ * platform/network/ResourceRequestBase.cpp:
+ (WebCore::ResourceRequestBase::reportMemoryUsage):
+
+2012-09-25 Vivek Galatage <vivekgalatage@gmail.com>
+
+ REGRESSION(r129346): It broke !ENABLE(INSPECTOR) build
+ https://bugs.webkit.org/show_bug.cgi?id=97490
+
+ Reviewed by Csaba Osztrogonác.
+
+ The dummy class implementation must be under the ENABLE(INSPECTOR)
+ guard. Added them to prevent from braking the build with --minimal
+ option for build-webkit
+
+ No new tests as caused by missing compile guard.
+
+ * testing/Internals.cpp:
+ (WebCore):
+
+2012-09-24 Bo Liu <boliu@chromium.org>
+
+ Reland "Add in-place reload behavior to ImagesEnabled setting" with optimizations
+ https://bugs.webkit.org/show_bug.cgi?id=97055
+
+ Reviewed by Adam Barth.
+
+ Relanding 128780, 128676, 128645. Was reverted in 128914 due to
+ performance regression in Chromium.
+
+ New changes in addition to previously reverted patches:
+
+ Refactored CachedResource::requestResource, loadResource, and
+ revalidateResource. Moved CachedResource::load method to end of
+ requestResource so there is one place where load is called for all
+ resources.
+
+ Added a enum parameter for requestResource and
+ determineRevalidationPolicy so that FrameLoaderClient::allowImage call
+ do not need to be called multiple times.
+
+ Removed CachedImage::load call in requestImage so it is not called
+ twice.
+
+ Removed unnecessary Frame.h includes in CachedResource and
+ CachedImage.
+
+ Removed dead load() method declaration in CachedImage.
+
+ Updated text expectation for two image-permissions tests to reflect
+ the removed calls to allowImage.
+
+ Tests: fast/loader/display-image-unset-allows-cached-image-load.html
+ fast/loader/display-image-unset-can-block-image-and-can-reload-in-place.html
+ fast/loader/images-enabled-unset-can-block-image-and-can-reload-in-place.html
+
+ * WebCore.exp.in:
+ * loader/FrameLoader.cpp:
+ (WebCore::FrameLoader::didBeginDocument):
+ * loader/SubresourceLoader.cpp:
+ (WebCore::SubresourceLoader::willSendRequest):
+ * loader/cache/CachedImage.cpp:
+ * loader/cache/CachedImage.h:
+ * loader/cache/CachedResource.cpp:
+ (WebCore::CachedResource::didAddClient):
+ * loader/cache/CachedResource.h:
+ (WebCore):
+ (WebCore::CachedResource::stillNeedsLoad):
+ * loader/cache/CachedResourceLoader.cpp:
+ (WebCore::CachedResourceLoader::CachedResourceLoader):
+ (WebCore::CachedResourceLoader::requestImage):
+ (WebCore::CachedResourceLoader::canRequest):
+ (WebCore::CachedResourceLoader::requestResource):
+ (WebCore::CachedResourceLoader::revalidateResource):
+ (WebCore::CachedResourceLoader::loadResource):
+ (WebCore::CachedResourceLoader::determineRevalidationPolicy):
+ (WebCore::CachedResourceLoader::setAutoLoadImages):
+ (WebCore):
+ (WebCore::CachedResourceLoader::setImagesEnabled):
+ (WebCore::CachedResourceLoader::clientDefersImage):
+ (WebCore::CachedResourceLoader::shouldDeferImageLoad):
+ (WebCore::CachedResourceLoader::reloadImagesIfNotDeferred):
+ * loader/cache/CachedResourceLoader.h:
+ (CachedResourceLoader):
+ * page/Settings.cpp:
+ (WebCore::setImageLoadingSettings):
+ (WebCore::Settings::Settings):
+ (WebCore::Settings::setLoadsImagesAutomatically):
+ (WebCore::Settings::imageLoadingSettingsTimerFired):
+ (WebCore::Settings::setImagesEnabled):
+ * page/Settings.h:
+ (Settings):
+ * testing/InternalSettings.cpp:
+ (WebCore::InternalSettings::Backup::Backup):
+ (WebCore::InternalSettings::Backup::restoreTo):
+ (WebCore::InternalSettings::setImagesEnabled):
+ (WebCore):
+ * testing/InternalSettings.h:
+ (Backup):
+ (InternalSettings):
+ * testing/InternalSettings.idl:
+
+2012-09-24 Filip Pizlo <fpizlo@apple.com>
+
+ SerializedScriptValue isn't aware of indexed storage, but should be
+ https://bugs.webkit.org/show_bug.cgi?id=97515
+ <rdar://problem/12361874>
+
+ Reviewed by Sam Weinig.
+
+ New test: fast/js/post-message-numeric-property.html
+
+ * bindings/js/SerializedScriptValue.cpp:
+ (WebCore::CloneDeserializer::putProperty):
+
+2012-09-24 Gavin Barraclough <barraclough@apple.com>
+
+ Remove JSObject::unwrappedGlobalObject(), JSObject::unwrappedObject()
+ https://bugs.webkit.org/show_bug.cgi?id=97519
+
+ Reviewed by Geoff Garen.
+
+ JSDOMWindowShell::setWindow should update the structure's globalObject.
+
+ * bindings/js/JSDOMWindowShell.h:
+ (WebCore::JSDOMWindowShell::setWindow):
+ - Update the JSDOMWindowShell's structure's globalObject when the
+ window changes.
+
+2012-09-24 Yoshifumi Inoue <yosin@chromium.org>
+
+ [Forms] We should remove DateTimeEditElement::valueAsDouble()
+ https://bugs.webkit.org/show_bug.cgi?id=97327
+
+ Reviewed by Kent Tamura.
+
+ This patch removes unused function DateTimeEditElement::valueAsDouble()
+ and related functions in DateTimeFieldElement.
+
+ This patch affects ports which enable both ENABLE_INPUT_TYPE_TIME and
+ ENABLE_INPUT_TYPE_TIME_MULTIPLE_FIELDS.
+
+ No new tests. This patch doesn't change behavior.
+
+ * html/shadow/DateTimeEditElement.cpp: Removed valueAsDouble() implementation.
+ * html/shadow/DateTimeEditElement.h: Removed valueAsDouble() declaration.
+ (DateTimeEditElement):
+ * html/shadow/DateTimeFieldElement.cpp: Removed valueAsDouble() implementation.
+ * html/shadow/DateTimeFieldElement.h: Removed unitInMillisecond() and valueAsDouble() declarations.
+ (DateTimeFieldElement):
+ * html/shadow/DateTimeFieldElements.cpp: Removed unitInMillisecond() implementations.
+ * html/shadow/DateTimeFieldElements.h:
+ (DateTimeAMPMFieldElement): Removed unitInMillisecond() declaration.
+ (DateTimeHourFieldElement): ditto.
+ (DateTimeMillisecondFieldElement): ditto.
+ (DateTimeMinuteFieldElement): ditto.
+ (DateTimeSecondFieldElement): ditto.
+
+2012-09-24 Antti Koivisto <antti@apple.com>
+
+ Don't use StyleSheetList internally.
+ https://bugs.webkit.org/show_bug.cgi?id=97504
+
+ Reviewed by Ryosuke Niwa.
+
+ StyleSheetList is a DOM type and should not be used internally. Use plain Vector instead and construct StyleSheetList on DOM access only.
+
+ * css/StyleResolver.cpp:
+ (WebCore::StyleResolver::StyleResolver):
+ (WebCore::StyleResolver::addStylesheetsFromSeamlessParents):
+ (WebCore::StyleResolver::collectMatchingRulesForList):
+ * css/StyleSheetList.cpp:
+ (WebCore::StyleSheetList::StyleSheetList):
+ (WebCore::StyleSheetList::styleSheets):
+ (WebCore):
+ (WebCore::StyleSheetList::detachFromDocument):
+
+ Use live stylesheet vector of the documents stylesheet collection as long as we are attached to a document.
+ When detached copy the stylesheet vector to a member field and use that instead.
+
+ (WebCore::StyleSheetList::length):
+ (WebCore::StyleSheetList::item):
+ (WebCore::StyleSheetList::getNamedItem):
+ * css/StyleSheetList.h:
+
+ Removed StyleSheetVector typedef as Vector<RefPtr<StyleSheet> > is less opaque and not much longer.
+
+ (WebCore):
+ (WebCore::StyleSheetList::create):
+ (StyleSheetList):
+ (WebCore::StyleSheetList::document):
+ * dom/Document.cpp:
+ (WebCore::Document::~Document):
+ (WebCore::Document::setCompatibilityMode):
+ (WebCore::Document::styleSheets):
+ * dom/Document.h:
+ (Document):
+ * dom/DocumentStyleSheetCollection.cpp:
+ (WebCore::DocumentStyleSheetCollection::DocumentStyleSheetCollection):
+ (WebCore::DocumentStyleSheetCollection::~DocumentStyleSheetCollection):
+ (WebCore::DocumentStyleSheetCollection::analyzeStyleSheetChange):
+ (WebCore::DocumentStyleSheetCollection::updateActiveStyleSheets):
+ * dom/DocumentStyleSheetCollection.h:
+ (WebCore::DocumentStyleSheetCollec
+
+2012-09-24 Laszlo Gombos <l.gombos@samsung.com>
+
+ [GTK][EFL] Remove cairo prefix from include statements
+ https://bugs.webkit.org/show_bug.cgi?id=97509
+
+ Reviewed by Gyuyoung Kim.
+
+ Make the build system consistent by always assuming that directory
+ that includes the cairo headers is included in the include path.
+
+ No new tests as there is no new functionality.
+
+ * platform/cairo/WidgetBackingStoreCairo.cpp:
+ * platform/gtk/GtkWidgetBackingStoreX11.cpp:
+ * plugins/gtk/PluginViewGtk.cpp:
+
+2012-09-24 Yoshifumi Inoue <yosin@chromium.org>
+
+ Document::adoptNode for multiple fields time input UI should not crash
+ https://bugs.webkit.org/show_bug.cgi?id=97428
+
+ Reviewed by Dimitri Glazkov.
+
+ This patch changes Document::removeFocusedNodeOfSubtree() to check
+ focused node in shadow DOM tree for avoiding Document::m_focusedNode
+ not to have dangling pointer to field owner in DateTimeFieldElement.
+
+ Test:
+ - fast/dom/shadow/shadow-removechild-and-blur-event.html: test for removeChild dispatches blur event.
+ - fast/forms/time-multiple-fields/time-multiple-fields-crash-after-adoptnode.html: test for adoptNode not to crash.
+ - fast/forms/time-multiple-fields/time-multiple-fields-state-change-on-focus-or-blur.html: removeChild of input type "time" dispatches blur event, existing test.
+
+ * dom/Document.cpp:
+ (WebCore::Document::removeFocusedNodeOfSubtree): Changed to check
+ focused node in shadow DOM tree in addition to descendant node.
+
+2012-09-24 Robin Cao <robin.cao@torchmobile.com.cn>
+
+ [Blackberry] Add a software rendering path for media player
+ https://bugs.webkit.org/show_bug.cgi?id=97443
+
+ Reviewed by Yong Li.
+
+ This patch adds a software rendering path for media player. When accelerated rendering
+ is not supported by the media engine for the current media, the rendering will fallback
+ to this software path.
+
+ PR #212386
+ Reviewed internally by Max Feil.
+
+ * platform/graphics/blackberry/MediaPlayerPrivateBlackBerry.cpp:
+ (WebCore::MediaPlayerPrivate::paint):
+ (WebCore::MediaPlayerPrivate::updateStates):
+ (WebCore::MediaPlayerPrivate::supportsAcceleratedRendering):
+ (WebCore):
+ * platform/graphics/blackberry/MediaPlayerPrivateBlackBerry.h:
+ (MediaPlayerPrivate):
+
+2012-09-24 Benjamin Poulain <bpoulain@apple.com>
+
+ Fix Geolocation error reporting in the test support
+ https://bugs.webkit.org/show_bug.cgi?id=97386
+
+ Reviewed by Sam Weinig.
+
+ GeolocationController currently expose GeolocationError which can be either
+ PermissionDenied or PositionUnavailable.
+
+ In practice, only PositionUnavailable is supported and tested, only Chrome
+ somewhat expose PermissionDenied.
+ The correct way to deny the permission is through Geolocation::setIsAllowed().
+
+ This patch does some of the initial cleanup toward that goal, reducing how
+ far GeolocationError is spread.
+
+ * WebCore.exp.in:
+ * WebCore.xcodeproj/project.pbxproj:
+ Mac does not use GeolocationClientMock, it should not be compiled in WebCore.
+
+ * platform/mock/GeolocationClientMock.cpp:
+ (WebCore::GeolocationClientMock::GeolocationClientMock):
+ (WebCore::GeolocationClientMock::setPosition):
+ (WebCore::GeolocationClientMock::setPositionUnavailableError):
+ This method replace setError(). It is limited to PositionUnavailable errors.
+
+ (WebCore::GeolocationClientMock::reset):
+ (WebCore::GeolocationClientMock::controllerTimerFired):
+ (WebCore):
+ (WebCore::GeolocationClientMock::clearError):
+ * platform/mock/GeolocationClientMock.h:
+ (WebCore):
+ (GeolocationClientMock):
+
+2012-09-24 Kent Tamura <tkent@chromium.org>
+
+ [Chromium] Implement ValidationMessageClient for Chromium
+ https://bugs.webkit.org/show_bug.cgi?id=97167
+
+ Reviewed by Hajime Morita.
+
+ * page/ValidationMessageClient.h:
+ Add forward declaration for WTF::String.
+
+2012-09-24 Yoshifumi Inoue <yosin@chromium.org>
+
+ [Forms] DateTimeEditElement should return string value for ease of implementing other date/time input types.
+ https://bugs.webkit.org/show_bug.cgi?id=97303
+
+ Reviewed by Kent Tamura.
+
+ This patch introduces a function DateTimeEditElement::value() for
+ setting internal text value of TimeInputType with new function
+ EditControlOwner::formatDateTimeFieldsState() to utilize this protocl
+ in other date time input types.
+
+ We used DateTimeEditElement::valueAsDouble() and and BaseDateAndTimeInputType::serialize()
+ to make string value then setting internal text value of multiple
+ fields time input UI. Although, this steps doesn't work well for
+ other date/time input types.
+
+ This patch affects ports which enable both ENABLE_INPUT_TYPE_TIME and
+ ENABLE_INPUT_TYPE_TIME_MULTIPLE_FIELDS.
+
+ No new tests. This patch doesn't change behavior.
+
+ * html/DateTimeFieldsState.cpp:
+ (WebCore::DateTimeFieldsState::hour23): Added to convert 1 to 12 hour value to 0 to 23 hour.
+ * html/DateTimeFieldsState.h:
+ (DateTimeFieldsState): Added declaration of hour23().
+ * html/TimeInputType.cpp:
+ (WebCore::TimeInputType::DateTimeEditControlOwnerImpl::editControlValueChanged): Changed to use DateTimeEditElement::value() instead of DateTimeEditElement::valueAsDouble().
+ (WebCore::TimeInputType::DateTimeEditControlOwnerImpl::formatDateTimeFieldsState): Added to format time.
+ (WebCore::TimeInputType::restoreFormControlState): Changed to use DateTimeEditElement::value() instead of DateTimeEditElement::valueAsDouble().
+ * html/TimeInputType.h:
+ (DateTimeEditControlOwnerImpl): Added a declaration of formatDateTimeFieldsState().
+ * html/shadow/DateTimeEditElement.cpp:
+ (WebCore::DateTimeEditElement::value): Added.
+ * html/shadow/DateTimeEditElement.h:
+ (EditControlOwner): Added a declaration of formatDateTimeFieldsState().
+ (DateTimeEditElement): Added a declaration of value().
+
+2012-09-24 Dean Jackson <dino@apple.com>
+
+ [WebGL] Intel Mac needs built-in function emulation
+ https://bugs.webkit.org/show_bug.cgi?id=96140
+
+ Reviewed by Sam Weinig.
+
+ Temporarily turn on built-in function emulation for Intel GPUs
+ on OS X. This is a work-around for a driver bug, and
+ will be removed once the driver is updated:
+ https://bugs.webkit.org/show_bug.cgi?id=97503
+
+ This can be tested using the Khronos WebGL conformance
+ suite, in particular:
+
+ conformance/glsl/functions/glsl-function-dot.html
+ conformance/glsl/functions/glsl-function-length.html
+ conformance/glsl/functions/glsl-function-normalize.html
+ conformance/glsl/functions/glsl-function-reflect.html
+
+ Note that the faceforward built-in will still cause
+ problems on Intel GPUs, but this would require an unnecessary
+ change in the ANGLE project (remember, we're going to
+ remove this code once the driver is fixed).
+
+ * platform/graphics/opengl/Extensions3DOpenGLCommon.cpp:
+ (WebCore::Extensions3DOpenGLCommon::getTranslatedShaderSourceANGLE):
+ Temporarily add "Intel" to the list of GPUs we do translation
+ for in the shader compiler.
+
+2012-09-24 Peter Wang <peter.wang@torchmobile.com.cn>
+
+ There is a mistake in InspectorProfilerAgent::enable(bool skipRecompile)
+ https://bugs.webkit.org/show_bug.cgi?id=97450
+
+ Reviewed by Yury Semikhatsky.
+
+ The "InspectorProfilerAgent::enable()" should invokes "PageScriptDebugServer" in
+ no-worker thread.
+
+ No new test case.
+
+ * inspector/InspectorProfilerAgent.cpp:
+ (WebCore::PageProfilerAgent::recompileScript):
+ (PageProfilerAgent):
+ (WebCore::WorkerProfilerAgent::recompileScript):
+ (WorkerProfilerAgent):
+ (WebCore::InspectorProfilerAgent::disable):
+ (WebCore::InspectorProfilerAgent::enable):
+ * inspector/InspectorProfilerAgent.h:
+ (InspectorProfilerAgent):
+
+2012-09-24 Patrick Gansterer <paroga@webkit.org>
+
+ Remove String::operator+=()
+ https://bugs.webkit.org/show_bug.cgi?id=96172
+
+ Reviewed by Benjamin Poulain.
+
+ Replace the last usage with String::append() in Gtk.
+
+ * platform/gtk/GtkInputMethodFilter.cpp:
+ (WebCore::GtkInputMethodFilter::handleCommit):
+
+2012-09-24 Mark Pilgrim <pilgrim@chromium.org>
+
+ [Chromium][Mac] Remove loadFont from PlatformSupport
+ https://bugs.webkit.org/show_bug.cgi?id=97360
+
+ Reviewed by Adam Barth.
+
+ Part of a refactoring series. See tracking bug 82948.
+
+ * platform/chromium/PlatformSupport.h:
+ (PlatformSupport):
+ * platform/graphics/chromium/CrossProcessFontLoading.mm:
+
+2012-09-24 Tony Chang <tony@chromium.org>
+
+ Replace 2 uses of updateLogicalHeight with computeLogicalHeight
+ https://bugs.webkit.org/show_bug.cgi?id=97486
+
+ Reviewed by Ojan Vafai.
+
+ More work for bug 96804. This is just a refactoring.
+
+ No new tests, behavior should be the same as before.
+
+ * rendering/RenderFlowThread.cpp:
+ (WebCore::RenderFlowThread::computeLogicalHeight):
+ * rendering/RenderFlowThread.h:
+ * rendering/RenderMultiColumnFlowThread.cpp:
+ (WebCore::RenderMultiColumnFlowThread::computeLogicalHeight):
+ (WebCore):
+ * rendering/RenderMultiColumnFlowThread.h:
+ (RenderMultiColumnFlowThread):
+
+2012-09-21 Kenneth Russell <kbr@google.com>
+
+ [V8] ArrayBuffer code should not pass a negative length to SetIndexedPropertiesToExternalArrayData()
+ https://bugs.webkit.org/show_bug.cgi?id=96703
+
+ Reviewed by Adam Barth.
+
+ Check length arguments that may be passed to SetIndexedPropertiesToExternalArrayData.
+
+ No tests because it is not guaranteed that buffers this large can actually be allocated.
+
+ * bindings/v8/custom/V8ArrayBufferViewCustom.h:
+ (WebCore::wrapArrayBufferView):
+ (WebCore::constructWebGLArrayWithArrayBufferArgument):
+ (WebCore::constructWebGLArray):
+
+2012-09-24 Antti Koivisto <antti@apple.com>
+
+ Split stylesheet related code out from Document
+ https://bugs.webkit.org/show_bug.cgi?id=97353
+
+ Reviewed by Andreas Kling.
+
+ Document is big and unwieldy. The code related to tracking active stylesheets can be factored out.
+
+ The patch moves stylesheet upkeep, collection and invalidation code from Document to a separate
+ DocumentStyleSheetCollection class. There are no functional changes.
+
+ The usesLinkRules stylesheet feature bit and the related code is removed as no one was using it.
+
+ * WebCore.xcodeproj/project.pbxproj:
+ * css/SelectorChecker.cpp:
+ (WebCore::SelectorChecker::checkOneSelector):
+ * css/StyleResolver.cpp:
+ (WebCore::StyleResolver::StyleResolver):
+ (WebCore::StyleResolver::Features::Features):
+ (WebCore::StyleResolver::Features::add):
+ (WebCore::StyleResolver::Features::clear):
+ (WebCore::StyleResolver::collectMatchingRulesForList):
+ * css/StyleResolver.h:
+ (WebCore::StyleResolver::usesBeforeAfterRules):
+ (Features):
+ * dom/Document.cpp:
+ (WebCore::Document::Document):
+ (WebCore::Document::~Document):
+ (WebCore::Document::setCompatibilityMode):
+ (WebCore::Document::recalcStyle):
+ (WebCore):
+ (WebCore::Document::createStyleResolver):
+ (WebCore::Document::seamlessParentUpdatedStylesheets):
+ (WebCore::Document::didRemoveAllPendingStylesheet):
+ (WebCore::Document::processHttpEquiv):
+ (WebCore::Document::styleSheets):
+ (WebCore::Document::preferredStylesheetSet):
+ (WebCore::Document::selectedStylesheetSet):
+ (WebCore::Document::setSelectedStylesheetSet):
+ (WebCore::Document::styleResolverChanged):
+ (WebCore::Document::reportMemoryUsage):
+ (WebCore::Document::haveStylesheetsLoaded):
+ * dom/Document.h:
+ (WebCore):
+ (Document):
+ (WebCore::Document::styleSheetCollection):
+ (WebCore::Document::hasNodesWithPlaceholderStyle):
+ (WebCore::Document::setNeedsNotifyRemoveAllPendingStylesheet):
+ (WebCore::Document::inStyleRecalc):
+ * dom/DocumentStyleSheetCollection.cpp: Added.
+ (WebCore):
+ (WebCore::DocumentStyleSheetCollection::DocumentStyleSheetCollection):
+ (WebCore::DocumentStyleSheetCollection::~DocumentStyleSheetCollection):
+ (WebCore::DocumentStyleSheetCollection::pageUserSheet):
+ (WebCore::DocumentStyleSheetCollection::clearPageUserSheet):
+ (WebCore::DocumentStyleSheetCollection::updatePageUserSheet):
+ (WebCore::DocumentStyleSheetCollection::pageGroupUserSheets):
+ (WebCore::DocumentStyleSheetCollection::clearPageGroupUserSheets):
+ (WebCore::DocumentStyleSheetCollection::updatePageGroupUserSheets):
+ (WebCore::DocumentStyleSheetCollection::addUserSheet):
+ (WebCore::DocumentStyleSheetCollection::removePendingSheet):
+ (WebCore::DocumentStyleSheetCollection::addStyleSheetCandidateNode):
+ (WebCore::DocumentStyleSheetCollection::removeStyleSheetCandidateNode):
+ (WebCore::DocumentStyleSheetCollection::collectActiveStyleSheets):
+ (WebCore::DocumentStyleSheetCollection::testAddedStyleSheetRequiresStyleRecalc):
+ (WebCore::DocumentStyleSheetCollection::analyzeStyleSheetChange):
+ (WebCore::styleSheetsUseRemUnits):
+ (WebCore::DocumentStyleSheetCollection::updateActiveStyleSheets):
+ (WebCore::DocumentStyleSheetCollection::combineCSSFeatureFlags):
+ (WebCore::DocumentStyleSheetCollection::resetCSSFeatureFlags):
+ (WebCore::DocumentStyleSheetCollection::reportMemoryUsage):
+ * dom/DocumentStyleSheetCollection.h: Added.
+ (WebCore):
+ (DocumentStyleSheetCollection):
+ (WebCore::DocumentStyleSheetCollection::authorStyleSheets):
+ (WebCore::DocumentStyleSheetCollection::documentUserSheets):
+ (WebCore::DocumentStyleSheetCollection::needsUpdateActiveStylesheetsOnStyleRecalc):
+ (WebCore::DocumentStyleSheetCollection::preferredStylesheetSetName):
+ (WebCore::DocumentStyleSheetCollection::selectedStylesheetSetName):
+ (WebCore::DocumentStyleSheetCollection::setPreferredStylesheetSetName):
+ (WebCore::DocumentStyleSheetCollection::setSelectedStylesheetSetName):
+ (WebCore::DocumentStyleSheetCollection::addPendingSheet):
+ (WebCore::DocumentStyleSheetCollection::hasPendingSheets):
+ (WebCore::DocumentStyleSheetCollection::usesSiblingRules):
+ (WebCore::DocumentStyleSheetCollection::setUsesSiblingRulesOverride):
+ (WebCore::DocumentStyleSheetCollection::usesFirstLineRules):
+ (WebCore::DocumentStyleSheetCollection::usesFirstLetterRules):
+ (WebCore::DocumentStyleSheetCollection::setUsesFirstLetterRules):
+ (WebCore::DocumentStyleSheetCollection::usesBeforeAfterRules):
+ (WebCore::DocumentStyleSheetCollection::setUsesBeforeAfterRulesOverride):
+ (WebCore::DocumentStyleSheetCollection::usesRemUnits):
+ (WebCore::DocumentStyleSheetCollection::setUsesRemUnit):
+ * dom/Element.cpp:
+ (WebCore::Element::recalcStyle):
+ * dom/ProcessingInstruction.cpp:
+ (WebCore::ProcessingInstruction::~ProcessingInstruction):
+ (WebCore::ProcessingInstruction::checkStyleSheet):
+ (WebCore::ProcessingInstruction::sheetLoaded):
+ (WebCore::ProcessingInstruction::insertedInto):
+ (WebCore::ProcessingInstruction::removedFrom):
+ * dom/StyleElement.cpp:
+ (WebCore::StyleElement::insertedIntoDocument):
+ (WebCore::StyleElement::removedFromDocument):
+ (WebCore::StyleElement::clearDocumentData):
+ (WebCore::StyleElement::createSheet):
+ (WebCore::StyleElement::sheetLoaded):
+ (WebCore::StyleElement::startLoadingDynamicSheet):
+ * html/HTMLLinkElement.cpp:
+ (WebCore::HTMLLinkElement::~HTMLLinkElement):
+ (WebCore::HTMLLinkElement::insertedInto):
+ (WebCore::HTMLLinkElement::removedFrom):
+ (WebCore::HTMLLinkElement::addPendingSheet):
+ (WebCore::HTMLLinkElement::removePendingSheet):
+ * html/HTMLQuoteElement.cpp:
+ (WebCore::HTMLQuoteElement::insertedInto):
+ * html/HTMLViewSourceDocument.cpp:
+ (WebCore::HTMLViewSourceDocument::HTMLViewSourceDocument):
+ * mathml/MathMLMathElement.cpp:
+ (WebCore::MathMLMathElement::insertedInto):
+ * page/Page.cpp:
+ (WebCore::Page::userStyleSheetLocationChanged):
+ * page/PageGroup.cpp:
+ (WebCore::PageGroup::resetUserStyleCacheInAllFrames):
+ * rendering/RenderBR.cpp:
+ (WebCore::RenderBR::lineHeight):
+ * rendering/RenderBlock.cpp:
+ (WebCore::RenderBlock::styleDidChange):
+ (WebCore::RenderBlock::splitBlocks):
+ (WebCore::RenderBlock::addChildIgnoringAnonymousColumnBlocks):
+ (WebCore::RenderBlock::lineHeight):
+ (WebCore::RenderBlock::updateFirstLetter):
+ * rendering/RenderInline.cpp:
+ (WebCore::RenderInline::styleDidChange):
+ (WebCore::RenderInline::updateAlwaysCreateLineBoxes):
+ (WebCore::RenderInline::addChildIgnoringContinuation):
+ (WebCore::RenderInline::splitInlines):
+ (WebCore::RenderInline::lineHeight):
+ * rendering/RenderObject.cpp:
+ (WebCore::RenderObject::uncachedFirstLineStyle):
+ (WebCore::RenderObject::firstLineStyleSlowCase):
+ * rendering/RenderObject.h:
+ (WebCore::RenderObject::firstLineStyle):
+ * rendering/RenderObjectChildList.cpp:
+ (WebCore::RenderObjectChildList::updateBeforeAfterContent):
+ * rendering/RenderTableRow.cpp:
+ (WebCore::RenderTableRow::updateBeforeAndAfterContent):
+ * rendering/RootInlineBox.cpp:
+ (WebCore::RootInlineBox::verticalPositionForBox):
+
+2012-09-24 Otto Derek Cheung <otcheung@rim.com>
+
+ [BlackBerry] Reverting implementation for 407 error pages
+ https://bugs.webkit.org/show_bug.cgi?id=97455
+
+ Reviewed by Rob Buis.
+
+ Revert "[BlackBerry] Reverting implementation for 407 error pages"
+ This reverts commit fda0a1b6ac40c06c03bb6293b4a7d7353c3ca238.
+
+ This revert also reverts commit 0cffe01961fb80204138505bcec29a83818efb73
+ due to dependency issues.
+
+ * PlatformBlackBerry.cmake:
+ * platform/blackberry/AuthenticationChallengeManager.cpp: Removed.
+ * platform/blackberry/AuthenticationChallengeManager.h:
+ * platform/blackberry/PageClientBlackBerry.h:
+ * platform/graphics/blackberry/MediaPlayerPrivateBlackBerry.cpp:
+ (WebCore::MediaPlayerPrivate::MediaPlayerPrivate):
+ (WebCore::MediaPlayerPrivate::~MediaPlayerPrivate):
+ (WebCore::MediaPlayerPrivate::onAuthenticationNeeded):
+ (WebCore::MediaPlayerPrivate::notifyChallengeResult):
+ * platform/graphics/blackberry/MediaPlayerPrivateBlackBerry.h:
+ (MediaPlayerPrivate):
+ * platform/network/blackberry/NetworkJob.cpp:
+ (WebCore::NetworkJob::NetworkJob):
+ (WebCore::NetworkJob::handleNotifyStatusReceived):
+ (WebCore::NetworkJob::notifyAuthReceived):
+ (WebCore::NetworkJob::handleNotifyClose):
+ (WebCore::NetworkJob::sendRequestWithCredentials):
+ (WebCore::NetworkJob::notifyChallengeResult):
+ * platform/network/blackberry/NetworkJob.h:
+ (NetworkJob):
+
+2012-09-24 Chris Rogers <crogers@google.com>
+
+ [REGRESSION] Layout Test webaudio/biquad-getFrequencyResponse.html is failing
+ https://bugs.webkit.org/show_bug.cgi?id=97439
+
+ Reviewed by Kenneth Russell.
+
+ Fixes uninitialized member variable.
+
+ This should fix flaky failing test: webaudio/biquad-getFrequencyResponse.html
+
+ * Modules/webaudio/BiquadProcessor.cpp:
+ (WebCore::BiquadProcessor::BiquadProcessor):
+
+2012-09-24 Tony Chang <tony@chromium.org>
+
+ flex-grow should be 1 when omitted from flex shorthand
+ https://bugs.webkit.org/show_bug.cgi?id=97480
+
+ Reviewed by Ojan Vafai.
+
+ We were using 0, based on an outdated version of the spec.
+
+ Tests: css3/flexbox/flex-property-parsing.html
+ css3/flexbox/flex-algorithm.html: New test case.
+
+ * css/CSSParser.cpp:
+ (WebCore::CSSParser::parseFlex):
+
+2012-09-24 Benjamin Poulain <benjamin@webkit.org>
+
+ Add support for query encoding to WTFURL
+ https://bugs.webkit.org/show_bug.cgi?id=97422
+
+ Reviewed by Adam Barth.
+
+ Add the Charset conversion on WebCore side.
+
+ * platform/KURLWTFURL.cpp:
+ (WebCore::KURL::KURL):
+ (CharsetConverter):
+ (WebCore::CharsetConverter::CharsetConverter):
+ * platform/mac/KURLMac.mm:
+ (WebCore::KURL::KURL):
+
+2012-09-24 Benjamin Poulain <benjamin@webkit.org>
+
+ Integrate most of GoogleURL in WTFURL
+ https://bugs.webkit.org/show_bug.cgi?id=97405
+
+ Reviewed by Adam Barth.
+
+ Loosen KURLWTFURL to be able to run most tests in Debug.
+
+ * platform/KURLWTFURL.cpp:
+ (WebCore::KURL::KURL):
+ (WebCore::KURL::hasPort):
+ (WebCore::KURL::user):
+ (WebCore::KURL::pass):
+ (WebCore::KURL::hasPath):
+ (WebCore::KURL::path):
+ (WebCore::KURL::query):
+ (WebCore::KURL::fragmentIdentifier):
+ (WebCore::KURL::fileSystemPath):
+
+2012-09-24 Hans Muller <hmuller@adobe.com>
+
+ [CSS Exclusions] ExclusionShape API should use logical coordinates for input/output
+ https://bugs.webkit.org/show_bug.cgi?id=96156
+
+ Reviewed by Dirk Schulze.
+
+ Correct how ExclusionShapes deal with logical coordinates and enable
+ shape-inside exclusion layout for vertical writing-modes.
+
+ BasicShape's are defined in physical cooordinates, incoming line and box
+ dimensions are logical coordinates, and the ExclusionShape internals assume
+ that lines are aligned with the Y axis. The createExclusionShape() method
+ is responsible for converting the BasicShape to the internal coordinate
+ system when the writing-mode is vertical. Similarly, the getInclude,ExcludedIntervals()
+ methods are responsible for converting their logical line parameters to Y
+ values in the internal coordinate system. The min,maxYForLogicalLine()
+ methods do the conversion, based on the WritingMode the ExclusionShape
+ was created with. The getInclude,ExcludedIntervals() methods return the
+ logical left and right edges of line segments. No transformation is needed for this.
+
+ The ExclusionShape's internal coordinate system is essentially the
+ "logical" one, except that top/bottom always map to Y, no matter what
+ the writing-mode is. This is just to simplify writing geometrical shape
+ algorithms, notably the complex ones for polygons. The bug report includes a
+ pair of diagrams that clarify how internal coordinates are related to logical
+ and physical coordinates.
+
+ Test: fast/exclusions/shape-inside/shape-inside-vertical-text.html
+
+ * rendering/ExclusionRectangle.cpp:
+ (WebCore::ExclusionRectangle::getExcludedIntervals): rename more accurately reflects return value
+ (WebCore::ExclusionRectangle::getIncludedIntervals): rename for consistency with "excluded" version
+ * rendering/ExclusionRectangle.h:
+ * rendering/ExclusionShape.cpp:
+ (WebCore):
+ (WebCore::ExclusionShape::createExclusionShape):
+ * rendering/ExclusionShape.h:
+ (LineSegment):
+ (WebCore::LineSegment::LineSegment): relocated from WrapShapeInfo.h
+ (WebCore):
+ (ExclusionShape):
+ (WebCore::ExclusionShape::minYForLogicalLine):
+ (WebCore::ExclusionShape::maxYForLogicalLine):
+ (WebCore::ExclusionShape::internalToLogicalBoundingBox):
+ * rendering/WrapShapeInfo.cpp:
+ (WebCore::WrapShapeInfo::isWrapShapeInfoEnabledForRenderBlock):
+ (WebCore::WrapShapeInfo::computeShapeSize): pass writingMode to createExclusionShape()
+ (WebCore::WrapShapeInfo::computeSegmentsForLine): removed short-circuit for vertical writing-modes
+ * rendering/WrapShapeInfo.h:
+ (WebCore):
+
+2012-09-24 Tony Chang <tony@chromium.org>
+
+ Replace RenderMeter::updateLogicalHeight to RenderMeter::computeLogicalHeight
+ https://bugs.webkit.org/show_bug.cgi?id=97475
+
+ Reviewed by Ojan Vafai.
+
+ Using RenderMeter::computeLogicalHeight is part of bug 96804.
+ Also fix some code to be vertical writing mode aware. This doesn't actually cause
+ a behavioral difference because we use percentage heights/widths which don't depend on
+ updateLogicalWidth or computeLogicalHeight. You can still see bugs if you try to set
+ the min-width on a <meter> node in a vertical writing mode.
+
+ No new tests, no behavioral changes.
+
+ * rendering/RenderMeter.cpp:
+ (WebCore::RenderMeter::updateLogicalWidth): Make vertical writing mode aware.
+ (WebCore::RenderMeter::computeLogicalHeight): Switch from updateLogicalHeight and make vertical writing mode aware.
+ * rendering/RenderMeter.h:
+ (RenderMeter):
+
+2012-09-24 Dimitri Glazkov <dglazkov@chromium.org>
+
+ Remove unbaked support for :scope pseudo-class.
+ https://bugs.webkit.org/show_bug.cgi?id=97467
+
+ Reviewed by Antti Koivisto.
+
+ It turns out, the Selectors 4 require ":scope" to match contextual reference element set, which would be the root node in querySelector:
+ http://dev.w3.org/csswg/selectors4/#the-scope-pseudo
+
+ Right now, we simply make ":scope" equivalent to ":root", which is not correct. Let's remove the partial implementation until we have
+ time/energy to fully implement it.
+
+ No new tests, removing half-baked feature.
+
+ * css/CSSSelector.cpp:
+ (WebCore::CSSSelector::pseudoId): Removed all mentions of PseudoScope
+ (WebCore::nameToPseudoTypeMap): Ditto.
+ (WebCore::CSSSelector::extractPseudoType): Ditto.
+ * css/CSSSelector.h: Ditto.
+ * css/SelectorChecker.cpp:
+ (WebCore::SelectorChecker::checkOneSelector): Ditto.
+
+2012-09-24 Ryosuke Niwa <rniwa@webkit.org>
+
+ suspend/resumeWidgetHierarchyUpdates should be a RAII object
+ https://bugs.webkit.org/show_bug.cgi?id=96706
+
+ Reviewed by Simon Fraser.
+
+ Replaced suspendWidgetHierarchyUpdates and resumeWidgetHierarchyUpdates by WidgetHierarchyUpdatesSuspensionScope.
+
+ * WebCore.exp.in: Export new symbols.
+ * dom/ContainerNode.cpp:
+ (WebCore::ContainerNode::removeChild):
+ (WebCore::ContainerNode::removeChildren):
+ * dom/Document.cpp:
+ (WebCore::Document::recalcStyle):
+ * dom/Element.cpp:
+ (WebCore::Element::attach):
+ (WebCore::Element::detach):
+ * page/mac/EventHandlerMac.mm:
+ (WebCore::EventHandler::passMouseDownEventToWidget):
+ * rendering/RenderWidget.cpp:
+ (WebCore):
+ (WebCore::WidgetHierarchyUpdatesSuspensionScope::widgetNewParentMap):
+ (WebCore::WidgetHierarchyUpdatesSuspensionScope::moveWidgets):
+ (WebCore::moveWidgetToParentSoon):
+ * rendering/RenderWidget.h:
+ (WidgetHierarchyUpdatesSuspensionScope):
+ (WebCore::WidgetHierarchyUpdatesSuspensionScope::WidgetHierarchyUpdatesSuspensionScope):
+ (WebCore::WidgetHierarchyUpdatesSuspensionScope::~WidgetHierarchyUpdatesSuspensionScope):
+ (WebCore::WidgetHierarchyUpdatesSuspensionScope::isSuspended):
+ (WebCore::WidgetHierarchyUpdatesSuspensionScope::scheduleWidgetToMove):
+ (WebCore):
+ (RenderWidget):
+
+2012-09-24 Otto Derek Cheung <otcheung@rim.com>
+
+ [BlackBerry] Reverting implementation for 407 error pages
+ https://bugs.webkit.org/show_bug.cgi?id=97455
+
+ Reviewed by Rob Buis.
+
+ Revert "[BlackBerry] Show custom error page when 407 is received"
+ This reverts commit e6d14529428fe47916fcb997528095b8acad2f2b.
+
+ * platform/network/blackberry/NetworkJob.cpp:
+ (WebCore::NetworkJob::handleNotifyStatusReceived):
+ (WebCore::NetworkJob::notifyAuthReceived):
+ (WebCore::NetworkJob::sendRequestWithCredentials):
+
+2012-09-24 Sheriff Bot <webkit.review.bot@gmail.com>
+
+ Unreviewed, rolling out r129388.
+ http://trac.webkit.org/changeset/129388
+ https://bugs.webkit.org/show_bug.cgi?id=97477
+
+ Caused an assertion in a WebKit2 unit test (Requested by
+ abarth on #webkit).
+
+ * WebCore.exp.in:
+ * loader/FrameLoader.cpp:
+ (WebCore::FrameLoader::didBeginDocument):
+ * loader/SubresourceLoader.cpp:
+ (WebCore::SubresourceLoader::willSendRequest):
+ * loader/cache/CachedImage.cpp:
+ * loader/cache/CachedImage.h:
+ (WebCore::CachedImage::stillNeedsLoad):
+ (CachedImage):
+ * loader/cache/CachedResource.cpp:
+ (WebCore::CachedResource::didAddClient):
+ * loader/cache/CachedResource.h:
+ (WebCore):
+ * loader/cache/CachedResourceLoader.cpp:
+ (WebCore::CachedResourceLoader::CachedResourceLoader):
+ (WebCore::CachedResourceLoader::requestImage):
+ (WebCore::CachedResourceLoader::canRequest):
+ (WebCore::CachedResourceLoader::requestResource):
+ (WebCore::CachedResourceLoader::revalidateResource):
+ (WebCore::CachedResourceLoader::loadResource):
+ (WebCore::CachedResourceLoader::determineRevalidationPolicy):
+ (WebCore::CachedResourceLoader::setAutoLoadImages):
+ * loader/cache/CachedResourceLoader.h:
+ (CachedResourceLoader):
+ * page/Settings.cpp:
+ (WebCore::setLoadsImagesAutomaticallyInAllFrames):
+ (WebCore::Settings::Settings):
+ (WebCore::Settings::setLoadsImagesAutomatically):
+ (WebCore::Settings::loadsImagesAutomaticallyTimerFired):
+ (WebCore::Settings::setImagesEnabled):
+ * page/Settings.h:
+ (Settings):
+ * testing/InternalSettings.cpp:
+ (WebCore::InternalSettings::Backup::Backup):
+ (WebCore::InternalSettings::Backup::restoreTo):
+ * testing/InternalSettings.h:
+ (Backup):
+ (InternalSettings):
+ * testing/InternalSettings.idl:
+
+2012-09-24 Erik Arvidsson <arv@chromium.org>
+
+ DOM4 remove method
+ https://bugs.webkit.org/show_bug.cgi?id=73885
+
+ Reviewed by Ojan Vafai.
+
+ This adds the DOM 4 remove method.
+
+ http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#dom-childnode-remove
+
+ The remove method removes the node from its parent if it has a parent.
+
+ Tests: fast/dom/Comment/remove.html
+ fast/dom/DocumentType/remove.html
+ fast/dom/Element/remove.html
+ fast/dom/Text/remove.html
+
+ * dom/CharacterData.idl:
+ * dom/DocumentType.idl:
+ * dom/Element.idl:
+ * dom/Node.cpp:
+ (WebCore::Node::remove): The spec says to do nothing if the node has no parent.
+ * html/parser/HTMLTreeBuilder.cpp:
+ (WebCore::HTMLTreeBuilder::processStartTagForInBody): Cleanup.
+ * html/track/TextTrackCue.cpp:
+ (WebCore::TextTrackCue::removeDisplayTree): No need to check parenNode twice.
+
+2012-09-24 Tommy Widenflycht <tommyw@google.com>
+
+ MediaStream API: Fix the incorrectly spelled RTCPeerConnection::onnegotiationneeded callback
+ https://bugs.webkit.org/show_bug.cgi?id=97456
+
+ Reviewed by Adam Barth.
+
+ Renamed onnegotationneeded to onnegotiationneeded.
+
+ Existing test updated.
+
+ * Modules/mediastream/RTCPeerConnection.cpp:
+ (WebCore::RTCPeerConnection::negotiationNeeded):
+ * Modules/mediastream/RTCPeerConnection.h:
+ (RTCPeerConnection):
+ * Modules/mediastream/RTCPeerConnection.idl:
+ * dom/EventNames.h:
+ (WebCore):
+
+2012-09-24 Peter Beverloo <peter@chromium.org>
+
+ Android's mock scrollbars shows up as a difference in layout test results
+ https://bugs.webkit.org/show_bug.cgi?id=96382
+
+ Reviewed by Adam Barth.
+
+ Remove the exceptions made for layout tests in Android's scrollbar theme.
+ This will make our actual scrollbars show up in layout test pixel results,
+ bringing the tests closer to what we actually ship.
+
+ An important difference with other platforms is that scrollbars do not
+ take any width on Android, they're rendered on top of the content. Therefore
+ each test that has a visible scrollbar does not just need a new pixel
+ result, but will also need a new text result. This will be handled as part
+ of a larger rebaselining process.
+
+ Will be exercised by every layout test that has a scrollbar.
+
+ * platform/chromium/ScrollbarThemeChromiumAndroid.cpp:
+ (WebCore::ScrollbarThemeChromiumAndroid::scrollbarThickness):
+ (WebCore::ScrollbarThemeChromiumAndroid::usesOverlayScrollbars):
+ (WebCore::ScrollbarThemeChromiumAndroid::hasThumb):
+ * platform/chromium/ScrollbarThemeChromiumAndroid.h:
+ (ScrollbarThemeChromiumAndroid):
+
+2012-09-24 Sean Wang <Xuewen.Wang@torchmobile.com.cn>
+
+ [BlackBerry] Basic authentication challenge credentials for stored credentials again after restarting browser
+ https://bugs.webkit.org/show_bug.cgi?id=96362
+
+ Reviewed by Rob Buis.
+
+ Fix a mistake of the commit 11fdc73c7c74bbd736ed4160248ff59636a01864
+ Trunk has been changed during reviewing that patch.
+
+ No new tests, this is to correct a build error.
+
+ * platform/network/blackberry/CredentialBackingStore.cpp:
+ (WebCore::CredentialBackingStore::getProtectionSpace):
+
+2012-09-24 Dan Bernstein <mitz@apple.com>
+
+ Reverted r129176, the fix for <http://webkit.org/b/97269>, because it introduced a
+ discrepancy between line breaking and max width computation.
+
+ Rubber-stamped by Anders Carlsson.
+
+ * platform/graphics/mac/ComplexTextController.cpp:
+ (WebCore::ComplexTextController::adjustGlyphsAndAdvances):
+
+2012-09-24 Bo Liu <boliu@chromium.org>
+
+ Reland "Add in-place reload behavior to ImagesEnabled setting" with optimizations
+ https://bugs.webkit.org/show_bug.cgi?id=97055
+
+ Reviewed by Adam Barth.
+
+ Relanding 128780, 128676, 128645. Was reverted in 128914 due to
+ performance regression in Chromium.
+
+ New changes in addition to previously reverted patches:
+
+ Refactored CachedResource::requestResource, loadResource, and
+ revalidateResource. Moved CachedResource::load method to end of
+ requestResource so there is one place where load is called for all
+ resources.
+
+ Added a enum parameter for requestResource and
+ determineRevalidationPolicy so that FrameLoaderClient::allowImage call
+ do not need to be called multiple times.
+
+ Removed CachedImage::load call in requestImage so it is not called
+ twice.
+
+ Removed unnecessary Frame.h includes in CachedResource and
+ CachedImage.
+
+ Removed dead load() method declaration in CachedImage.
+
+ Updated text expectation for two image-permissions tests to reflect
+ the removed calls to allowImage.
+
+ Tests: fast/loader/display-image-unset-allows-cached-image-load.html
+ fast/loader/display-image-unset-can-block-image-and-can-reload-in-place.html
+ fast/loader/images-enabled-unset-can-block-image-and-can-reload-in-place.html
+
+ * WebCore.exp.in:
+ * loader/FrameLoader.cpp:
+ (WebCore::FrameLoader::didBeginDocument):
+ * loader/SubresourceLoader.cpp:
+ (WebCore::SubresourceLoader::willSendRequest):
+ * loader/cache/CachedImage.cpp:
+ * loader/cache/CachedImage.h:
+ * loader/cache/CachedResource.cpp:
+ (WebCore::CachedResource::didAddClient):
+ * loader/cache/CachedResource.h:
+ (WebCore):
+ (WebCore::CachedResource::stillNeedsLoad):
+ * loader/cache/CachedResourceLoader.cpp:
+ (WebCore::CachedResourceLoader::CachedResourceLoader):
+ (WebCore::CachedResourceLoader::requestImage):
+ (WebCore::CachedResourceLoader::canRequest):
+ (WebCore::CachedResourceLoader::requestResource):
+ (WebCore::CachedResourceLoader::revalidateResource):
+ (WebCore::CachedResourceLoader::loadResource):
+ (WebCore::CachedResourceLoader::determineRevalidationPolicy):
+ (WebCore::CachedResourceLoader::setAutoLoadImages):
+ (WebCore):
+ (WebCore::CachedResourceLoader::setImagesEnabled):
+ (WebCore::CachedResourceLoader::clientDefersImage):
+ (WebCore::CachedResourceLoader::shouldDeferImageLoad):
+ (WebCore::CachedResourceLoader::reloadImagesIfNotDeferred):
+ * loader/cache/CachedResourceLoader.h:
+ (CachedResourceLoader):
+ * page/Settings.cpp:
+ (WebCore::setImageLoadingSettings):
+ (WebCore::Settings::Settings):
+ (WebCore::Settings::setLoadsImagesAutomatically):
+ (WebCore::Settings::imageLoadingSettingsTimerFired):
+ (WebCore::Settings::setImagesEnabled):
+ * page/Settings.h:
+ (Settings):
+ * testing/InternalSettings.cpp:
+ (WebCore::InternalSettings::Backup::Backup):
+ (WebCore::InternalSettings::Backup::restoreTo):
+ (WebCore::InternalSettings::setImagesEnabled):
+ (WebCore):
+ * testing/InternalSettings.h:
+ (Backup):
+ (InternalSettings):
+ * testing/InternalSettings.idl:
+
+2012-09-24 Joone Hur <joone.hur@intel.com>, Gustavo Noronha Silva <gustavo.noronha@collabora.com>
+
+ [GTK] Implement GraphicsLayer using Clutter
+ https://bugs.webkit.org/show_bug.cgi?id=73767
+
+ Reviewed by Martin Robinson.
+
+ This patch is needed for enabling Accelerated Compositing(Clutter backend)
+ with the patches submitted in bug 92045 and 91940.
+
+ No new tests. This will be covered by pixel tests for Qt/GTK+ accelerated
+ compositing and 3D transforms.
+
+ * GNUmakefile.list.am:
+ * platform/clutter/GRefPtrClutter.cpp: Removed.
+ * platform/clutter/GRefPtrClutter.h: Removed.
+ * platform/graphics/clutter/PlatformClutterLayerClient.h: Added.
+ (WebCore):
+ (PlatformClutterLayerClient):
+ (WebCore::PlatformClutterLayerClient::~PlatformClutterLayerClient):
+ * platform/graphics/clutter/TransformationMatrixClutter.cpp: Added to convert CoglMatrix to
+ TransformationMatrix.
+ (WebCore):
+ (WebCore::TransformationMatrix::operator CoglMatrix):
+ * platform/graphics/transforms/TransformationMatrix.h:
+ (TransformationMatrix):
+
+2012-09-24 David Grogan <dgrogan@chromium.org>
+
+ Unprefix IndexedDB
+ https://bugs.webkit.org/show_bug.cgi?id=96548
+
+ Reviewed by Adam Barth.
+
+ We are largely compatible with the FF implementation and the w3c test
+ suite submitted by MS. The w3c test suite doesn't yet check
+ for lack of prefix; this is mostly to signal to devs that we think our
+ implementation is stable.
+
+ This patch uses the new FeatureObserver to get data about prefixed
+ vs unprefixed usage.
+
+ Tests: storage/indexeddb/unprefix-workers.html
+ storage/indexeddb/unprefix.html
+
+ * Modules/indexeddb/DOMWindowIndexedDatabase.cpp:
+ (WebCore::DOMWindowIndexedDatabase::indexedDB):
+ * Modules/indexeddb/DOMWindowIndexedDatabase.h:
+ (DOMWindowIndexedDatabase):
+ * Modules/indexeddb/DOMWindowIndexedDatabase.idl:
+ * Modules/indexeddb/WorkerContextIndexedDatabase.cpp:
+ (WebCore::WorkerContextIndexedDatabase::indexedDB):
+ * Modules/indexeddb/WorkerContextIndexedDatabase.h:
+ (WorkerContextIndexedDatabase):
+ * Modules/indexeddb/WorkerContextIndexedDatabase.idl:
+ * bindings/generic/RuntimeEnabledFeatures.h:
+ Making the auxiliary objects RuntimeEnabled didn't make much sense as
+ they are useless without the factory, so always enable them.
+
+ (WebCore::RuntimeEnabledFeatures::indexedDBEnabled):
+ * bindings/scripts/CodeGeneratorGObject.pm:
+ (SkipAttribute):
+ * page/FeatureObserver.h:
+
+2012-09-24 Andrey Adaikin <aandrey@chromium.org>
+
+ Web Inspector: [WebGL] First step towards 2D canvas instrumentation in injected script
+ https://bugs.webkit.org/show_bug.cgi?id=96746
+
+ Reviewed by Pavel Feldman.
+
+ First step towards the 2D canvas instrumentation from the WebGL injected script module side.
+ We trace and save all calls that affect the 2D canvas context state and it's resources (Gradient and Pattern)
+ so that we could replay the context and resources states later.
+ The 2D canvas context state consists of:
+ - current transformation matrix
+ - current default path
+ - current clipping region (affected by the "clip" command)
+ - current values of the context attributes (like strokeStyle, fillStyle, etc.)
+ - a stack of saved drawing states (affected by the "save" and "restore" commands)
+
+ * inspector/InjectedScriptCanvasModuleSource.js:
+ (.):
+
+2012-09-24 Andrey Adaikin <aandrey@chromium.org>
+
+ Web Inspector: [TextEditor] conditional breakpoint popup not showing up the first time
+ https://bugs.webkit.org/show_bug.cgi?id=97442
+
+ Reviewed by Pavel Feldman.
+
+ 1) The conditional breakpoint popup may not show up the first time we click on the gutter.
+ This was the case because the popup decoration element would be deleted from the line while
+ it was being highlighted and appended afterwards. Now we do not remove decorations from the
+ DOM while highlighting.
+
+ 2) Also the popup will close itself on any mouse click event, even if it's targeted to the
+ input box itself. This was due to pointer-events: none; CSS style for the parent element.
+ Now we just override this style for the input box.
+
+ * inspector/front-end/DefaultTextEditor.js:
+ (WebInspector.TextEditorMainPanel.prototype._paintLine):
+ (WebInspector.TextEditorMainPanel.prototype._insertSpanBefore):
+ (WebInspector.TextEditorMainPanel.prototype._insertTextNodeBefore):
+ * inspector/front-end/inspector.css:
+ (.source-frame-breakpoint-condition):
+
+2012-09-24 Andrey Adaikin <aandrey@chromium.org>
+
+ Web Inspector: [Canvas] set CanvasAgent in InstrumentingAgents upon calling enable command
+ https://bugs.webkit.org/show_bug.cgi?id=97331
+
+ Reviewed by Yury Semikhatsky.
+
+ We should set CanvasAgent in InstrumentingAgents from enable() command and remove from disable(), instead of doing this in constructor and destructor.
+
+ * inspector/InspectorCanvasAgent.cpp:
+ (WebCore::InspectorCanvasAgent::InspectorCanvasAgent):
+ (WebCore::InspectorCanvasAgent::~InspectorCanvasAgent):
+ (WebCore::InspectorCanvasAgent::restore):
+ (WebCore::InspectorCanvasAgent::enable):
+ (WebCore::InspectorCanvasAgent::disable):
+ * inspector/InspectorCanvasAgent.h:
+ (InspectorCanvasAgent):
+ * inspector/InspectorCanvasInstrumentation.h:
+ (WebCore::InspectorInstrumentation::wrapCanvas2DRenderingContextForInstrumentation):
+ (WebCore::InspectorInstrumentation::wrapWebGLRenderingContextForInstrumentation):
+
+2012-09-24 Patrick Gansterer <paroga@webkit.org>
+
+ Remove remaining WTF_DEPRECATED_STRING_OPERATORS from cpp files
+ https://bugs.webkit.org/show_bug.cgi?id=97412
+
+ Reviewed by Adam Barth.
+
+ * css/StylePropertySet.cpp: Removed useless define.
+
+2012-09-20 Emil A Eklund <eae@chromium.org>
+
+ snapToSize rounds the incorrectly for negative locations
+ https://bugs.webkit.org/show_bug.cgi?id=97265
+
+ Reviewed by Eric Seidel.
+
+ Change snapSizeToPixel to preserve sign for location which
+ affects rounding.
+
+ Test: fast/sub-pixel/snap-negative-location.html
+
+ * platform/FractionalLayoutUnit.h:
+ (WebCore::snapSizeToPixel):
+
+2012-09-24 Jonathan Liu <net147@gmail.com>
+
+ Use unsigned char for bitfield instead of unsigned.
+ https://bugs.webkit.org/show_bug.cgi?id=97447
+
+ Reviewed by Andreas Kling.
+
+ Not all compilers will pad an unsigned bitfield to the smallest size.
+ Use unsigned char instead of unsigned to reduce padding for compilers
+ that pad to the underlying type.
+
+ No new tests. There is already a compile-time assertion.
+
+ * css/CSSRule.cpp:
+ (SameSizeAsCSSRule):
+ * css/CSSRule.h:
+ (CSSRule):
+
+2012-09-24 Peter Rybin <peter.rybin@gmail.com>
+
+ Web Inspector: don't allow exception in front-end when expanding function scope
+ https://bugs.webkit.org/show_bug.cgi?id=97346
+
+ Reviewed by Yury Semikhatsky.
+
+ A missing guard condition is added.
+
+ * inspector/front-end/ObjectPropertiesSection.js:
+ (WebInspector.FunctionScopeMainTreeElement.prototype.onpopulate.didGetDetails):
+ (WebInspector.FunctionScopeMainTreeElement.prototype.onpopulate):
+
+2012-09-24 Arvid Nilsson <anilsson@rim.com>
+
+ [BlackBerry] Add cookie database API
+ https://bugs.webkit.org/show_bug.cgi?id=97102
+
+ Reviewed by Antonio Gomes.
+
+ Add a CookieManager method that takes a list of strings to parse
+ instead of just one string. Expose CookieParser::parseOneCookie.
+
+ Reviewed internally by Otto D. Cheung.
+
+ No change in behavior, no new tests.
+
+ * platform/blackberry/CookieManager.cpp:
+ (WebCore::CookieManager::setCookies):
+ (WebCore):
+ * platform/blackberry/CookieManager.h:
+ * platform/blackberry/CookieParser.cpp:
+ (WebCore::CookieParser::parseOneCookie):
+ (WebCore):
+ * platform/blackberry/CookieParser.h:
+ (CookieParser):
+
+2012-09-24 Vsevolod Vlasov <vsevik@chromium.org>
+
+ Web Inspector: Open resource dialog has too many false positive matches.
+ https://bugs.webkit.org/show_bug.cgi?id=97332
+
+ Reviewed by Alexander Pavlov.
+
+ Improved open resource dialog filtering to make the amount of false
+ positive search results less.
+
+ * inspector/front-end/FilteredItemSelectionDialog.js:
+ (WebInspector.FilteredItemSelectionDialog.prototype._innerCreateSearchRegExp):
+ (WebInspector.FilteredItemSelectionDialog.prototype._highlightItem.get var):
+ (WebInspector.FilteredItemSelectionDialog.prototype._highlightItem):
+
+2012-09-24 Andrey Adaikin <aandrey@chromium.org>
+
+ Web Inspector: [Canvas] support 2D canvas instrumentation from the inspector C++ code
+ https://bugs.webkit.org/show_bug.cgi?id=97203
+
+ Reviewed by Yury Semikhatsky.
+
+ Implements wrapping a 2D canvas context through the injected canvas module script facility.
+
+ * bindings/js/JSHTMLCanvasElementCustom.cpp:
+ (WebCore::JSHTMLCanvasElement::getContext):
+ * bindings/v8/custom/V8HTMLCanvasElementCustom.cpp:
+ (WebCore::V8HTMLCanvasElement::getContextCallback):
+ * inspector/InjectedScriptCanvasModule.cpp:
+ (WebCore::InjectedScriptCanvasModule::wrapCanvas2DContext):
+ (WebCore):
+ (WebCore::InjectedScriptCanvasModule::wrapWebGLContext):
+ (WebCore::InjectedScriptCanvasModule::callWrapContextFunction):
+ * inspector/InjectedScriptCanvasModule.h:
+ (InjectedScriptCanvasModule):
+ * inspector/InspectorCanvasAgent.cpp:
+ (WebCore::InspectorCanvasAgent::wrapCanvas2DRenderingContextForInstrumentation):
+ (WebCore):
+ * inspector/InspectorCanvasAgent.h:
+ (InspectorCanvasAgent):
+ * inspector/InspectorCanvasInstrumentation.h:
+ (WebCore::InspectorInstrumentation::wrapCanvas2DRenderingContextForInstrumentation):
+ (WebCore):
+ * inspector/InspectorInstrumentation.h:
+ (InspectorInstrumentation):
+
+2012-09-24 Pavel Feldman <pfeldman@chromium.org>
+
+ Web Inspector:EXC_BAD_ACCESS upon closing page with node highlighted
+ https://bugs.webkit.org/show_bug.cgi?id=97446
+
+ Reviewed by Alexander Pavlov.
+
+ Added 0 check on frame view.
+
+ * inspector/InspectorOverlay.cpp:
+ (WebCore::InspectorOverlay::update):
+
+2012-09-21 Alexander Pavlov <apavlov@chromium.org>
+
+ Web Inspector: [REGRESSION] Cmd-Shift-C doesn't enable element inspection mode when inspector hidden
+ https://bugs.webkit.org/show_bug.cgi?id=97249
+
+ Reviewed by Yury Semikhatsky.
+
+ Fix regression from r125871.
+
+ * inspector/front-end/InspectorFrontendAPI.js:
+ (InspectorFrontendAPI.enterInspectElementMode):
+ * inspector/front-end/inspector.js:
+ (WebInspector._createGlobalStatusBarItems):
+ (WebInspector.documentKeyDown):
+
+2012-09-24 Alexander Pavlov <apavlov@chromium.org>
+
+ Web Inspector: Disable persistence of master switches in the "Overrides" settings tab
+ https://bugs.webkit.org/show_bug.cgi?id=97440
+
+ Reviewed by Yury Semikhatsky.
+
+ Disables enforcement of device metrics, geolocation, and device orientation overrides on Web Inspector start.
+
+ * inspector/InspectorPageAgent.cpp:
+ (WebCore::InspectorPageAgent::restore):
+ * inspector/front-end/SettingsScreen.js:
+ (WebInspector.UserAgentSettingsTab.prototype._onMetricsCheckboxClicked):
+ (WebInspector.UserAgentSettingsTab.prototype._onGeolocationOverrideCheckboxClicked):
+ (WebInspector.UserAgentSettingsTab.prototype._onDeviceOrientationOverrideCheckboxClicked):
+ * inspector/front-end/UserAgentSupport.js:
+ (WebInspector.UserAgentSupport):
+ (WebInspector.UserAgentSupport.prototype.toggleDeviceMetricsOverride):
+ (WebInspector.UserAgentSupport.prototype.toggleGeolocationPositionOverride):
+ (WebInspector.UserAgentSupport.prototype.toggleDeviceOrientationOverride):
+ * inspector/front-end/externs.js:
+
+2012-09-24 Vivek Galatage <vivekgalatage@gmail.com>
+
+ Web Inspector: implement testing harness for pure protocol tests.
+ https://bugs.webkit.org/show_bug.cgi?id=90675
+
+ Reviewed by Yury Semikhatsky.
+
+ Implementing the testing harness as the APIs of Internals object not
+ only reduced platform specific patching of DRTs but also minimized the
+ the effort required to open up the new dummy inspector Frontend.
+
+ The openDummyInspectorFrontend method will return the handle to newly
+ created DOMWindow. This DOMWindow object can be utilized inside the test
+ case to communicate using postMessage WebAPI.
+
+ The newly created DOMWindow will host the protocol-test.html which
+ will seed the necessary JS libraries to communicate with the
+ InspectorBackend.
+
+ Test: inspector-protocol/css-getSupportedCSSProperties.html
+
+ * WebCore.exp.in:
+ * WebCore.gypi:
+ * inspector/InspectorClient.h:
+ (InspectorClient):
+ * testing/Internals.cpp:
+ (InspectorFrontendClientDummy):
+ (WebCore::InspectorFrontendClientDummy::~InspectorFrontendClientDummy):
+ (WebCore):
+ (WebCore::InspectorFrontendClientDummy::InspectorFrontendClientDummy):
+ (InspectorFrontendChannelDummy):
+ (WebCore::InspectorFrontendChannelDummy::~InspectorFrontendChannelDummy):
+ (WebCore::InspectorFrontendChannelDummy::InspectorFrontendChannelDummy):
+ (WebCore::InspectorFrontendChannelDummy::sendMessageToFrontend):
+ (WebCore::Internals::consoleMessageArgumentCounts):
+ (WebCore::Internals::openDummyInspectorFrontend):
+ (WebCore::Internals::closeDummyInspectorFrontend):
+ * testing/Internals.h:
+ (WebCore):
+ (Internals):
+ * testing/Internals.idl:
+
+2012-09-24 Keishi Hattori <keishi@webkit.org>
+
+ REGRESSION(r127727): Calendar picker focus doesn't loop in calendar-picker.html
+ https://bugs.webkit.org/show_bug.cgi?id=97183
+
+ Reviewed by Kent Tamura.
+
+ Fixing bug calendar-picker.html. The page popup behaves fine because
+ this code is only necessary in calendar-picker.html where the focus can
+ move outside of the picker because we are just using an iframe.
+
+ No new tests. Added tests to calendar-picker-key-operations.html.
+
+ * Resources/pagepopups/calendarPicker.js:
+ (YearMonthController.prototype.attachTo):
+ (CalendarPicker.prototype._handleBodyKeyDown):
+
2012-09-24 Andrey Kosyakov <caseq@chromium.org>
Unreviewed follow-up to r129336 -- fixed closure compiler warnings.
diff --git a/Source/WebCore/GNUmakefile.list.am b/Source/WebCore/GNUmakefile.list.am
index 8ca8b268e..d2ed2915f 100644
--- a/Source/WebCore/GNUmakefile.list.am
+++ b/Source/WebCore/GNUmakefile.list.am
@@ -2734,6 +2734,8 @@ webcore_sources += \
Source/WebCore/dom/DocumentOrderedMap.h \
Source/WebCore/dom/DocumentParser.cpp \
Source/WebCore/dom/DocumentParser.h \
+ Source/WebCore/dom/DocumentStyleSheetCollection.cpp \
+ Source/WebCore/dom/DocumentStyleSheetCollection.h \
Source/WebCore/dom/DocumentTiming.h \
Source/WebCore/dom/DocumentType.cpp \
Source/WebCore/dom/DocumentType.h \
@@ -6238,10 +6240,9 @@ endif # END ENABLE_WEBGL
if USE_ACCELERATED_COMPOSITING
if USE_CLUTTER
webcore_sources += \
- Source/WebCore/platform/clutter/GRefPtrClutter.cpp \
- Source/WebCore/platform/clutter/GRefPtrClutter.h \
Source/WebCore/platform/graphics/clutter/GraphicsLayerClutter.cpp \
- Source/WebCore/platform/graphics/clutter/GraphicsLayerClutter.h
+ Source/WebCore/platform/graphics/clutter/GraphicsLayerClutter.h \
+ Source/WebCore/platform/graphics/clutter/TransformationMatrixClutter.cpp
endif # END USE_CLUTTER
if USE_TEXTURE_MAPPER_CAIRO
diff --git a/Source/WebCore/Modules/indexeddb/DOMWindowIndexedDatabase.cpp b/Source/WebCore/Modules/indexeddb/DOMWindowIndexedDatabase.cpp
index 9f4cbb4f7..168028b63 100644
--- a/Source/WebCore/Modules/indexeddb/DOMWindowIndexedDatabase.cpp
+++ b/Source/WebCore/Modules/indexeddb/DOMWindowIndexedDatabase.cpp
@@ -88,12 +88,12 @@ void DOMWindowIndexedDatabase::willDetachGlobalObjectFromFrame()
DOMWindowProperty::willDetachGlobalObjectFromFrame();
}
-IDBFactory* DOMWindowIndexedDatabase::webkitIndexedDB(DOMWindow* window)
+IDBFactory* DOMWindowIndexedDatabase::indexedDB(DOMWindow* window)
{
- return from(window)->webkitIndexedDB();
+ return from(window)->indexedDB();
}
-IDBFactory* DOMWindowIndexedDatabase::webkitIndexedDB()
+IDBFactory* DOMWindowIndexedDatabase::indexedDB()
{
Document* document = m_window->document();
if (!document)
diff --git a/Source/WebCore/Modules/indexeddb/DOMWindowIndexedDatabase.h b/Source/WebCore/Modules/indexeddb/DOMWindowIndexedDatabase.h
index fd32f9d42..c8c6303b2 100644
--- a/Source/WebCore/Modules/indexeddb/DOMWindowIndexedDatabase.h
+++ b/Source/WebCore/Modules/indexeddb/DOMWindowIndexedDatabase.h
@@ -41,7 +41,7 @@ public:
virtual ~DOMWindowIndexedDatabase();
static DOMWindowIndexedDatabase* from(DOMWindow*);
- static IDBFactory* webkitIndexedDB(DOMWindow*);
+ static IDBFactory* indexedDB(DOMWindow*);
virtual void disconnectFrameForPageCache() OVERRIDE;
virtual void reconnectFrameFromPageCache(Frame*) OVERRIDE;
@@ -52,7 +52,7 @@ public:
private:
explicit DOMWindowIndexedDatabase(DOMWindow*);
- IDBFactory* webkitIndexedDB();
+ IDBFactory* indexedDB();
DOMWindow* m_window;
RefPtr<IDBFactory> m_idbFactory;
diff --git a/Source/WebCore/Modules/indexeddb/DOMWindowIndexedDatabase.idl b/Source/WebCore/Modules/indexeddb/DOMWindowIndexedDatabase.idl
index 09513f1fa..a290b7300 100644
--- a/Source/WebCore/Modules/indexeddb/DOMWindowIndexedDatabase.idl
+++ b/Source/WebCore/Modules/indexeddb/DOMWindowIndexedDatabase.idl
@@ -30,7 +30,7 @@ module window {
Conditional=INDEXED_DATABASE,
Supplemental=DOMWindow
] DOMWindowIndexedDatabase {
- readonly attribute [V8MeasureAs=PrefixedIndexedDB] IDBFactory webkitIndexedDB;
+ readonly attribute [ImplementedAs=indexedDB,V8MeasureAs=PrefixedIndexedDB] IDBFactory webkitIndexedDB;
attribute IDBCursorConstructor webkitIDBCursor;
attribute IDBDatabaseConstructor webkitIDBDatabase;
@@ -41,6 +41,18 @@ module window {
attribute IDBObjectStoreConstructor webkitIDBObjectStore;
attribute IDBRequestConstructor webkitIDBRequest;
attribute IDBTransactionConstructor webkitIDBTransaction;
+
+ readonly attribute [V8MeasureAs=UnprefixedIndexedDB] IDBFactory indexedDB;
+
+ attribute IDBCursorConstructor IDBCursor;
+ attribute IDBDatabaseConstructor IDBDatabase;
+ attribute IDBDatabaseExceptionConstructor IDBDatabaseException;
+ attribute IDBFactoryConstructor IDBFactory;
+ attribute IDBIndexConstructor IDBIndex;
+ attribute IDBKeyRangeConstructor IDBKeyRange;
+ attribute IDBObjectStoreConstructor IDBObjectStore;
+ attribute IDBRequestConstructor IDBRequest;
+ attribute IDBTransactionConstructor IDBTransaction;
};
}
diff --git a/Source/WebCore/Modules/indexeddb/WorkerContextIndexedDatabase.cpp b/Source/WebCore/Modules/indexeddb/WorkerContextIndexedDatabase.cpp
index b3d209992..0a25ea7d7 100644
--- a/Source/WebCore/Modules/indexeddb/WorkerContextIndexedDatabase.cpp
+++ b/Source/WebCore/Modules/indexeddb/WorkerContextIndexedDatabase.cpp
@@ -58,12 +58,12 @@ WorkerContextIndexedDatabase* WorkerContextIndexedDatabase::from(ScriptExecution
return supplement;
}
-IDBFactory* WorkerContextIndexedDatabase::webkitIndexedDB(ScriptExecutionContext* context)
+IDBFactory* WorkerContextIndexedDatabase::indexedDB(ScriptExecutionContext* context)
{
- return from(context)->webkitIndexedDB();
+ return from(context)->indexedDB();
}
-IDBFactory* WorkerContextIndexedDatabase::webkitIndexedDB()
+IDBFactory* WorkerContextIndexedDatabase::indexedDB()
{
if (!m_context->securityOrigin()->canAccessDatabase())
return 0;
diff --git a/Source/WebCore/Modules/indexeddb/WorkerContextIndexedDatabase.h b/Source/WebCore/Modules/indexeddb/WorkerContextIndexedDatabase.h
index 836caa8c6..9a84f1799 100644
--- a/Source/WebCore/Modules/indexeddb/WorkerContextIndexedDatabase.h
+++ b/Source/WebCore/Modules/indexeddb/WorkerContextIndexedDatabase.h
@@ -42,12 +42,12 @@ public:
virtual ~WorkerContextIndexedDatabase();
static WorkerContextIndexedDatabase* from(ScriptExecutionContext*);
- static IDBFactory* webkitIndexedDB(ScriptExecutionContext*);
+ static IDBFactory* indexedDB(ScriptExecutionContext*);
private:
explicit WorkerContextIndexedDatabase(ScriptExecutionContext*);
- IDBFactory* webkitIndexedDB();
+ IDBFactory* indexedDB();
ScriptExecutionContext* m_context;
RefPtr<IDBFactoryBackendInterface> m_factoryBackend;
diff --git a/Source/WebCore/Modules/indexeddb/WorkerContextIndexedDatabase.idl b/Source/WebCore/Modules/indexeddb/WorkerContextIndexedDatabase.idl
index c336c57ee..acc5565bd 100644
--- a/Source/WebCore/Modules/indexeddb/WorkerContextIndexedDatabase.idl
+++ b/Source/WebCore/Modules/indexeddb/WorkerContextIndexedDatabase.idl
@@ -30,17 +30,29 @@ module threads {
Conditional=INDEXED_DATABASE,
Supplemental=WorkerContext
] WorkerContextIndexedDatabase {
- readonly attribute [V8EnabledAtRuntime] IDBFactory webkitIndexedDB;
+ readonly attribute [ImplementedAs=indexedDB,V8EnabledAtRuntime] IDBFactory webkitIndexedDB;
- attribute [V8EnabledAtRuntime] IDBCursorConstructor webkitIDBCursor;
- attribute [V8EnabledAtRuntime] IDBDatabaseConstructor webkitIDBDatabase;
- attribute [V8EnabledAtRuntime] IDBDatabaseExceptionConstructor webkitIDBDatabaseException;
- attribute [V8EnabledAtRuntime] IDBFactoryConstructor webkitIDBFactory;
- attribute [V8EnabledAtRuntime] IDBIndexConstructor webkitIDBIndex;
- attribute [V8EnabledAtRuntime] IDBKeyRangeConstructor webkitIDBKeyRange;
- attribute [V8EnabledAtRuntime] IDBObjectStoreConstructor webkitIDBObjectStore;
- attribute [V8EnabledAtRuntime] IDBRequestConstructor webkitIDBRequest;
- attribute [V8EnabledAtRuntime] IDBTransactionConstructor webkitIDBTransaction;
+ attribute IDBCursorConstructor webkitIDBCursor;
+ attribute IDBDatabaseConstructor webkitIDBDatabase;
+ attribute IDBDatabaseExceptionConstructor webkitIDBDatabaseException;
+ attribute IDBFactoryConstructor webkitIDBFactory;
+ attribute IDBIndexConstructor webkitIDBIndex;
+ attribute IDBKeyRangeConstructor webkitIDBKeyRange;
+ attribute IDBObjectStoreConstructor webkitIDBObjectStore;
+ attribute IDBRequestConstructor webkitIDBRequest;
+ attribute IDBTransactionConstructor webkitIDBTransaction;
+
+ readonly attribute [V8EnabledAtRuntime] IDBFactory indexedDB;
+
+ attribute IDBCursorConstructor IDBCursor;
+ attribute IDBDatabaseConstructor IDBDatabase;
+ attribute IDBDatabaseExceptionConstructor IDBDatabaseException;
+ attribute IDBFactoryConstructor IDBFactory;
+ attribute IDBIndexConstructor IDBIndex;
+ attribute IDBKeyRangeConstructor IDBKeyRange;
+ attribute IDBObjectStoreConstructor IDBObjectStore;
+ attribute IDBRequestConstructor IDBRequest;
+ attribute IDBTransactionConstructor IDBTransaction;
};
}
diff --git a/Source/WebCore/Modules/mediastream/RTCPeerConnection.cpp b/Source/WebCore/Modules/mediastream/RTCPeerConnection.cpp
index 78896a796..cb9ba7c5a 100644
--- a/Source/WebCore/Modules/mediastream/RTCPeerConnection.cpp
+++ b/Source/WebCore/Modules/mediastream/RTCPeerConnection.cpp
@@ -393,7 +393,7 @@ void RTCPeerConnection::close(ExceptionCode& ec)
void RTCPeerConnection::negotiationNeeded()
{
- dispatchEvent(Event::create(eventNames().negotationneededEvent, false, false));
+ dispatchEvent(Event::create(eventNames().negotiationneededEvent, false, false));
}
void RTCPeerConnection::didGenerateIceCandidate(PassRefPtr<RTCIceCandidateDescriptor> iceCandidateDescriptor)
diff --git a/Source/WebCore/Modules/mediastream/RTCPeerConnection.h b/Source/WebCore/Modules/mediastream/RTCPeerConnection.h
index 1615581a5..84d1e1fbe 100644
--- a/Source/WebCore/Modules/mediastream/RTCPeerConnection.h
+++ b/Source/WebCore/Modules/mediastream/RTCPeerConnection.h
@@ -86,7 +86,7 @@ public:
void close(ExceptionCode&);
- DEFINE_ATTRIBUTE_EVENT_LISTENER(negotationneeded);
+ DEFINE_ATTRIBUTE_EVENT_LISTENER(negotiationneeded);
DEFINE_ATTRIBUTE_EVENT_LISTENER(icecandidate);
DEFINE_ATTRIBUTE_EVENT_LISTENER(open);
DEFINE_ATTRIBUTE_EVENT_LISTENER(statechange);
diff --git a/Source/WebCore/Modules/mediastream/RTCPeerConnection.idl b/Source/WebCore/Modules/mediastream/RTCPeerConnection.idl
index 967ad4023..bc4390f54 100644
--- a/Source/WebCore/Modules/mediastream/RTCPeerConnection.idl
+++ b/Source/WebCore/Modules/mediastream/RTCPeerConnection.idl
@@ -75,7 +75,7 @@ module mediastream {
void close()
raises(DOMException);
- attribute EventListener onnegotationneeded;
+ attribute EventListener onnegotiationneeded;
attribute EventListener onicecandidate;
attribute EventListener onopen;
attribute EventListener onstatechange;
diff --git a/Source/WebCore/Modules/webaudio/BiquadProcessor.cpp b/Source/WebCore/Modules/webaudio/BiquadProcessor.cpp
index 3ae02636a..6362a10e7 100644
--- a/Source/WebCore/Modules/webaudio/BiquadProcessor.cpp
+++ b/Source/WebCore/Modules/webaudio/BiquadProcessor.cpp
@@ -39,6 +39,7 @@ BiquadProcessor::BiquadProcessor(AudioContext* context, float sampleRate, size_t
, m_parameter2(0)
, m_parameter3(0)
, m_filterCoefficientsDirty(true)
+ , m_hasSampleAccurateValues(false)
{
double nyquist = 0.5 * this->sampleRate();
diff --git a/Source/WebCore/PlatformBlackBerry.cmake b/Source/WebCore/PlatformBlackBerry.cmake
index 987202cde..b608ae873 100644
--- a/Source/WebCore/PlatformBlackBerry.cmake
+++ b/Source/WebCore/PlatformBlackBerry.cmake
@@ -61,7 +61,6 @@ LIST(APPEND WebCore_SOURCES
bindings/cpp/WebDOMString.cpp
bindings/cpp/WebExceptionHandler.cpp
platform/blackberry/CookieDatabaseBackingStore/CookieDatabaseBackingStore.cpp
- platform/blackberry/AuthenticationChallengeManager.cpp
platform/blackberry/CookieManager.cpp
platform/blackberry/CookieMap.cpp
platform/blackberry/CookieParser.cpp
diff --git a/Source/WebCore/Resources/pagepopups/calendarPicker.js b/Source/WebCore/Resources/pagepopups/calendarPicker.js
index db984a538..3758006f9 100644
--- a/Source/WebCore/Resources/pagepopups/calendarPicker.js
+++ b/Source/WebCore/Resources/pagepopups/calendarPicker.js
@@ -479,7 +479,7 @@ YearMonthController.prototype.attachTo = function(element) {
}
this._month.style.minWidth = maxWidth + 'px';
- global.firstFocusableControl = this._left2; // FIXME: Should it be this.month?
+ this.picker.firstFocusableControl = this._left2; // FIXME: Should it be this.month?
};
YearMonthController.addTenYearsButtons = false;
@@ -1178,11 +1178,11 @@ CalendarPicker.prototype._handleBodyKeyDown = function(event) {
this.maybeUpdateFocusStyle();
var key = event.keyIdentifier;
if (key == "U+0009") {
- if (!event.shiftKey && document.activeElement == global.lastFocusableControl) {
+ if (!event.shiftKey && document.activeElement == this.lastFocusableControl) {
event.stopPropagation();
event.preventDefault();
this.firstFocusableControl.focus();
- } else if (event.shiftKey && document.activeElement == global.firstFocusableControl) {
+ } else if (event.shiftKey && document.activeElement == this.firstFocusableControl) {
event.stopPropagation();
event.preventDefault();
this.lastFocusableControl.focus();
diff --git a/Source/WebCore/Target.pri b/Source/WebCore/Target.pri
index 7465d4405..523d884df 100644
--- a/Source/WebCore/Target.pri
+++ b/Source/WebCore/Target.pri
@@ -371,6 +371,7 @@ SOURCES += \
dom/DocumentMarker.cpp \
dom/DocumentOrderedMap.cpp \
dom/DocumentParser.cpp \
+ dom/DocumentStyleSheetCollection.cpp \
dom/DocumentType.cpp \
dom/DOMCoreException.cpp \
dom/DOMError.cpp \
@@ -1528,6 +1529,7 @@ HEADERS += \
dom/DocumentMarker.h \
dom/DocumentMarkerController.h \
dom/DocumentOrderedMap.h \
+ dom/DocumentStyleSheetCollection.h \
dom/DocumentType.h \
dom/DOMError.h \
dom/DOMImplementation.h \
diff --git a/Source/WebCore/WebCore.exp.in b/Source/WebCore/WebCore.exp.in
index dff830d50..5e087ac56 100644
--- a/Source/WebCore/WebCore.exp.in
+++ b/Source/WebCore/WebCore.exp.in
@@ -186,8 +186,6 @@ __ZN7WebCore12PrintContextC1EPNS_5FrameE
__ZN7WebCore12PrintContextD1Ev
__ZNK7WebCore12RenderObject16repaintRectangleERKNS_20FractionalLayoutRectEb
__ZN7WebCore12RenderObject19scrollRectToVisibleERKNS_20FractionalLayoutRectERKNS_15ScrollAlignmentES6_
-__ZN7WebCore12RenderWidget28resumeWidgetHierarchyUpdatesEv
-__ZN7WebCore12RenderWidget29suspendWidgetHierarchyUpdatesEv
__ZN7WebCore12SharedBuffer10wrapCFDataEPK8__CFData
__ZN7WebCore12SharedBuffer10wrapNSDataEP6NSData
__ZN7WebCore12SharedBuffer12createNSDataEv
@@ -638,6 +636,8 @@ __ZN7WebCore31CrossOriginPreflightResultCache5emptyEv
__ZN7WebCore31CrossOriginPreflightResultCache6sharedEv
__ZN7WebCore32plainTextToMallocAllocatedBufferEPKNS_5RangeERjbNS_20TextIteratorBehaviorE
__ZN7WebCore33stripLeadingAndTrailingHTMLSpacesERKN3WTF6StringE
+__ZN7WebCore37WidgetHierarchyUpdatesSuspensionScope11moveWidgetsEv
+__ZN7WebCore37WidgetHierarchyUpdatesSuspensionScope35s_widgetHierarchyUpdateSuspendCountE
__ZN7WebCore3macERKNS_10CredentialE
__ZN7WebCore3macERKNS_23AuthenticationChallengeE
__ZN7WebCore40restrictMinimumScaleFactorToViewportSizeERNS_18ViewportAttributesENS_7IntSizeE
@@ -852,6 +852,7 @@ __ZN7WebCore8GradientC1ERKNS_10FloatPointES3_
__ZN7WebCore8PositionC1EN3WTF10PassRefPtrINS_4NodeEEEiNS0_10AnchorTypeE
__ZN7WebCore8Settings14setJavaEnabledEb
__ZN7WebCore8Settings15setWebGLEnabledEb
+__ZN7WebCore8Settings16setImagesEnabledEb
__ZN7WebCore8Settings16setScriptEnabledEb
__ZN7WebCore8Settings16setUsesPageCacheEb
__ZN7WebCore8Settings17setPluginsEnabledEb
@@ -2191,7 +2192,6 @@ __ZN7WebCore11Geolocation12setIsAllowedEb
__ZN7WebCore11GeolocationD1Ev
__ZNK7WebCore11Geolocation5frameEv
__ZN7WebCore20provideGeolocationToEPNS_4PageEPNS_17GeolocationClientE
-__ZN7WebCore21GeolocationClientMock13setPermissionEb
__ZN7WebCore21GeolocationController13errorOccurredEPNS_16GeolocationErrorE
__ZN7WebCore21GeolocationController14supplementNameEv
__ZN7WebCore21GeolocationController15positionChangedEPNS_19GeolocationPositionE
@@ -2235,6 +2235,7 @@ __ZN7WebCore16HTMLInputElement25selectColorInColorChooserERKNS_5ColorE
__ZN7WebCore15InspectorClient31doDispatchMessageOnFrontendPageEPNS_4PageERKN3WTF6StringE
__ZN7WebCore17InspectorCounters12counterValueENS0_11CounterTypeE
__ZN7WebCore19InspectorController15profilerEnabledEv
+__ZN7WebCore19InspectorController15connectFrontendEPNS_24InspectorFrontendChannelE
__ZN7WebCore19InspectorController18disconnectFrontendEv
__ZN7WebCore19InspectorController18setProfilerEnabledEb
__ZN7WebCore19InspectorController25evaluateForTestInFrontendElRKN3WTF6StringE
@@ -2273,7 +2274,11 @@ __ZN7WebCore28InspectorFrontendClientLocal27setTimelineProfilingEnabledEb
__ZN7WebCore28InspectorFrontendClientLocal31constrainedAttachedWindowHeightEjj
__ZN7WebCore28InspectorFrontendClientLocalC2EPNS_19InspectorControllerEPNS_4PageEN3WTF10PassOwnPtrINS0_8SettingsEEE
__ZN7WebCore28InspectorFrontendClientLocalD2Ev
+__ZN7WebCore4toJSEPN3JSC9ExecStateEPNS_17JSDOMGlobalObjectEPNS_9DOMWindowE
+__ZN7WebCore9DOMWindow4openERKN3WTF6StringERKNS1_12AtomicStringES4_PS0_S8_
+__ZN7WebCore9DOMWindow5closeEPNS_22ScriptExecutionContextE
__ZNK7WebCore19InspectorController13drawHighlightERNS_15GraphicsContextE
+__ZNK7WebCore9DOMWindow8documentEv
#endif
#if ENABLE(INSPECTOR) && PLATFORM(IOS)
diff --git a/Source/WebCore/WebCore.gypi b/Source/WebCore/WebCore.gypi
index e8af673cc..311e75866 100644
--- a/Source/WebCore/WebCore.gypi
+++ b/Source/WebCore/WebCore.gypi
@@ -657,6 +657,7 @@
'dom/DocumentMarkerController.h',
'dom/DocumentOrderedMap.h',
'dom/DocumentParser.h',
+ 'dom/DocumentStyleSheetCollection.h',
'dom/DocumentTiming.h',
'dom/DocumentType.h',
'dom/Element.h',
@@ -3816,6 +3817,7 @@
'dom/DocumentMarker.cpp',
'dom/DocumentOrderedMap.cpp',
'dom/DocumentParser.cpp',
+ 'dom/DocumentStyleSheetCollection.cpp',
'dom/DocumentType.cpp',
'dom/DynamicNodeList.cpp',
'dom/DynamicNodeList.h',
@@ -6313,6 +6315,8 @@
'testing/MallocStatistics.idl',
],
'webcore_test_support_files': [
+ 'inspector/InspectorFrontendClientLocal.cpp',
+ 'inspector/InspectorFrontendClientLocal.h',
'testing/v8/WebCoreTestSupport.cpp',
'testing/v8/WebCoreTestSupport.h',
'testing/js/WebCoreTestSupport.cpp',
diff --git a/Source/WebCore/WebCore.vcproj/WebCore.vcproj b/Source/WebCore/WebCore.vcproj/WebCore.vcproj
index ce26603d8..16ab4216d 100755
--- a/Source/WebCore/WebCore.vcproj/WebCore.vcproj
+++ b/Source/WebCore/WebCore.vcproj/WebCore.vcproj
@@ -50406,6 +50406,14 @@
RelativePath="..\dom\DocumentParser.h"
>
</File>
+ <File
+ RelativePath="..\dom\DocumentStyleSheetCollection.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\dom\DocumentStyleSheetCollection.h"
+ >
+ </File>
<File
RelativePath="..\dom\DocumentTiming.h"
>
diff --git a/Source/WebCore/WebCore.xcodeproj/project.pbxproj b/Source/WebCore/WebCore.xcodeproj/project.pbxproj
index 7a25eaa88..b32c24029 100644
--- a/Source/WebCore/WebCore.xcodeproj/project.pbxproj
+++ b/Source/WebCore/WebCore.xcodeproj/project.pbxproj
@@ -76,8 +76,6 @@
033A6A7E147E07E700509B36 /* HTMLPropertiesCollection.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 033A6A7D147E07E700509B36 /* HTMLPropertiesCollection.cpp */; };
033A6A81147E088600509B36 /* JSHTMLPropertiesCollection.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 033A6A80147E088600509B36 /* JSHTMLPropertiesCollection.cpp */; };
033A6A83147E08A600509B36 /* JSHTMLPropertiesCollection.h in Headers */ = {isa = PBXBuildFile; fileRef = 033A6A82147E08A600509B36 /* JSHTMLPropertiesCollection.h */; };
- 052BFCE9128ABF1500FD338D /* GeolocationClientMock.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 052BFCE8128ABF1500FD338D /* GeolocationClientMock.cpp */; };
- 052BFCEB128ABF2100FD338D /* GeolocationClientMock.h in Headers */ = {isa = PBXBuildFile; fileRef = 052BFCEA128ABF2100FD338D /* GeolocationClientMock.h */; settings = {ATTRIBUTES = (Private, ); }; };
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, ); }; };
@@ -6141,6 +6139,8 @@
E4778B80115A581A00B5D372 /* JSCustomEvent.h in Headers */ = {isa = PBXBuildFile; fileRef = E4778B7E115A581A00B5D372 /* JSCustomEvent.h */; };
E47B4BE80E71241600038854 /* CachedResourceHandle.h in Headers */ = {isa = PBXBuildFile; fileRef = E47B4BE60E71241600038854 /* CachedResourceHandle.h */; settings = {ATTRIBUTES = (Private, ); }; };
E47B4BE90E71241600038854 /* CachedResourceHandle.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E47B4BE70E71241600038854 /* CachedResourceHandle.cpp */; };
+ E47E276516036ED200EE2AFB /* DocumentStyleSheetCollection.h in Headers */ = {isa = PBXBuildFile; fileRef = E47E276416036ED200EE2AFB /* DocumentStyleSheetCollection.h */; settings = {ATTRIBUTES = (Private, ); }; };
+ E47E276816036EDC00EE2AFB /* DocumentStyleSheetCollection.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E47E276716036EDC00EE2AFB /* DocumentStyleSheetCollection.cpp */; };
E4946EAE156E64DD00D3297F /* StyleRuleImport.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E4946EAC156E64DD00D3297F /* StyleRuleImport.cpp */; };
E4946EAF156E64DD00D3297F /* StyleRuleImport.h in Headers */ = {isa = PBXBuildFile; fileRef = E4946EAD156E64DD00D3297F /* StyleRuleImport.h */; };
E49BD9FA131FD2ED003C56F0 /* CSSValuePool.h in Headers */ = {isa = PBXBuildFile; fileRef = E49BD9F9131FD2ED003C56F0 /* CSSValuePool.h */; };
@@ -7088,8 +7088,6 @@
033A6A7F147E07F900509B36 /* HTMLPropertiesCollection.idl */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = HTMLPropertiesCollection.idl; sourceTree = "<group>"; };
033A6A80147E088600509B36 /* JSHTMLPropertiesCollection.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSHTMLPropertiesCollection.cpp; sourceTree = "<group>"; };
033A6A82147E08A600509B36 /* JSHTMLPropertiesCollection.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSHTMLPropertiesCollection.h; sourceTree = "<group>"; };
- 052BFCE8128ABF1500FD338D /* GeolocationClientMock.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = GeolocationClientMock.cpp; path = mock/GeolocationClientMock.cpp; sourceTree = "<group>"; };
- 052BFCEA128ABF2100FD338D /* GeolocationClientMock.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = GeolocationClientMock.h; path = mock/GeolocationClientMock.h; 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>"; };
@@ -13520,6 +13518,8 @@
E4778B7E115A581A00B5D372 /* JSCustomEvent.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSCustomEvent.h; sourceTree = "<group>"; };
E47B4BE60E71241600038854 /* CachedResourceHandle.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CachedResourceHandle.h; sourceTree = "<group>"; };
E47B4BE70E71241600038854 /* CachedResourceHandle.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CachedResourceHandle.cpp; sourceTree = "<group>"; };
+ E47E276416036ED200EE2AFB /* DocumentStyleSheetCollection.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DocumentStyleSheetCollection.h; sourceTree = "<group>"; };
+ E47E276716036EDC00EE2AFB /* DocumentStyleSheetCollection.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = DocumentStyleSheetCollection.cpp; sourceTree = "<group>"; };
E4946EAC156E64DD00D3297F /* StyleRuleImport.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = StyleRuleImport.cpp; sourceTree = "<group>"; };
E4946EAD156E64DD00D3297F /* StyleRuleImport.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = StyleRuleImport.h; sourceTree = "<group>"; };
E49BD9F9131FD2ED003C56F0 /* CSSValuePool.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CSSValuePool.h; sourceTree = "<group>"; };
@@ -15461,8 +15461,6 @@
children = (
59309A1011F4AE5800250603 /* DeviceOrientationClientMock.cpp */,
59309A1211F4AE6A00250603 /* DeviceOrientationClientMock.h */,
- 052BFCE8128ABF1500FD338D /* GeolocationClientMock.cpp */,
- 052BFCEA128ABF2100FD338D /* GeolocationClientMock.h */,
0FE71403142170B800DB33BA /* ScrollbarThemeMock.cpp */,
0FE71404142170B800DB33BA /* ScrollbarThemeMock.h */,
);
@@ -21671,6 +21669,8 @@
14947FFC12F80CD200A0F631 /* DocumentOrderedMap.h */,
A8C2280D11D4A59700D5A7D3 /* DocumentParser.cpp */,
BCCFBAE70B5152ED0001F1D7 /* DocumentParser.h */,
+ E47E276716036EDC00EE2AFB /* DocumentStyleSheetCollection.cpp */,
+ E47E276416036ED200EE2AFB /* DocumentStyleSheetCollection.h */,
86D982F6125C154000AD9E3D /* DocumentTiming.h */,
A8185F3209765765005826D9 /* DocumentType.cpp */,
A8185F3109765765005826D9 /* DocumentType.h */,
@@ -22275,6 +22275,7 @@
isa = PBXHeadersBuildPhase;
buildActionMask = 2147483647;
files = (
+ E47E276516036ED200EE2AFB /* DocumentStyleSheetCollection.h in Headers */,
97BC69DB1505F076001B74AC /* AbstractDatabase.h in Headers */,
41E1B1D10FF5986900576B3B /* AbstractWorker.h in Headers */,
29A8122E0FBB9C1D00510293 /* AccessibilityARIAGridCell.h in Headers */,
@@ -23521,7 +23522,6 @@
0720B0A114D3323500642955 /* GenericEventQueue.h in Headers */,
9746AF2414F4DDE6003E7A70 /* Geolocation.h in Headers */,
BC56CB2310D5AC8000A77C64 /* GeolocationClient.h in Headers */,
- 052BFCEB128ABF2100FD338D /* GeolocationClientMock.h in Headers */,
9746AF2714F4DDE6003E7A70 /* GeolocationController.h in Headers */,
9746AF2814F4DDE6003E7A70 /* GeolocationError.h in Headers */,
9746AF2914F4DDE6003E7A70 /* GeolocationPosition.h in Headers */,
@@ -26753,7 +26753,6 @@
2D481F03146B5C6500AA7834 /* GeneratorGeneratedImage.cpp in Sources */,
0720B0A014D3323500642955 /* GenericEventQueue.cpp in Sources */,
9746AF2314F4DDE6003E7A70 /* Geolocation.cpp in Sources */,
- 052BFCE9128ABF1500FD338D /* GeolocationClientMock.cpp in Sources */,
9746AF2614F4DDE6003E7A70 /* GeolocationController.cpp in Sources */,
0720B0A014D3323500642956 /* GestureEvent.cpp in Sources */,
B2C3DA6D0D006CD600EF6F26 /* GlyphPageTreeNode.cpp in Sources */,
@@ -28668,6 +28667,7 @@
E1BE512D0CF6C512002EA959 /* XSLTUnicodeSort.cpp in Sources */,
977E2E0E12F0FC9C00C13379 /* XSSAuditor.cpp in Sources */,
FD537352137B651800008DCE /* ZeroPole.cpp in Sources */,
+ E47E276816036EDC00EE2AFB /* DocumentStyleSheetCollection.cpp in Sources */,
4F1D11BF15FF37200026E908 /* PlatformMemoryInstrumentation.cpp in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
diff --git a/Source/WebCore/bindings/generic/RuntimeEnabledFeatures.h b/Source/WebCore/bindings/generic/RuntimeEnabledFeatures.h
index fa5945843..33a7e6fe5 100644
--- a/Source/WebCore/bindings/generic/RuntimeEnabledFeatures.h
+++ b/Source/WebCore/bindings/generic/RuntimeEnabledFeatures.h
@@ -61,16 +61,7 @@ public:
static void setWebkitIndexedDBEnabled(bool isEnabled) { isIndexedDBEnabled = isEnabled; }
static bool webkitIndexedDBEnabled() { return isIndexedDBEnabled; }
- static bool webkitIDBCursorEnabled() { return isIndexedDBEnabled; }
- static bool webkitIDBDatabaseEnabled() { return isIndexedDBEnabled; }
- static bool webkitIDBDatabaseErrorEnabled() { return isIndexedDBEnabled; }
- static bool webkitIDBDatabaseExceptionEnabled() { return isIndexedDBEnabled; }
- static bool webkitIDBFactoryEnabled() { return isIndexedDBEnabled; }
- static bool webkitIDBIndexEnabled() { return isIndexedDBEnabled; }
- static bool webkitIDBKeyRangeEnabled() { return isIndexedDBEnabled; }
- static bool webkitIDBObjectStoreEnabled() { return isIndexedDBEnabled; }
- static bool webkitIDBRequestEnabled() { return isIndexedDBEnabled; }
- static bool webkitIDBTransactionEnabled() { return isIndexedDBEnabled; }
+ static bool indexedDBEnabled() { return isIndexedDBEnabled; }
#if ENABLE(CSS_EXCLUSIONS)
static void setCSSExclusionsEnabled(bool isEnabled) { isCSSExclusionsEnabled = isEnabled; }
diff --git a/Source/WebCore/bindings/js/JSDOMWindowShell.h b/Source/WebCore/bindings/js/JSDOMWindowShell.h
index 9fe38ea41..fccc703e1 100644
--- a/Source/WebCore/bindings/js/JSDOMWindowShell.h
+++ b/Source/WebCore/bindings/js/JSDOMWindowShell.h
@@ -48,6 +48,7 @@ namespace WebCore {
{
ASSERT_ARG(window, window);
setUnwrappedObject(globalData, window);
+ structure()->setGlobalObject(*JSDOMWindow::commonJSGlobalData(), window);
}
void setWindow(PassRefPtr<DOMWindow>);
diff --git a/Source/WebCore/bindings/js/JSHTMLCanvasElementCustom.cpp b/Source/WebCore/bindings/js/JSHTMLCanvasElementCustom.cpp
index 556bdf75f..72bf386a0 100644
--- a/Source/WebCore/bindings/js/JSHTMLCanvasElementCustom.cpp
+++ b/Source/WebCore/bindings/js/JSHTMLCanvasElementCustom.cpp
@@ -29,11 +29,11 @@
#include "CanvasContextAttributes.h"
#include "HTMLCanvasElement.h"
+#include "InspectorCanvasInstrumentation.h"
#include "JSCanvasRenderingContext2D.h"
+#include "ScriptObject.h"
#if ENABLE(WEBGL)
-#include "InspectorCanvasInstrumentation.h"
#include "JSWebGLRenderingContext.h"
-#include "ScriptObject.h"
#include "WebGLContextAttributes.h"
#endif
#include <wtf/GetPtr.h>
@@ -78,14 +78,18 @@ JSValue JSHTMLCanvasElement::getContext(ExecState* exec)
if (!context)
return jsNull();
JSValue jsValue = toJS(exec, globalObject(), WTF::getPtr(context));
+ if (InspectorInstrumentation::hasFrontends()) {
+ ScriptObject contextObject(exec, jsValue.getObject());
+ ScriptObject wrapped;
+ if (context->is2d())
+ wrapped = InspectorInstrumentation::wrapCanvas2DRenderingContextForInstrumentation(canvas->document(), contextObject);
#if ENABLE(WEBGL)
- if (context->is3d() && InspectorInstrumentation::hasFrontends()) {
- ScriptObject glContext(exec, jsValue.getObject());
- ScriptObject wrapped = InspectorInstrumentation::wrapWebGLRenderingContextForInstrumentation(canvas->document(), glContext);
+ else if (context->is3d())
+ wrapped = InspectorInstrumentation::wrapWebGLRenderingContextForInstrumentation(canvas->document(), contextObject);
+#endif
if (!wrapped.hasNoValue())
return wrapped.jsValue();
}
-#endif
return jsValue;
}
diff --git a/Source/WebCore/bindings/js/JSInjectedScriptManager.cpp b/Source/WebCore/bindings/js/JSInjectedScriptManager.cpp
index dc502fc8d..9f9109849 100644
--- a/Source/WebCore/bindings/js/JSInjectedScriptManager.cpp
+++ b/Source/WebCore/bindings/js/JSInjectedScriptManager.cpp
@@ -59,7 +59,13 @@ ScriptObject InjectedScriptManager::createInjectedScript(const String& source, S
JSValue globalThisValue = scriptState->globalThisValue();
JSValue evaluationException;
- JSValue evaluationReturnValue = JSMainThreadExecState::evaluate(scriptState, sourceCode, globalThisValue, &evaluationException);
+ JSValue evaluationReturnValue;
+ if (isMainThread())
+ evaluationReturnValue = JSMainThreadExecState::evaluate(scriptState, sourceCode, globalThisValue, &evaluationException);
+ else {
+ JSC::JSLockHolder lock(scriptState);
+ evaluationReturnValue = JSC::evaluate(scriptState, sourceCode, globalThisValue, &evaluationException);
+ }
if (evaluationException)
return ScriptObject();
diff --git a/Source/WebCore/bindings/js/ScriptFunctionCall.cpp b/Source/WebCore/bindings/js/ScriptFunctionCall.cpp
index e52842e0b..be91d5cdc 100644
--- a/Source/WebCore/bindings/js/ScriptFunctionCall.cpp
+++ b/Source/WebCore/bindings/js/ScriptFunctionCall.cpp
@@ -135,7 +135,12 @@ ScriptValue ScriptFunctionCall::call(bool& hadException, bool reportExceptions)
if (callType == CallTypeNone)
return ScriptValue();
- JSValue result = JSMainThreadExecState::call(m_exec, function, callType, callData, thisObject, m_arguments);
+ JSValue result;
+ if (isMainThread())
+ result = JSMainThreadExecState::call(m_exec, function, callType, callData, thisObject, m_arguments);
+ else
+ result = JSC::call(m_exec, function, callType, callData, thisObject, m_arguments);
+
if (m_exec->hadException()) {
if (reportExceptions)
reportException(m_exec, m_exec->exception());
diff --git a/Source/WebCore/bindings/js/SerializedScriptValue.cpp b/Source/WebCore/bindings/js/SerializedScriptValue.cpp
index 6ae5e3803..02f8cff66 100644
--- a/Source/WebCore/bindings/js/SerializedScriptValue.cpp
+++ b/Source/WebCore/bindings/js/SerializedScriptValue.cpp
@@ -1320,7 +1320,7 @@ private:
void putProperty(JSObject* object, const Identifier& property, JSValue value)
{
- object->putDirect(m_exec->globalData(), property, value);
+ object->putDirectMayBeIndex(m_exec, property, value);
}
bool readFile(RefPtr<File>& file)
diff --git a/Source/WebCore/bindings/scripts/CodeGeneratorGObject.pm b/Source/WebCore/bindings/scripts/CodeGeneratorGObject.pm
index c84087b19..5d8af4a0e 100644
--- a/Source/WebCore/bindings/scripts/CodeGeneratorGObject.pm
+++ b/Source/WebCore/bindings/scripts/CodeGeneratorGObject.pm
@@ -203,7 +203,7 @@ sub SkipAttribute {
}
# Skip indexed database attributes for now, they aren't yet supported for the GObject generator.
- if ($attribute->signature->name =~ /^webkitIndexedDB/ or $attribute->signature->name =~ /^webkitIDB/) {
+ if ($attribute->signature->name =~ /^(?:webkit)?[Ii]ndexedDB/ or $attribute->signature->name =~ /^(?:webkit)?IDB/) {
return 1;
}
diff --git a/Source/WebCore/bindings/v8/V8PerIsolateData.cpp b/Source/WebCore/bindings/v8/V8PerIsolateData.cpp
index e1bc31e5c..4e1e0a1f5 100644
--- a/Source/WebCore/bindings/v8/V8PerIsolateData.cpp
+++ b/Source/WebCore/bindings/v8/V8PerIsolateData.cpp
@@ -28,6 +28,7 @@
#include "ScriptGCEvent.h"
#include "V8Binding.h"
+#include <wtf/MemoryInstrumentationVector.h>
namespace WebCore {
@@ -87,7 +88,7 @@ void V8PerIsolateData::reportMemoryUsage(MemoryObjectInfo* memoryObjectInfo) con
info.addHashMap(m_rawTemplates);
info.addHashMap(m_templates);
info.addMember(m_stringCache);
- info.addVector(m_domDataList);
+ info.addMember(m_domDataList);
for (size_t i = 0; i < m_domDataList.size(); i++)
info.addMember(m_domDataList[i]);
diff --git a/Source/WebCore/bindings/v8/custom/V8ArrayBufferViewCustom.h b/Source/WebCore/bindings/v8/custom/V8ArrayBufferViewCustom.h
index 1ce2bebd1..615584438 100644
--- a/Source/WebCore/bindings/v8/custom/V8ArrayBufferViewCustom.h
+++ b/Source/WebCore/bindings/v8/custom/V8ArrayBufferViewCustom.h
@@ -52,6 +52,7 @@ v8::Handle<v8::Value> wrapArrayBufferView(const v8::Arguments& args, WrapperType
{
// Transform the holder into a wrapper object for the array.
V8DOMWrapper::setDOMWrapper(args.Holder(), type, array.get());
+ ASSERT(!hasIndexer || static_cast<int32_t>(array.get()->length()) >= 0);
if (hasIndexer)
args.Holder()->SetIndexedPropertiesToExternalArrayData(array.get()->baseAddress(), arrayType, array.get()->length());
v8::Handle<v8::Object> wrapper = args.Holder();
@@ -85,6 +86,10 @@ v8::Handle<v8::Value> constructWebGLArrayWithArrayBufferArgument(const v8::Argum
return throwError(RangeError, "ArrayBuffer length minus the byteOffset is not a multiple of the element size.", args.GetIsolate());
length = (buf->byteLength() - offset) / sizeof(ElementType);
}
+
+ if (static_cast<int32_t>(length) < 0)
+ return throwError(RangeError, tooLargeSize, args.GetIsolate());
+
RefPtr<ArrayClass> array = ArrayClass::create(buf, offset, length);
if (!array)
return throwError(RangeError, tooLargeSize, args.GetIsolate());
@@ -143,6 +148,10 @@ v8::Handle<v8::Value> constructWebGLArray(const v8::Arguments& args, WrapperType
if (JavaScriptWrapperArrayType::HasInstance(args[0])) {
ArrayClass* source = JavaScriptWrapperArrayType::toNative(args[0]->ToObject());
uint32_t length = source->length();
+
+ if (static_cast<int32_t>(length) < 0)
+ return throwError(RangeError, tooLargeSize, args.GetIsolate());
+
RefPtr<ArrayClass> array = ArrayClass::createUninitialized(length);
if (!array.get())
return throwError(RangeError, tooLargeSize, args.GetIsolate());
@@ -174,6 +183,9 @@ v8::Handle<v8::Value> constructWebGLArray(const v8::Arguments& args, WrapperType
}
}
+ if (static_cast<int32_t>(len) < 0)
+ return throwError(RangeError, tooLargeSize, args.GetIsolate());
+
RefPtr<ArrayClass> array;
if (doInstantiation) {
if (srcArray.IsEmpty())
diff --git a/Source/WebCore/bindings/v8/custom/V8HTMLCanvasElementCustom.cpp b/Source/WebCore/bindings/v8/custom/V8HTMLCanvasElementCustom.cpp
index 0b157279c..a6fb22a44 100644
--- a/Source/WebCore/bindings/v8/custom/V8HTMLCanvasElementCustom.cpp
+++ b/Source/WebCore/bindings/v8/custom/V8HTMLCanvasElementCustom.cpp
@@ -35,12 +35,12 @@
#include "CanvasContextAttributes.h"
#include "CanvasRenderingContext.h"
#include "HTMLCanvasElement.h"
+#include "InspectorCanvasInstrumentation.h"
#include "WebGLContextAttributes.h"
#include "V8Binding.h"
#include "V8CanvasRenderingContext2D.h"
#include "V8Node.h"
#if ENABLE(WEBGL)
-#include "InspectorCanvasInstrumentation.h"
#include "V8WebGLRenderingContext.h"
#endif
#include <wtf/MathExtras.h>
@@ -85,9 +85,17 @@ v8::Handle<v8::Value> V8HTMLCanvasElement::getContextCallback(const v8::Argument
CanvasRenderingContext* result = imp->getContext(contextId, attrs.get());
if (!result)
return v8::Null(args.GetIsolate());
-
- if (result->is2d())
- return toV8(static_cast<CanvasRenderingContext2D*>(result), args.Holder(), args.GetIsolate());
+ else if (result->is2d()) {
+ v8::Handle<v8::Value> v8Result = toV8(static_cast<CanvasRenderingContext2D*>(result), args.Holder(), args.GetIsolate());
+ if (InspectorInstrumentation::hasFrontends()) {
+ ScriptState* scriptState = ScriptState::forContext(v8::Context::GetCurrent());
+ ScriptObject context(scriptState, v8::Handle<v8::Object>::Cast(v8Result));
+ ScriptObject wrapped = InspectorInstrumentation::wrapCanvas2DRenderingContextForInstrumentation(imp->document(), context);
+ if (!wrapped.hasNoValue())
+ return wrapped.v8Value();
+ }
+ return v8Result;
+ }
#if ENABLE(WEBGL)
else if (result->is3d()) {
// 3D canvas contexts can hold on to lots of GPU resources, and we want to take an
diff --git a/Source/WebCore/css/CSSGradientValue.cpp b/Source/WebCore/css/CSSGradientValue.cpp
index f9715f27f..d00c1308e 100644
--- a/Source/WebCore/css/CSSGradientValue.cpp
+++ b/Source/WebCore/css/CSSGradientValue.cpp
@@ -37,6 +37,7 @@
#include "RenderObject.h"
#include "StyleResolver.h"
#include "WebCoreMemoryInstrumentation.h"
+#include <wtf/MemoryInstrumentationVector.h>
#include <wtf/text/StringBuilder.h>
#include <wtf/text/WTFString.h>
@@ -469,7 +470,7 @@ void CSSGradientValue::reportBaseClassMemoryUsage(MemoryObjectInfo* memoryObject
info.addMember(m_firstY);
info.addMember(m_secondX);
info.addMember(m_secondY);
- info.addInstrumentedVector(m_stops);
+ info.addMember(m_stops);
}
String CSSLinearGradientValue::customCssText() const
diff --git a/Source/WebCore/css/CSSImageSetValue.cpp b/Source/WebCore/css/CSSImageSetValue.cpp
index 5e6bee5a6..6e02a20f9 100644
--- a/Source/WebCore/css/CSSImageSetValue.cpp
+++ b/Source/WebCore/css/CSSImageSetValue.cpp
@@ -37,6 +37,7 @@
#include "StyleCachedImageSet.h"
#include "StylePendingImage.h"
#include "WebCoreMemoryInstrumentation.h"
+#include <wtf/MemoryInstrumentationVector.h>
namespace WebCore {
@@ -168,7 +169,7 @@ void CSSImageSetValue::reportDescendantMemoryUsage(MemoryObjectInfo* memoryObjec
{
MemoryClassInfo info(memoryObjectInfo, this, WebCoreMemoryTypes::CSS);
CSSValueList::reportDescendantMemoryUsage(memoryObjectInfo);
- info.addInstrumentedVector(m_imagesInSet);
+ info.addMember(m_imagesInSet);
}
void CSSImageSetValue::ImageWithScale::reportMemoryUsage(MemoryObjectInfo* memoryObjectInfo) const
diff --git a/Source/WebCore/css/CSSMediaRule.cpp b/Source/WebCore/css/CSSMediaRule.cpp
index f0e9c79c3..8c2c973c2 100644
--- a/Source/WebCore/css/CSSMediaRule.cpp
+++ b/Source/WebCore/css/CSSMediaRule.cpp
@@ -29,6 +29,7 @@
#include "ExceptionCode.h"
#include "StyleRule.h"
#include "WebCoreMemoryInstrumentation.h"
+#include <wtf/MemoryInstrumentationVector.h>
#include <wtf/text/StringBuilder.h>
namespace WebCore {
@@ -180,7 +181,7 @@ void CSSMediaRule::reportDescendantMemoryUsage(MemoryObjectInfo* memoryObjectInf
MemoryClassInfo info(memoryObjectInfo, this, WebCoreMemoryTypes::CSS);
CSSRule::reportBaseClassMemoryUsage(memoryObjectInfo);
info.addMember(m_mediaCSSOMWrapper);
- info.addInstrumentedVector(m_childRuleCSSOMWrappers);
+ info.addMember(m_childRuleCSSOMWrappers);
info.addMember(m_ruleListCSSOMWrapper);
}
diff --git a/Source/WebCore/css/CSSParser.cpp b/Source/WebCore/css/CSSParser.cpp
index efd9bae3a..9a922f191 100644
--- a/Source/WebCore/css/CSSParser.cpp
+++ b/Source/WebCore/css/CSSParser.cpp
@@ -5994,7 +5994,7 @@ bool CSSParser::parseFlex(CSSParserValueList* args, bool important)
}
if (flexGrow == unsetValue)
- flexGrow = 0;
+ flexGrow = 1;
if (flexShrink == unsetValue)
flexShrink = 1;
if (!flexBasis)
diff --git a/Source/WebCore/css/CSSParserValues.h b/Source/WebCore/css/CSSParserValues.h
index ad11198be..83aa77c33 100644
--- a/Source/WebCore/css/CSSParserValues.h
+++ b/Source/WebCore/css/CSSParserValues.h
@@ -46,7 +46,7 @@ struct CSSParserString {
m_is8Bit = false;
}
- void init(String string)
+ void init(const String& string)
{
m_length = string.length();
if (m_length && string.is8Bit()) {
diff --git a/Source/WebCore/css/CSSRule.cpp b/Source/WebCore/css/CSSRule.cpp
index b61f3fe65..cd533d9a8 100644
--- a/Source/WebCore/css/CSSRule.cpp
+++ b/Source/WebCore/css/CSSRule.cpp
@@ -40,11 +40,7 @@
namespace WebCore {
struct SameSizeAsCSSRule : public RefCounted<SameSizeAsCSSRule> {
-#if USE(JSC)
- char bitfields;
-#else
- unsigned bitfields;
-#endif
+ unsigned char bitfields;
void* pointerUnion;
};
diff --git a/Source/WebCore/css/CSSRule.h b/Source/WebCore/css/CSSRule.h
index c3bfcab01..b31fe7b8d 100644
--- a/Source/WebCore/css/CSSRule.h
+++ b/Source/WebCore/css/CSSRule.h
@@ -127,9 +127,9 @@ protected:
void reportBaseClassMemoryUsage(MemoryObjectInfo*) const;
private:
- mutable unsigned m_hasCachedSelectorText : 1;
- unsigned m_parentIsRule : 1;
- unsigned m_type : 5;
+ mutable unsigned char m_hasCachedSelectorText : 1;
+ unsigned char m_parentIsRule : 1;
+ unsigned char m_type : 5;
union {
CSSRule* m_parentRule;
CSSStyleSheet* m_parentStyleSheet;
diff --git a/Source/WebCore/css/CSSRuleList.cpp b/Source/WebCore/css/CSSRuleList.cpp
index 472b3dd60..dadc93b15 100644
--- a/Source/WebCore/css/CSSRuleList.cpp
+++ b/Source/WebCore/css/CSSRuleList.cpp
@@ -24,6 +24,7 @@
#include "CSSRule.h"
#include "CSSStyleSheet.h"
+#include <wtf/MemoryInstrumentationVector.h>
namespace WebCore {
@@ -54,7 +55,7 @@ void StaticCSSRuleList::deref()
void StaticCSSRuleList::reportMemoryUsage(MemoryObjectInfo* memoryObjectInfo) const
{
MemoryClassInfo info(memoryObjectInfo, this, WebCoreMemoryTypes::CSS);
- info.addInstrumentedVector(m_rules);
+ info.addMember(m_rules);
}
} // namespace WebCore
diff --git a/Source/WebCore/css/CSSSelector.cpp b/Source/WebCore/css/CSSSelector.cpp
index 5c26256a8..62233e6d4 100644
--- a/Source/WebCore/css/CSSSelector.cpp
+++ b/Source/WebCore/css/CSSSelector.cpp
@@ -183,7 +183,6 @@ PseudoId CSSSelector::pseudoId(PseudoType type)
case PseudoValid:
case PseudoInvalid:
case PseudoIndeterminate:
- case PseudoScope:
case PseudoTarget:
case PseudoLang:
case PseudoNot:
@@ -265,7 +264,6 @@ static HashMap<AtomicStringImpl*, CSSSelector::PseudoType>* nameToPseudoTypeMap(
DEFINE_STATIC_LOCAL(AtomicString, scrollbarTrack, ("-webkit-scrollbar-track", AtomicString::ConstructFromLiteral));
DEFINE_STATIC_LOCAL(AtomicString, scrollbarTrackPiece, ("-webkit-scrollbar-track-piece", AtomicString::ConstructFromLiteral));
DEFINE_STATIC_LOCAL(AtomicString, selection, ("selection", AtomicString::ConstructFromLiteral));
- DEFINE_STATIC_LOCAL(AtomicString, scope, ("scope", AtomicString::ConstructFromLiteral));
DEFINE_STATIC_LOCAL(AtomicString, target, ("target", AtomicString::ConstructFromLiteral));
DEFINE_STATIC_LOCAL(AtomicString, visited, ("visited", AtomicString::ConstructFromLiteral));
DEFINE_STATIC_LOCAL(AtomicString, windowInactive, ("window-inactive", AtomicString::ConstructFromLiteral));
@@ -353,7 +351,6 @@ static HashMap<AtomicStringImpl*, CSSSelector::PseudoType>* nameToPseudoTypeMap(
nameToPseudoType->set(scrollbarTrackPiece.impl(), CSSSelector::PseudoScrollbarTrackPiece);
nameToPseudoType->set(cornerPresent.impl(), CSSSelector::PseudoCornerPresent);
nameToPseudoType->set(selection.impl(), CSSSelector::PseudoSelection);
- nameToPseudoType->set(scope.impl(), CSSSelector::PseudoScope);
nameToPseudoType->set(target.impl(), CSSSelector::PseudoTarget);
nameToPseudoType->set(visited.impl(), CSSSelector::PseudoVisited);
nameToPseudoType->set(firstPage.impl(), CSSSelector::PseudoFirstPage);
@@ -445,7 +442,6 @@ void CSSSelector::extractPseudoType() const
case PseudoValid:
case PseudoInvalid:
case PseudoIndeterminate:
- case PseudoScope:
case PseudoTarget:
case PseudoLang:
case PseudoNot:
diff --git a/Source/WebCore/css/CSSSelector.h b/Source/WebCore/css/CSSSelector.h
index 2e9e5908f..5ca24f4e0 100644
--- a/Source/WebCore/css/CSSSelector.h
+++ b/Source/WebCore/css/CSSSelector.h
@@ -116,7 +116,6 @@ namespace WebCore {
PseudoValid,
PseudoInvalid,
PseudoIndeterminate,
- PseudoScope,
PseudoTarget,
PseudoBefore,
PseudoAfter,
diff --git a/Source/WebCore/css/CSSStyleSheet.cpp b/Source/WebCore/css/CSSStyleSheet.cpp
index 0e10202c7..dcfc22006 100644
--- a/Source/WebCore/css/CSSStyleSheet.cpp
+++ b/Source/WebCore/css/CSSStyleSheet.cpp
@@ -38,6 +38,7 @@
#include "StyleRule.h"
#include "StyleSheetContents.h"
#include "WebCoreMemoryInstrumentation.h"
+#include <wtf/MemoryInstrumentationVector.h>
#include <wtf/text/StringBuilder.h>
namespace WebCore {
@@ -187,7 +188,7 @@ void CSSStyleSheet::reportMemoryUsage(MemoryObjectInfo* memoryObjectInfo) const
info.addMember(m_ownerNode);
info.addMember(m_ownerRule);
info.addMember(m_mediaCSSOMWrapper);
- info.addInstrumentedVector(m_childRuleCSSOMWrappers);
+ info.addMember(m_childRuleCSSOMWrappers);
}
void CSSStyleSheet::setDisabled(bool disabled)
diff --git a/Source/WebCore/css/CSSValueList.cpp b/Source/WebCore/css/CSSValueList.cpp
index 21e4fa703..9ec2d5085 100644
--- a/Source/WebCore/css/CSSValueList.cpp
+++ b/Source/WebCore/css/CSSValueList.cpp
@@ -23,6 +23,7 @@
#include "CSSParserValues.h"
#include "WebCoreMemoryInstrumentation.h"
+#include <wtf/MemoryInstrumentationVector.h>
#include <wtf/PassOwnPtr.h>
#include <wtf/text/StringBuilder.h>
@@ -189,7 +190,7 @@ PassRefPtr<CSSValueList> CSSValueList::cloneForCSSOM() const
void CSSValueList::reportDescendantMemoryUsage(MemoryObjectInfo* memoryObjectInfo) const
{
MemoryClassInfo info(memoryObjectInfo, this, WebCoreMemoryTypes::CSS);
- info.addInstrumentedVector(m_values);
+ info.addMember(m_values);
}
} // namespace WebCore
diff --git a/Source/WebCore/css/MediaList.cpp b/Source/WebCore/css/MediaList.cpp
index 62903d6b1..bdbc57174 100644
--- a/Source/WebCore/css/MediaList.cpp
+++ b/Source/WebCore/css/MediaList.cpp
@@ -27,6 +27,7 @@
#include "MediaQuery.h"
#include "MediaQueryExp.h"
#include "WebCoreMemoryInstrumentation.h"
+#include <wtf/MemoryInstrumentationVector.h>
#include <wtf/text/StringBuilder.h>
namespace WebCore {
@@ -215,7 +216,7 @@ String MediaQuerySet::mediaText() const
void MediaQuerySet::reportMemoryUsage(MemoryObjectInfo* memoryObjectInfo) const
{
MemoryClassInfo info(memoryObjectInfo, this, WebCoreMemoryTypes::CSS);
- info.addInstrumentedVector(m_queries);
+ info.addMember(m_queries);
}
MediaList::MediaList(MediaQuerySet* mediaQueries, CSSStyleSheet* parentSheet)
diff --git a/Source/WebCore/css/MediaQuery.cpp b/Source/WebCore/css/MediaQuery.cpp
index a3f25d712..fc4551ffb 100644
--- a/Source/WebCore/css/MediaQuery.cpp
+++ b/Source/WebCore/css/MediaQuery.cpp
@@ -31,6 +31,7 @@
#include "MediaQueryExp.h"
#include "WebCoreMemoryInstrumentation.h"
+#include <wtf/MemoryInstrumentationVector.h>
#include <wtf/NonCopyingSort.h>
#include <wtf/text/StringBuilder.h>
@@ -138,7 +139,7 @@ void MediaQuery::reportMemoryUsage(MemoryObjectInfo* memoryObjectInfo) const
{
MemoryClassInfo info(memoryObjectInfo, this, WebCoreMemoryTypes::CSS);
info.addMember(m_mediaType);
- info.addInstrumentedVectorPtr(m_expressions);
+ info.addMember(m_expressions);
info.addMember(m_serializationCache);
}
diff --git a/Source/WebCore/css/SelectorChecker.cpp b/Source/WebCore/css/SelectorChecker.cpp
index 133e2a8aa..aae47e2cf 100644
--- a/Source/WebCore/css/SelectorChecker.cpp
+++ b/Source/WebCore/css/SelectorChecker.cpp
@@ -31,6 +31,7 @@
#include "CSSSelector.h"
#include "CSSSelectorList.h"
#include "Document.h"
+#include "DocumentStyleSheetCollection.h"
#include "FocusController.h"
#include "Frame.h"
#include "FrameSelection.h"
@@ -783,7 +784,7 @@ bool SelectorChecker::checkOneSelector(const SelectorCheckingContext& context, P
if (m_mode == ResolvingStyle) {
if (context.elementStyle)
context.elementStyle->setEmptyState(result);
- else if (element->renderStyle() && (element->document()->usesSiblingRules() || element->renderStyle()->unique()))
+ else if (element->renderStyle() && (element->document()->styleSheetCollection()->usesSiblingRules() || element->renderStyle()->unique()))
element->renderStyle()->setEmptyState(result);
}
return result;
@@ -1115,10 +1116,6 @@ bool SelectorChecker::checkOneSelector(const SelectorCheckingContext& context, P
return true;
break;
}
- case CSSSelector::PseudoScope:
- if (context.scope)
- return element == context.scope;
- // If there is no scope, :scope should behave as :root -> fall through
case CSSSelector::PseudoRoot:
if (element == element->document()->documentElement())
return true;
@@ -1187,7 +1184,7 @@ bool SelectorChecker::checkOneSelector(const SelectorCheckingContext& context, P
PseudoId pseudoId = CSSSelector::pseudoId(selector->pseudoType());
if (pseudoId == FIRST_LETTER) {
if (Document* document = element->document())
- document->setUsesFirstLetterRules(true);
+ document->styleSheetCollection()->setUsesFirstLetterRules(true);
}
if (pseudoId != NOPSEUDO)
dynamicPseudo = pseudoId;
diff --git a/Source/WebCore/css/StylePropertySet.cpp b/Source/WebCore/css/StylePropertySet.cpp
index 6e3c0fde9..52e4a24d7 100644
--- a/Source/WebCore/css/StylePropertySet.cpp
+++ b/Source/WebCore/css/StylePropertySet.cpp
@@ -19,8 +19,6 @@
* Boston, MA 02110-1301, USA.
*/
-#define WTF_DEPRECATED_STRING_OPERATORS
-
#include "config.h"
#include "StylePropertySet.h"
@@ -33,6 +31,7 @@
#include "StylePropertyShorthand.h"
#include "StyleSheetContents.h"
#include <wtf/BitArray.h>
+#include <wtf/MemoryInstrumentationVector.h>
#include <wtf/text/StringBuilder.h>
#ifndef NDEBUG
@@ -1123,7 +1122,7 @@ void StylePropertySet::reportMemoryUsage(MemoryObjectInfo* memoryObjectInfo) con
size_t actualSize = m_isMutable ? sizeof(StylePropertySet) : immutableStylePropertySetSize(m_arraySize);
MemoryClassInfo info(memoryObjectInfo, this, WebCoreMemoryTypes::CSS, actualSize);
if (m_isMutable)
- info.addVectorPtr(m_mutablePropertyVector);
+ info.addMember(m_mutablePropertyVector);
unsigned count = propertyCount();
for (unsigned i = 0; i < count; ++i)
diff --git a/Source/WebCore/css/StyleResolver.cpp b/Source/WebCore/css/StyleResolver.cpp
index ec0c39c49..6ae35acf8 100644
--- a/Source/WebCore/css/StyleResolver.cpp
+++ b/Source/WebCore/css/StyleResolver.cpp
@@ -60,6 +60,7 @@
#include "Counter.h"
#include "CounterContent.h"
#include "CursorList.h"
+#include "DocumentStyleSheetCollection.h"
#include "FontFeatureValue.h"
#include "FontValue.h"
#include "Frame.h"
@@ -125,6 +126,7 @@
#include "WebKitCSSTransformValue.h"
#include "WebKitFontFamilyNames.h"
#include "XMLNames.h"
+#include <wtf/MemoryInstrumentationVector.h>
#include <wtf/StdLibExtras.h>
#include <wtf/Vector.h>
@@ -428,12 +430,13 @@ StyleResolver::StyleResolver(Document* document, bool matchAuthorAndUserStyles)
// Note that there usually is only 1 sheet for scoped rules, so auto-shrink-to-fit is fine.
m_authorStyle->disableAutoShrinkToFit();
+ DocumentStyleSheetCollection* styleSheetCollection = document->styleSheetCollection();
// FIXME: This sucks! The user sheet is reparsed every time!
OwnPtr<RuleSet> tempUserStyle = RuleSet::create();
- if (CSSStyleSheet* pageUserSheet = document->pageUserSheet())
+ if (CSSStyleSheet* pageUserSheet = styleSheetCollection->pageUserSheet())
tempUserStyle->addRulesFromSheet(pageUserSheet->contents(), *m_medium, this);
- addAuthorRulesAndCollectUserRulesFromSheets(document->pageGroupUserSheets(), *tempUserStyle);
- addAuthorRulesAndCollectUserRulesFromSheets(document->documentUserSheets(), *tempUserStyle);
+ addAuthorRulesAndCollectUserRulesFromSheets(styleSheetCollection->pageGroupUserSheets(), *tempUserStyle);
+ addAuthorRulesAndCollectUserRulesFromSheets(styleSheetCollection->documentUserSheets(), *tempUserStyle);
if (tempUserStyle->m_ruleCount > 0 || tempUserStyle->m_pageRules.size() > 0)
m_userStyle = tempUserStyle.release();
@@ -447,7 +450,7 @@ StyleResolver::StyleResolver(Document* document, bool matchAuthorAndUserStyles)
#endif
addStylesheetsFromSeamlessParents();
- appendAuthorStylesheets(0, document->styleSheets()->vector());
+ appendAuthorStylesheets(0, styleSheetCollection->authorStyleSheets());
}
void StyleResolver::addStylesheetsFromSeamlessParents()
@@ -455,14 +458,14 @@ void StyleResolver::addStylesheetsFromSeamlessParents()
// Build a list of stylesheet lists from our ancestors, and walk that
// list in reverse order so that the root-most sheets are appended first.
Document* childDocument = document();
- Vector<StyleSheetList*> ancestorSheets;
+ Vector<const Vector<RefPtr<StyleSheet> >* > ancestorSheets;
while (HTMLIFrameElement* parentIFrame = childDocument->seamlessParentIFrame()) {
Document* parentDocument = parentIFrame->document();
- ancestorSheets.append(parentDocument->styleSheets());
+ ancestorSheets.append(&parentDocument->styleSheetCollection()->authorStyleSheets());
childDocument = parentDocument;
}
for (int i = ancestorSheets.size() - 1; i >= 0; i--)
- appendAuthorStylesheets(0, ancestorSheets.at(i)->vector());
+ appendAuthorStylesheets(0, *ancestorSheets[i]);
}
void StyleResolver::addAuthorRulesAndCollectUserRulesFromSheets(const Vector<RefPtr<CSSStyleSheet> >* userSheets, RuleSet& userStyle)
@@ -708,7 +711,6 @@ void StyleResolver::sweepMatchedPropertiesCache()
StyleResolver::Features::Features()
: usesFirstLineRules(false)
, usesBeforeAfterRules(false)
- , usesLinkRules(false)
{
}
@@ -728,7 +730,6 @@ void StyleResolver::Features::add(const StyleResolver::Features& other)
uncommonAttributeRules.append(other.uncommonAttributeRules);
usesFirstLineRules = usesFirstLineRules || other.usesFirstLineRules;
usesBeforeAfterRules = usesBeforeAfterRules || other.usesBeforeAfterRules;
- usesLinkRules = usesLinkRules || other.usesLinkRules;
}
void StyleResolver::Features::clear()
@@ -739,7 +740,6 @@ void StyleResolver::Features::clear()
uncommonAttributeRules.clear();
usesFirstLineRules = false;
usesBeforeAfterRules = false;
- usesLinkRules = false;
}
void StyleResolver::Features::reportMemoryUsage(MemoryObjectInfo* memoryObjectInfo) const
@@ -747,8 +747,8 @@ void StyleResolver::Features::reportMemoryUsage(MemoryObjectInfo* memoryObjectIn
MemoryClassInfo info(memoryObjectInfo, this, WebCoreMemoryTypes::CSS);
info.addHashSet(idsInRules);
info.addHashSet(attrsInRules);
- info.addVector(siblingRules);
- info.addVector(uncommonAttributeRules);
+ info.addMember(siblingRules);
+ info.addMember(uncommonAttributeRules);
}
static StyleSheetContents* parseUASheet(const String& str)
@@ -2568,7 +2568,7 @@ static void reportAtomRuleMap(MemoryClassInfo* info, const RuleSet::AtomRuleMap&
{
info->addHashMap(atomicRuleMap);
for (RuleSet::AtomRuleMap::const_iterator it = atomicRuleMap.begin(); it != atomicRuleMap.end(); ++it)
- info->addInstrumentedVector(*it->second);
+ info->addMember(*it->second);
}
void RuleSet::reportMemoryUsage(MemoryObjectInfo* memoryObjectInfo) const
@@ -2578,11 +2578,11 @@ void RuleSet::reportMemoryUsage(MemoryObjectInfo* memoryObjectInfo) const
reportAtomRuleMap(&info, m_classRules);
reportAtomRuleMap(&info, m_tagRules);
reportAtomRuleMap(&info, m_shadowPseudoElementRules);
- info.addInstrumentedVector(m_linkPseudoClassRules);
- info.addInstrumentedVector(m_focusPseudoClassRules);
- info.addInstrumentedVector(m_universalRules);
- info.addVector(m_pageRules);
- info.addInstrumentedVector(m_regionSelectorsAndRuleSets);
+ info.addMember(m_linkPseudoClassRules);
+ info.addMember(m_focusPseudoClassRules);
+ info.addMember(m_universalRules);
+ info.addMember(m_pageRules);
+ info.addMember(m_regionSelectorsAndRuleSets);
}
void RuleSet::RuleSetSelectorPair::reportMemoryUsage(MemoryObjectInfo* memoryObjectInfo) const
@@ -2605,10 +2605,6 @@ static inline void collectFeaturesFromSelector(StyleResolver::Features& features
case CSSSelector::PseudoAfter:
features.usesBeforeAfterRules = true;
break;
- case CSSSelector::PseudoLink:
- case CSSSelector::PseudoVisited:
- features.usesLinkRules = true;
- break;
default:
break;
}
@@ -3181,25 +3177,25 @@ static void collectCSSOMWrappers(HashMap<StyleRule*, RefPtr<CSSStyleRule> >& wra
collectCSSOMWrappers(wrapperMap, styleSheetWrapper.get());
}
-static void collectCSSOMWrappers(HashMap<StyleRule*, RefPtr<CSSStyleRule> >& wrapperMap, Document* document)
+static void collectCSSOMWrappers(HashMap<StyleRule*, RefPtr<CSSStyleRule> >& wrapperMap, DocumentStyleSheetCollection* styleSheetCollection)
{
- const Vector<RefPtr<StyleSheet> >& styleSheets = document->styleSheets()->vector();
+ const Vector<RefPtr<StyleSheet> >& styleSheets = styleSheetCollection->authorStyleSheets();
for (unsigned i = 0; i < styleSheets.size(); ++i) {
StyleSheet* styleSheet = styleSheets[i].get();
if (!styleSheet->isCSSStyleSheet())
continue;
collectCSSOMWrappers(wrapperMap, static_cast<CSSStyleSheet*>(styleSheet));
}
- collectCSSOMWrappers(wrapperMap, document->pageUserSheet());
+ collectCSSOMWrappers(wrapperMap, styleSheetCollection->pageUserSheet());
{
- const Vector<RefPtr<CSSStyleSheet> >* pageGroupUserSheets = document->pageGroupUserSheets();
+ const Vector<RefPtr<CSSStyleSheet> >* pageGroupUserSheets = styleSheetCollection->pageGroupUserSheets();
if (pageGroupUserSheets) {
for (size_t i = 0, size = pageGroupUserSheets->size(); i < size; ++i)
collectCSSOMWrappers(wrapperMap, pageGroupUserSheets->at(i).get());
}
}
{
- const Vector<RefPtr<CSSStyleSheet> >* documentUserSheets = document->documentUserSheets();
+ const Vector<RefPtr<CSSStyleSheet> >* documentUserSheets = styleSheetCollection->documentUserSheets();
if (documentUserSheets) {
for (size_t i = 0, size = documentUserSheets->size(); i < size; ++i)
collectCSSOMWrappers(wrapperMap, documentUserSheets->at(i).get());
@@ -3218,7 +3214,7 @@ CSSStyleRule* StyleResolver::ensureFullCSSOMWrapperForInspector(StyleRule* rule)
collectCSSOMWrappers(m_styleRuleToCSSOMWrapperMap, m_styleSheetCSSOMWrapperSet, mediaControlsStyleSheet);
collectCSSOMWrappers(m_styleRuleToCSSOMWrapperMap, m_styleSheetCSSOMWrapperSet, fullscreenStyleSheet);
- collectCSSOMWrappers(m_styleRuleToCSSOMWrapperMap, document());
+ collectCSSOMWrappers(m_styleRuleToCSSOMWrapperMap, document()->styleSheetCollection());
}
return m_styleRuleToCSSOMWrapperMap.get(rule).get();
}
@@ -5767,7 +5763,7 @@ void StyleResolver::MatchedProperties::reportMemoryUsage(MemoryObjectInfo* memor
void StyleResolver::MatchedPropertiesCacheItem::reportMemoryUsage(MemoryObjectInfo* memoryObjectInfo) const
{
MemoryClassInfo info(memoryObjectInfo, this, WebCoreMemoryTypes::CSS);
- info.addInstrumentedVector(matchedProperties);
+ info.addMember(matchedProperties);
}
void MediaQueryResult::reportMemoryUsage(MemoryObjectInfo* memoryObjectInfo) const
@@ -5787,13 +5783,13 @@ void StyleResolver::reportMemoryUsage(MemoryObjectInfo* memoryObjectInfo) const
info.addHashMap(m_keyframesRuleMap);
info.addHashMap(m_matchedPropertiesCache);
info.addInstrumentedMapValues(m_matchedPropertiesCache);
- info.addVector(m_matchedRules);
+ info.addMember(m_matchedRules);
info.addMember(m_ruleList);
info.addHashMap(m_pendingImageProperties);
info.addInstrumentedMapValues(m_pendingImageProperties);
info.addMember(m_lineHeightValue);
- info.addInstrumentedVector(m_viewportDependentMediaQueryResults);
+ info.addMember(m_viewportDependentMediaQueryResults);
info.addHashMap(m_styleRuleToCSSOMWrapperMap);
info.addInstrumentedMapEntries(m_styleRuleToCSSOMWrapperMap);
info.addInstrumentedHashSet(m_styleSheetCSSOMWrapperSet);
@@ -5803,7 +5799,7 @@ void StyleResolver::reportMemoryUsage(MemoryObjectInfo* memoryObjectInfo) const
#if ENABLE(STYLE_SCOPED)
info.addHashMap(m_scopedAuthorStyles);
info.addInstrumentedMapEntries(m_scopedAuthorStyles);
- info.addVector(m_scopeStack);
+ info.addMember(m_scopeStack);
#endif
// FIXME: move this to a place where it would be called only once?
diff --git a/Source/WebCore/css/StyleResolver.h b/Source/WebCore/css/StyleResolver.h
index 9c6fe1d3c..2e530f0e5 100644
--- a/Source/WebCore/css/StyleResolver.h
+++ b/Source/WebCore/css/StyleResolver.h
@@ -244,7 +244,6 @@ public:
bool usesSiblingRules() const { return !m_features.siblingRules.isEmpty(); }
bool usesFirstLineRules() const { return m_features.usesFirstLineRules; }
bool usesBeforeAfterRules() const { return m_features.usesBeforeAfterRules; }
- bool usesLinkRules() const { return m_features.usesLinkRules; }
static bool createTransformOperations(CSSValue* inValue, RenderStyle* inStyle, RenderStyle* rootStyle, TransformOperations& outOperations);
@@ -297,7 +296,6 @@ public:
Vector<RuleFeature> uncommonAttributeRules;
bool usesFirstLineRules;
bool usesBeforeAfterRules;
- bool usesLinkRules;
};
private:
diff --git a/Source/WebCore/css/StyleRule.cpp b/Source/WebCore/css/StyleRule.cpp
index 5ece1b4a2..73b0af26c 100644
--- a/Source/WebCore/css/StyleRule.cpp
+++ b/Source/WebCore/css/StyleRule.cpp
@@ -33,6 +33,7 @@
#include "WebKitCSSKeyframeRule.h"
#include "WebKitCSSKeyframesRule.h"
#include "WebKitCSSRegionRule.h"
+#include <wtf/MemoryInstrumentationVector.h>
namespace WebCore {
@@ -340,7 +341,7 @@ void StyleRuleBlock::wrapperRemoveRule(unsigned index)
void StyleRuleBlock::reportDescendantMemoryUsage(MemoryObjectInfo* memoryObjectInfo) const
{
MemoryClassInfo info(memoryObjectInfo, this, WebCoreMemoryTypes::CSS);
- info.addInstrumentedVector(m_childRules);
+ info.addMember(m_childRules);
}
StyleRuleMedia::StyleRuleMedia(PassRefPtr<MediaQuerySet> media, Vector<RefPtr<StyleRuleBase> >& adoptRules)
diff --git a/Source/WebCore/css/StyleSheetContents.cpp b/Source/WebCore/css/StyleSheetContents.cpp
index 048273bec..945f355a3 100644
--- a/Source/WebCore/css/StyleSheetContents.cpp
+++ b/Source/WebCore/css/StyleSheetContents.cpp
@@ -33,6 +33,7 @@
#include "StyleRuleImport.h"
#include "WebCoreMemoryInstrumentation.h"
#include <wtf/Deque.h>
+#include <wtf/MemoryInstrumentationVector.h>
namespace WebCore {
@@ -489,10 +490,10 @@ void StyleSheetContents::reportMemoryUsage(MemoryObjectInfo* memoryObjectInfo) c
MemoryClassInfo info(memoryObjectInfo, this, WebCoreMemoryTypes::CSS);
info.addMember(m_originalURL);
info.addMember(m_encodingFromCharsetRule);
- info.addVector(m_importRules);
- info.addInstrumentedVector(m_childRules);
+ info.addMember(m_importRules);
+ info.addMember(m_childRules);
info.addHashMap(m_namespaces);
- info.addVector(m_clients);
+ info.addMember(m_clients);
}
}
diff --git a/Source/WebCore/css/StyleSheetList.cpp b/Source/WebCore/css/StyleSheetList.cpp
index f1ab52dc9..0f8fc2517 100644
--- a/Source/WebCore/css/StyleSheetList.cpp
+++ b/Source/WebCore/css/StyleSheetList.cpp
@@ -23,6 +23,7 @@
#include "CSSStyleSheet.h"
#include "Document.h"
+#include "DocumentStyleSheetCollection.h"
#include "HTMLNames.h"
#include "HTMLStyleElement.h"
#include <wtf/text/WTFString.h>
@@ -31,8 +32,8 @@ namespace WebCore {
using namespace HTMLNames;
-StyleSheetList::StyleSheetList(Document* doc)
- : m_doc(doc)
+StyleSheetList::StyleSheetList(Document* document)
+ : m_document(document)
{
}
@@ -40,24 +41,33 @@ StyleSheetList::~StyleSheetList()
{
}
-void StyleSheetList::documentDestroyed()
+inline const Vector<RefPtr<StyleSheet> >& StyleSheetList::styleSheets() const
{
- m_doc = 0;
+ if (!m_document)
+ return m_detachedStyleSheets;
+ return m_document->styleSheetCollection()->authorStyleSheets();
+}
+
+void StyleSheetList::detachFromDocument()
+{
+ m_detachedStyleSheets = m_document->styleSheetCollection()->authorStyleSheets();
+ m_document = 0;
}
unsigned StyleSheetList::length() const
{
- return m_sheets.size();
+ return styleSheets().size();
}
StyleSheet* StyleSheetList::item(unsigned index)
{
- return index < length() ? m_sheets[index].get() : 0;
+ const Vector<RefPtr<StyleSheet> >& sheets = styleSheets();
+ return index < sheets.size() ? sheets[index].get() : 0;
}
HTMLStyleElement* StyleSheetList::getNamedItem(const String& name) const
{
- if (!m_doc)
+ if (!m_document)
return 0;
// IE also supports retrieving a stylesheet by name, using the name/id of the <style> tag
@@ -65,8 +75,7 @@ HTMLStyleElement* StyleSheetList::getNamedItem(const String& name) const
// ### Bad implementation because returns a single element (are IDs always unique?)
// and doesn't look for name attribute.
// But unicity of stylesheet ids is good practice anyway ;)
-
- Element* element = m_doc->getElementById(name);
+ Element* element = m_document->getElementById(name);
if (element && element->hasTagName(styleTag))
return static_cast<HTMLStyleElement*>(element);
return 0;
diff --git a/Source/WebCore/css/StyleSheetList.h b/Source/WebCore/css/StyleSheetList.h
index 3f81163e6..c05284159 100644
--- a/Source/WebCore/css/StyleSheetList.h
+++ b/Source/WebCore/css/StyleSheetList.h
@@ -32,40 +32,26 @@ class Document;
class HTMLStyleElement;
class StyleSheet;
-typedef Vector<RefPtr<StyleSheet> > StyleSheetVector;
-
class StyleSheetList : public RefCounted<StyleSheetList> {
public:
- static PassRefPtr<StyleSheetList> create(Document* doc) { return adoptRef(new StyleSheetList(doc)); }
+ static PassRefPtr<StyleSheetList> create(Document* document) { return adoptRef(new StyleSheetList(document)); }
~StyleSheetList();
- void documentDestroyed();
-
unsigned length() const;
StyleSheet* item(unsigned index);
HTMLStyleElement* getNamedItem(const String&) const;
- const StyleSheetVector& vector() const
- {
- return m_sheets;
- }
-
- void swap(StyleSheetVector& sheets)
- {
- m_sheets.swap(sheets);
- }
+ Document* document() { return m_document; }
- Document* document()
- {
- return m_doc;
- }
+ void detachFromDocument();
private:
StyleSheetList(Document*);
+ const Vector<RefPtr<StyleSheet> >& styleSheets() const;
- Document* m_doc;
- StyleSheetVector m_sheets;
+ Document* m_document;
+ Vector<RefPtr<StyleSheet> > m_detachedStyleSheets;
};
} // namespace WebCore
diff --git a/Source/WebCore/css/WebKitCSSKeyframesRule.cpp b/Source/WebCore/css/WebKitCSSKeyframesRule.cpp
index a2991a818..08fbb0a55 100644
--- a/Source/WebCore/css/WebKitCSSKeyframesRule.cpp
+++ b/Source/WebCore/css/WebKitCSSKeyframesRule.cpp
@@ -33,6 +33,7 @@
#include "StyleSheet.h"
#include "WebCoreMemoryInstrumentation.h"
#include "WebKitCSSKeyframeRule.h"
+#include <wtf/MemoryInstrumentationVector.h>
#include <wtf/text/StringBuilder.h>
namespace WebCore {
@@ -90,7 +91,7 @@ int StyleRuleKeyframes::findKeyframeIndex(const String& key) const
void StyleRuleKeyframes::reportDescendantMemoryUsage(MemoryObjectInfo* memoryObjectInfo) const
{
MemoryClassInfo info(memoryObjectInfo, this, WebCoreMemoryTypes::CSS);
- info.addInstrumentedVector(m_keyframes);
+ info.addMember(m_keyframes);
info.addMember(m_name);
}
@@ -211,7 +212,7 @@ void WebKitCSSKeyframesRule::reportDescendantMemoryUsage(MemoryObjectInfo* memor
MemoryClassInfo info(memoryObjectInfo, this, WebCoreMemoryTypes::CSS);
CSSRule::reportBaseClassMemoryUsage(memoryObjectInfo);
info.addMember(m_keyframesRule);
- info.addInstrumentedVector(m_childRuleCSSOMWrappers);
+ info.addMember(m_childRuleCSSOMWrappers);
info.addMember(m_ruleListCSSOMWrapper);
}
diff --git a/Source/WebCore/css/WebKitCSSRegionRule.cpp b/Source/WebCore/css/WebKitCSSRegionRule.cpp
index 5c2c721cd..ce1207cab 100644
--- a/Source/WebCore/css/WebKitCSSRegionRule.cpp
+++ b/Source/WebCore/css/WebKitCSSRegionRule.cpp
@@ -34,6 +34,7 @@
#include "CSSParser.h"
#include "CSSRuleList.h"
#include "StyleRule.h"
+#include <wtf/MemoryInstrumentationVector.h>
#include <wtf/text/StringBuilder.h>
#if ENABLE(CSS_REGIONS)
@@ -113,7 +114,7 @@ void WebKitCSSRegionRule::reportDescendantMemoryUsage(MemoryObjectInfo* memoryOb
MemoryClassInfo info(memoryObjectInfo, this, WebCoreMemoryTypes::CSS);
CSSRule::reportBaseClassMemoryUsage(memoryObjectInfo);
info.addMember(m_regionRule);
- info.addInstrumentedVector(m_childRuleCSSOMWrappers);
+ info.addMember(m_childRuleCSSOMWrappers);
info.addMember(m_ruleListCSSOMWrapper);
}
diff --git a/Source/WebCore/dom/CharacterData.idl b/Source/WebCore/dom/CharacterData.idl
index 2bb3d4e49..bf8fef19f 100644
--- a/Source/WebCore/dom/CharacterData.idl
+++ b/Source/WebCore/dom/CharacterData.idl
@@ -45,7 +45,10 @@ module core {
in [IsIndex,Optional=DefaultIsUndefined] unsigned long length,
in [Optional=DefaultIsUndefined] DOMString data)
raises(DOMException);
-
+
+ // DOM 4
+ void remove()
+ raises(DOMException);
};
}
diff --git a/Source/WebCore/dom/ContainerNode.cpp b/Source/WebCore/dom/ContainerNode.cpp
index cd118f17d..dafee6077 100644
--- a/Source/WebCore/dom/ContainerNode.cpp
+++ b/Source/WebCore/dom/ContainerNode.cpp
@@ -419,15 +419,15 @@ bool ContainerNode::removeChild(Node* oldChild, ExceptionCode& ec)
return false;
}
- RenderWidget::suspendWidgetHierarchyUpdates();
-
- Node* prev = child->previousSibling();
- Node* next = child->nextSibling();
- removeBetween(prev, next, child.get());
- childrenChanged(false, prev, next, -1);
- ChildNodeRemovalNotifier(this).notify(child.get());
-
- RenderWidget::resumeWidgetHierarchyUpdates();
+ {
+ WidgetHierarchyUpdatesSuspensionScope suspendWidgetHierarchyUpdates;
+
+ Node* prev = child->previousSibling();
+ Node* next = child->nextSibling();
+ removeBetween(prev, next, child.get());
+ childrenChanged(false, prev, next, -1);
+ ChildNodeRemovalNotifier(this).notify(child.get());
+ }
dispatchSubtreeModifiedEvent();
return child;
@@ -497,49 +497,50 @@ void ContainerNode::removeChildren()
// and remove... e.g. stop loading frames, fire unload events.
willRemoveChildren(protect.get());
- RenderWidget::suspendWidgetHierarchyUpdates();
- forbidEventDispatch();
Vector<RefPtr<Node>, 10> removedChildren;
- removedChildren.reserveInitialCapacity(childNodeCount());
- while (RefPtr<Node> n = m_firstChild) {
- Node* next = n->nextSibling();
-
- // Remove the node from the tree before calling detach or removedFromDocument (4427024, 4129744).
- // removeChild() does this after calling detach(). There is no explanation for
- // this discrepancy between removeChild() and its optimized version removeChildren().
- n->setPreviousSibling(0);
- n->setNextSibling(0);
- n->setParentOrHostNode(0);
- document()->adoptIfNeeded(n.get());
-
- m_firstChild = next;
- if (n == m_lastChild)
- m_lastChild = 0;
- removedChildren.append(n.release());
- }
+ {
+ WidgetHierarchyUpdatesSuspensionScope suspendWidgetHierarchyUpdates;
+ forbidEventDispatch();
+ removedChildren.reserveInitialCapacity(childNodeCount());
+ while (RefPtr<Node> n = m_firstChild) {
+ Node* next = n->nextSibling();
+
+ // Remove the node from the tree before calling detach or removedFromDocument (4427024, 4129744).
+ // removeChild() does this after calling detach(). There is no explanation for
+ // this discrepancy between removeChild() and its optimized version removeChildren().
+ n->setPreviousSibling(0);
+ n->setNextSibling(0);
+ n->setParentOrHostNode(0);
+ document()->adoptIfNeeded(n.get());
+
+ m_firstChild = next;
+ if (n == m_lastChild)
+ m_lastChild = 0;
+ removedChildren.append(n.release());
+ }
- size_t removedChildrenCount = removedChildren.size();
- size_t i;
-
- // Detach the nodes only after properly removed from the tree because
- // a. detaching requires a proper DOM tree (for counters and quotes for
- // example) and during the previous loop the next sibling still points to
- // the node being removed while the node being removed does not point back
- // and does not point to the same parent as its next sibling.
- // b. destroying Renderers of standalone nodes is sometimes faster.
- for (i = 0; i < removedChildrenCount; ++i) {
- Node* removedChild = removedChildren[i].get();
- if (removedChild->attached())
- removedChild->detach();
- }
+ size_t removedChildrenCount = removedChildren.size();
+ size_t i;
+
+ // Detach the nodes only after properly removed from the tree because
+ // a. detaching requires a proper DOM tree (for counters and quotes for
+ // example) and during the previous loop the next sibling still points to
+ // the node being removed while the node being removed does not point back
+ // and does not point to the same parent as its next sibling.
+ // b. destroying Renderers of standalone nodes is sometimes faster.
+ for (i = 0; i < removedChildrenCount; ++i) {
+ Node* removedChild = removedChildren[i].get();
+ if (removedChild->attached())
+ removedChild->detach();
+ }
- childrenChanged(false, 0, 0, -static_cast<int>(removedChildrenCount));
+ childrenChanged(false, 0, 0, -static_cast<int>(removedChildrenCount));
- for (i = 0; i < removedChildrenCount; ++i)
- ChildNodeRemovalNotifier(this).notify(removedChildren[i].get());
+ for (i = 0; i < removedChildrenCount; ++i)
+ ChildNodeRemovalNotifier(this).notify(removedChildren[i].get());
- allowEventDispatch();
- RenderWidget::resumeWidgetHierarchyUpdates();
+ allowEventDispatch();
+ }
dispatchSubtreeModifiedEvent();
}
diff --git a/Source/WebCore/dom/Document.cpp b/Source/WebCore/dom/Document.cpp
index 3fa6b41ab..009c84592 100644
--- a/Source/WebCore/dom/Document.cpp
+++ b/Source/WebCore/dom/Document.cpp
@@ -57,6 +57,7 @@
#include "DocumentFragment.h"
#include "DocumentLoader.h"
#include "DocumentMarkerController.h"
+#include "DocumentStyleSheetCollection.h"
#include "DocumentType.h"
#include "EditingText.h"
#include "Editor.h"
@@ -173,6 +174,7 @@
#include <wtf/CurrentTime.h>
#include <wtf/HashFunctions.h>
#include <wtf/MainThread.h>
+#include <wtf/MemoryInstrumentationVector.h>
#include <wtf/PassRefPtr.h>
#include <wtf/StdLibExtras.h>
#include <wtf/text/StringBuffer.h>
@@ -437,8 +439,7 @@ Document::Document(Frame* frame, const KURL& url, bool isXHTML, bool isHTML)
#if ENABLE(MUTATION_OBSERVERS)
, m_mutationObserverTypes(0)
#endif
- , m_styleSheets(StyleSheetList::create(this))
- , m_hadActiveLoadingStylesheet(false)
+ , m_styleSheetCollection(adoptPtr(new DocumentStyleSheetCollection(this)))
, m_readyState(Complete)
, m_styleRecalcTimer(this, &Document::styleRecalcTimerFired)
, m_pendingStyleRecalcShouldForce(false)
@@ -504,8 +505,6 @@ Document::Document(Frame* frame, const KURL& url, bool isXHTML, bool isHTML)
{
m_document = this;
- m_pageGroupUserSheetCacheValid = false;
-
m_printing = false;
m_paginatedForScreen = false;
@@ -543,20 +542,9 @@ Document::Document(Frame* frame, const KURL& url, bool isXHTML, bool isHTML)
m_inStyleRecalc = false;
m_closeAfterStyleRecalc = false;
- m_usesSiblingRules = false;
- m_usesSiblingRulesOverride = false;
- m_usesFirstLineRules = false;
- m_usesFirstLetterRules = false;
- m_usesBeforeAfterRules = false;
- m_usesBeforeAfterRulesOverride = false;
- m_usesRemUnits = false;
- m_usesLinkRules = false;
-
m_gotoAnchorNeededAfterStylesheetsLoad = false;
m_didCalculateStyleResolver = false;
- m_hasDirtyStyleResolver = false;
- m_pendingStylesheets = 0;
m_ignorePendingStylesheets = false;
m_needsNotifyRemoveAllPendingStylesheet = false;
m_hasNodesWithPlaceholderStyle = false;
@@ -643,24 +631,16 @@ Document::~Document()
m_decoder = 0;
- if (m_styleSheets)
- m_styleSheets->documentDestroyed();
+ if (m_styleSheetList)
+ m_styleSheetList->detachFromDocument();
+
+ m_styleSheetCollection.clear();
if (m_namedFlows)
m_namedFlows->documentDestroyed();
if (m_elemSheet)
m_elemSheet->clearOwnerNode();
- if (m_pageUserSheet)
- m_pageUserSheet->clearOwnerNode();
- if (m_pageGroupUserSheets) {
- for (size_t i = 0; i < m_pageGroupUserSheets->size(); ++i)
- (*m_pageGroupUserSheets)[i]->clearOwnerNode();
- }
- if (m_userSheets) {
- for (size_t i = 0; i < m_userSheets->size(); ++i)
- (*m_userSheets)[i]->clearOwnerNode();
- }
deleteCustomFonts();
@@ -802,14 +782,14 @@ void Document::setCompatibilityMode(CompatibilityMode mode)
{
if (m_compatibilityModeLocked || mode == m_compatibilityMode)
return;
- ASSERT(!m_styleSheets->length());
+ ASSERT(m_styleSheetCollection->authorStyleSheets().isEmpty());
bool wasInQuirksMode = inQuirksMode();
m_compatibilityMode = mode;
selectorQueryCache()->invalidate();
if (inQuirksMode() != wasInQuirksMode) {
// All user stylesheets have to reparse using the different mode.
- clearPageUserSheet();
- clearPageGroupUserSheets();
+ m_styleSheetCollection->clearPageUserSheet();
+ m_styleSheetCollection->clearPageGroupUserSheets();
}
}
@@ -1069,8 +1049,11 @@ PassRefPtr<Node> Document::adoptNode(PassRefPtr<Node> source, ExceptionCode& ec)
return 0;
}
}
- if (source->parentNode())
+ if (source->parentNode()) {
source->parentNode()->removeChild(source.get(), ec);
+ if (ec)
+ return 0;
+ }
}
this->adoptIfNeeded(source.get());
@@ -1822,75 +1805,76 @@ void Document::recalcStyle(StyleChange change)
// re-attaching our containing iframe, which when asked HTMLFrameElementBase::isURLAllowed
// hits a null-dereference due to security code always assuming the document has a SecurityOrigin.
- if (m_hasDirtyStyleResolver)
- updateActiveStylesheets(RecalcStyleImmediately);
+ if (m_styleSheetCollection->needsUpdateActiveStylesheetsOnStyleRecalc())
+ m_styleSheetCollection->updateActiveStyleSheets(DocumentStyleSheetCollection::FullUpdate);
InspectorInstrumentationCookie cookie = InspectorInstrumentation::willRecalculateStyle(this);
if (m_elemSheet && m_elemSheet->contents()->usesRemUnits())
- m_usesRemUnits = true;
+ m_styleSheetCollection->setUsesRemUnit(true);
m_inStyleRecalc = true;
suspendPostAttachCallbacks();
- RenderWidget::suspendWidgetHierarchyUpdates();
-
- RefPtr<FrameView> frameView = view();
- if (frameView) {
- frameView->pauseScheduledEvents();
- frameView->beginDeferredRepaints();
- }
+ {
+ WidgetHierarchyUpdatesSuspensionScope suspendWidgetHierarchyUpdates;
- ASSERT(!renderer() || renderArena());
- if (!renderer() || !renderArena())
- goto bail_out;
+ RefPtr<FrameView> frameView = view();
+ if (frameView) {
+ frameView->pauseScheduledEvents();
+ frameView->beginDeferredRepaints();
+ }
- if (m_pendingStyleRecalcShouldForce)
- change = Force;
+ ASSERT(!renderer() || renderArena());
+ if (!renderer() || !renderArena())
+ goto bailOut;
- // Recalculating the root style (on the document) is not needed in the common case.
- if ((change == Force) || (shouldDisplaySeamlesslyWithParent() && (change >= Inherit))) {
- // style selector may set this again during recalc
- m_hasNodesWithPlaceholderStyle = false;
-
- RefPtr<RenderStyle> documentStyle = StyleResolver::styleForDocument(this, m_styleResolver ? m_styleResolver->fontSelector() : 0);
- StyleChange ch = Node::diff(documentStyle.get(), renderer()->style(), this);
- if (ch != NoChange)
- renderer()->setStyle(documentStyle.release());
- }
+ if (m_pendingStyleRecalcShouldForce)
+ change = Force;
- for (Node* n = firstChild(); n; n = n->nextSibling()) {
- if (!n->isElementNode())
- continue;
- Element* element = static_cast<Element*>(n);
- if (change >= Inherit || element->childNeedsStyleRecalc() || element->needsStyleRecalc())
- element->recalcStyle(change);
- }
+ // Recalculating the root style (on the document) is not needed in the common case.
+ if ((change == Force) || (shouldDisplaySeamlesslyWithParent() && (change >= Inherit))) {
+ // style selector may set this again during recalc
+ m_hasNodesWithPlaceholderStyle = false;
+
+ RefPtr<RenderStyle> documentStyle = StyleResolver::styleForDocument(this, m_styleResolver ? m_styleResolver->fontSelector() : 0);
+ StyleChange ch = Node::diff(documentStyle.get(), renderer()->style(), this);
+ if (ch != NoChange)
+ renderer()->setStyle(documentStyle.release());
+ }
-#if USE(ACCELERATED_COMPOSITING)
- if (view()) {
- bool layoutPending = view()->layoutPending() || renderer()->needsLayout();
- // If we didn't update compositing layers because of layout(), we need to do so here.
- if (!layoutPending)
- view()->updateCompositingLayersAfterStyleChange();
- }
-#endif
+ for (Node* n = firstChild(); n; n = n->nextSibling()) {
+ if (!n->isElementNode())
+ continue;
+ Element* element = static_cast<Element*>(n);
+ if (change >= Inherit || element->childNeedsStyleRecalc() || element->needsStyleRecalc())
+ element->recalcStyle(change);
+ }
-bail_out:
- clearNeedsStyleRecalc();
- clearChildNeedsStyleRecalc();
- unscheduleStyleRecalc();
+ #if USE(ACCELERATED_COMPOSITING)
+ if (view()) {
+ bool layoutPending = view()->layoutPending() || renderer()->needsLayout();
+ // If we didn't update compositing layers because of layout(), we need to do so here.
+ if (!layoutPending)
+ view()->updateCompositingLayersAfterStyleChange();
+ }
+ #endif
- m_inStyleRecalc = false;
-
- // Pseudo element removal and similar may only work with these flags still set. Reset them after the style recalc.
- if (m_styleResolver)
- resetCSSFeatureFlags();
+ bailOut:
+ clearNeedsStyleRecalc();
+ clearChildNeedsStyleRecalc();
+ unscheduleStyleRecalc();
+
+ m_inStyleRecalc = false;
- if (frameView) {
- frameView->resumeScheduledEvents();
- frameView->endDeferredRepaints();
+ // Pseudo element removal and similar may only work with these flags still set. Reset them after the style recalc.
+ if (m_styleResolver)
+ m_styleSheetCollection->resetCSSFeatureFlags();
+
+ if (frameView) {
+ frameView->resumeScheduledEvents();
+ frameView->endDeferredRepaints();
+ }
}
- RenderWidget::resumeWidgetHierarchyUpdates();
resumePostAttachCallbacks();
// If we wanted to call implicitClose() during recalcStyle, do so now that we're finished.
@@ -2067,33 +2051,16 @@ void Document::setIsViewSource(bool isViewSource)
didUpdateSecurityOrigin();
}
-void Document::combineCSSFeatureFlags()
-{
- // Delay resetting the flags until after next style recalc since unapplying the style may not work without these set (this is true at least with before/after).
- m_usesSiblingRules = m_usesSiblingRules || m_styleResolver->usesSiblingRules();
- m_usesFirstLineRules = m_usesFirstLineRules || m_styleResolver->usesFirstLineRules();
- m_usesBeforeAfterRules = m_usesBeforeAfterRules || m_styleResolver->usesBeforeAfterRules();
- m_usesLinkRules = m_usesLinkRules || m_styleResolver->usesLinkRules();
-}
-
-void Document::resetCSSFeatureFlags()
-{
- m_usesSiblingRules = m_styleResolver->usesSiblingRules();
- m_usesFirstLineRules = m_styleResolver->usesFirstLineRules();
- m_usesBeforeAfterRules = m_styleResolver->usesBeforeAfterRules();
- m_usesLinkRules = m_styleResolver->usesLinkRules();
-}
-
void Document::createStyleResolver()
{
bool matchAuthorAndUserStyles = true;
if (Settings* docSettings = settings())
matchAuthorAndUserStyles = docSettings->authorAndUserStylesEnabled();
m_styleResolver = adoptPtr(new StyleResolver(this, matchAuthorAndUserStyles));
- combineCSSFeatureFlags();
+ m_styleSheetCollection->combineCSSFeatureFlags();
}
-inline void Document::clearStyleResolver()
+void Document::clearStyleResolver()
{
m_styleResolver.clear();
}
@@ -2903,105 +2870,23 @@ Frame* Document::findUnsafeParentScrollPropagationBoundary()
return 0;
}
-CSSStyleSheet* Document::pageUserSheet()
-{
- if (m_pageUserSheet)
- return m_pageUserSheet.get();
-
- Page* owningPage = page();
- if (!owningPage)
- return 0;
-
- String userSheetText = owningPage->userStyleSheet();
- if (userSheetText.isEmpty())
- return 0;
-
- // Parse the sheet and cache it.
- m_pageUserSheet = CSSStyleSheet::createInline(this, settings()->userStyleSheetLocation());
- m_pageUserSheet->contents()->setIsUserStyleSheet(true);
- m_pageUserSheet->contents()->parseString(userSheetText);
- return m_pageUserSheet.get();
-}
-
-void Document::clearPageUserSheet()
-{
- if (m_pageUserSheet) {
- m_pageUserSheet = 0;
- styleResolverChanged(DeferRecalcStyle);
- }
-}
-
-void Document::updatePageUserSheet()
-{
- clearPageUserSheet();
- if (pageUserSheet())
- styleResolverChanged(RecalcStyleImmediately);
-}
-const Vector<RefPtr<CSSStyleSheet> >* Document::pageGroupUserSheets() const
+void Document::seamlessParentUpdatedStylesheets()
{
- if (m_pageGroupUserSheetCacheValid)
- return m_pageGroupUserSheets.get();
-
- m_pageGroupUserSheetCacheValid = true;
-
- Page* owningPage = page();
- if (!owningPage)
- return 0;
-
- const PageGroup& pageGroup = owningPage->group();
- const UserStyleSheetMap* sheetsMap = pageGroup.userStyleSheets();
- if (!sheetsMap)
- return 0;
-
- UserStyleSheetMap::const_iterator end = sheetsMap->end();
- for (UserStyleSheetMap::const_iterator it = sheetsMap->begin(); it != end; ++it) {
- const UserStyleSheetVector* sheets = it->second.get();
- for (unsigned i = 0; i < sheets->size(); ++i) {
- const UserStyleSheet* sheet = sheets->at(i).get();
- if (sheet->injectedFrames() == InjectInTopFrameOnly && ownerElement())
- continue;
- if (!UserContentURLPattern::matchesPatterns(url(), sheet->whitelist(), sheet->blacklist()))
- continue;
- RefPtr<CSSStyleSheet> groupSheet = CSSStyleSheet::createInline(const_cast<Document*>(this), sheet->url());
- if (!m_pageGroupUserSheets)
- m_pageGroupUserSheets = adoptPtr(new Vector<RefPtr<CSSStyleSheet> >);
- m_pageGroupUserSheets->append(groupSheet);
- groupSheet->contents()->setIsUserStyleSheet(sheet->level() == UserStyleUserLevel);
- groupSheet->contents()->parseString(sheet->source());
- }
- }
-
- return m_pageGroupUserSheets.get();
+ styleResolverChanged(RecalcStyleImmediately);
}
-void Document::clearPageGroupUserSheets()
+void Document::didRemoveAllPendingStylesheet()
{
- m_pageGroupUserSheetCacheValid = false;
- if (m_pageGroupUserSheets && m_pageGroupUserSheets->size()) {
- m_pageGroupUserSheets->clear();
- styleResolverChanged(DeferRecalcStyle);
- }
-}
+ m_needsNotifyRemoveAllPendingStylesheet = false;
-void Document::updatePageGroupUserSheets()
-{
- clearPageGroupUserSheets();
- if (pageGroupUserSheets() && pageGroupUserSheets()->size())
- styleResolverChanged(RecalcStyleImmediately);
-}
+ styleResolverChanged(RecalcStyleIfNeeded);
-void Document::addUserSheet(PassRefPtr<StyleSheetContents> userSheet)
-{
- if (!m_userSheets)
- m_userSheets = adoptPtr(new Vector<RefPtr<CSSStyleSheet> >);
- m_userSheets->append(CSSStyleSheet::create(userSheet, this));
- styleResolverChanged(RecalcStyleImmediately);
-}
+ if (ScriptableDocumentParser* parser = scriptableDocumentParser())
+ parser->executeScriptsWaitingForStylesheets();
-void Document::seamlessParentUpdatedStylesheets()
-{
- styleResolverChanged(RecalcStyleImmediately);
+ if (m_gotoAnchorNeededAfterStylesheetsLoad && view())
+ view()->scrollToFragment(m_url);
}
CSSStyleSheet* Document::elementSheet()
@@ -3042,8 +2927,8 @@ void Document::processHttpEquiv(const String& equiv, const String& content)
// For more info, see the test at:
// http://www.hixie.ch/tests/evil/css/import/main/preferred.html
// -dwh
- m_selectedStylesheetSet = content;
- m_preferredStylesheetSet = content;
+ m_styleSheetCollection->setSelectedStylesheetSetName(content);
+ m_styleSheetCollection->setPreferredStylesheetSetName(content);
styleResolverChanged(DeferRecalcStyle);
} else if (equalIgnoringCase(equiv, "refresh")) {
double delay;
@@ -3315,63 +3200,27 @@ PassRefPtr<Node> Document::cloneNode(bool /*deep*/)
StyleSheetList* Document::styleSheets()
{
- return m_styleSheets.get();
+ if (!m_styleSheetList)
+ m_styleSheetList = StyleSheetList::create(this);
+ return m_styleSheetList.get();
}
String Document::preferredStylesheetSet() const
{
- return m_preferredStylesheetSet;
+ return m_styleSheetCollection->preferredStylesheetSetName();
}
String Document::selectedStylesheetSet() const
{
- return m_selectedStylesheetSet;
+ return m_styleSheetCollection->selectedStylesheetSetName();
}
void Document::setSelectedStylesheetSet(const String& aString)
{
- m_selectedStylesheetSet = aString;
+ m_styleSheetCollection->setSelectedStylesheetSetName(aString);
styleResolverChanged(DeferRecalcStyle);
}
-// This method is called whenever a top-level stylesheet has finished loading.
-void Document::removePendingSheet(RemovePendingSheetNotificationType notification)
-{
- // Make sure we knew this sheet was pending, and that our count isn't out of sync.
- ASSERT(m_pendingStylesheets > 0);
-
- m_pendingStylesheets--;
-
-#ifdef INSTRUMENT_LAYOUT_SCHEDULING
- if (!ownerElement())
- printf("Stylesheet loaded at time %d. %d stylesheets still remain.\n", elapsedTime(), m_pendingStylesheets);
-#endif
-
- if (m_pendingStylesheets)
- return;
-
- if (notification == RemovePendingSheetNotifyLater) {
- setNeedsNotifyRemoveAllPendingStylesheet();
- return;
- }
-
- didRemoveAllPendingStylesheet();
-}
-
-void Document::didRemoveAllPendingStylesheet()
-{
- m_needsNotifyRemoveAllPendingStylesheet = false;
-
- styleResolverChanged(RecalcStyleIfNeeded);
-
- if (ScriptableDocumentParser* parser = scriptableDocumentParser())
- parser->executeScriptsWaitingForStylesheets();
-
- if (m_gotoAnchorNeededAfterStylesheetsLoad && view())
- view()->scrollToFragment(m_url);
-}
-
-
void Document::evaluateMediaQueryList()
{
if (m_mediaQueryMatcher)
@@ -3386,20 +3235,24 @@ void Document::styleResolverChanged(StyleResolverUpdateFlag updateFlag)
m_styleResolver.clear();
return;
}
+ m_didCalculateStyleResolver = true;
#ifdef INSTRUMENT_LAYOUT_SCHEDULING
if (!ownerElement())
printf("Beginning update of style selector at time %d.\n", elapsedTime());
#endif
- bool stylesheetChangeRequiresStyleRecalc = updateActiveStylesheets(updateFlag);
+ DocumentStyleSheetCollection::UpdateFlag styleSheetUpdate = (updateFlag == RecalcStyleIfNeeded)
+ ? DocumentStyleSheetCollection::OptimizedUpdate
+ : DocumentStyleSheetCollection::FullUpdate;
+ bool stylesheetChangeRequiresStyleRecalc = m_styleSheetCollection->updateActiveStyleSheets(styleSheetUpdate);
if (updateFlag == DeferRecalcStyle) {
scheduleForcedStyleRecalc();
return;
}
- if (didLayoutWithPendingStylesheets() && m_pendingStylesheets <= 0) {
+ if (didLayoutWithPendingStylesheets() && !m_styleSheetCollection->hasPendingSheets()) {
m_pendingSheetLayout = IgnoreLayoutWithPendingSheets;
if (renderer())
renderer()->repaint();
@@ -3429,219 +3282,6 @@ void Document::styleResolverChanged(StyleResolverUpdateFlag updateFlag)
evaluateMediaQueryList();
}
-void Document::addStyleSheetCandidateNode(Node* node, bool createdByParser)
-{
- if (!node->inDocument())
- return;
-
- // Until the <body> exists, we have no choice but to compare document positions,
- // since styles outside of the body and head continue to be shunted into the head
- // (and thus can shift to end up before dynamically added DOM content that is also
- // outside the body).
- if ((createdByParser && body()) || m_styleSheetCandidateNodes.isEmpty()) {
- m_styleSheetCandidateNodes.add(node);
- return;
- }
-
- // Determine an appropriate insertion point.
- StyleSheetCandidateListHashSet::iterator begin = m_styleSheetCandidateNodes.begin();
- StyleSheetCandidateListHashSet::iterator end = m_styleSheetCandidateNodes.end();
- StyleSheetCandidateListHashSet::iterator it = end;
- Node* followingNode = 0;
- do {
- --it;
- Node* n = *it;
- unsigned short position = n->compareDocumentPosition(node);
- if (position == DOCUMENT_POSITION_FOLLOWING) {
- m_styleSheetCandidateNodes.insertBefore(followingNode, node);
- return;
- }
- followingNode = n;
- } while (it != begin);
-
- m_styleSheetCandidateNodes.insertBefore(followingNode, node);
-}
-
-void Document::removeStyleSheetCandidateNode(Node* node)
-{
- m_styleSheetCandidateNodes.remove(node);
-}
-
-void Document::collectActiveStylesheets(Vector<RefPtr<StyleSheet> >& sheets)
-{
- if (settings() && !settings()->authorAndUserStylesEnabled())
- return;
-
- StyleSheetCandidateListHashSet::iterator begin = m_styleSheetCandidateNodes.begin();
- StyleSheetCandidateListHashSet::iterator end = m_styleSheetCandidateNodes.end();
- for (StyleSheetCandidateListHashSet::iterator it = begin; it != end; ++it) {
- Node* n = *it;
- StyleSheet* sheet = 0;
- if (n->nodeType() == PROCESSING_INSTRUCTION_NODE) {
- // Processing instruction (XML documents only).
- // We don't support linking to embedded CSS stylesheets, see <https://bugs.webkit.org/show_bug.cgi?id=49281> for discussion.
- ProcessingInstruction* pi = static_cast<ProcessingInstruction*>(n);
- sheet = pi->sheet();
-#if ENABLE(XSLT)
- // Don't apply XSL transforms to already transformed documents -- <rdar://problem/4132806>
- if (pi->isXSL() && !transformSourceDocument()) {
- // Don't apply XSL transforms until loading is finished.
- if (!parsing())
- applyXSLTransform(pi);
- return;
- }
-#endif
- } else if ((n->isHTMLElement() && (n->hasTagName(linkTag) || n->hasTagName(styleTag)))
-#if ENABLE(SVG)
- || (n->isSVGElement() && n->hasTagName(SVGNames::styleTag))
-#endif
- ) {
- Element* e = static_cast<Element*>(n);
- AtomicString title = e->getAttribute(titleAttr);
- bool enabledViaScript = false;
- if (e->hasLocalName(linkTag)) {
- // <LINK> element
- HTMLLinkElement* linkElement = static_cast<HTMLLinkElement*>(n);
- if (linkElement->isDisabled())
- continue;
- enabledViaScript = linkElement->isEnabledViaScript();
- if (linkElement->styleSheetIsLoading()) {
- // it is loading but we should still decide which style sheet set to use
- if (!enabledViaScript && !title.isEmpty() && m_preferredStylesheetSet.isEmpty()) {
- const AtomicString& rel = e->getAttribute(relAttr);
- if (!rel.contains("alternate")) {
- m_preferredStylesheetSet = title;
- m_selectedStylesheetSet = title;
- }
- }
- continue;
- }
- if (!linkElement->sheet())
- title = nullAtom;
- }
- // Get the current preferred styleset. This is the
- // set of sheets that will be enabled.
-#if ENABLE(SVG)
- if (n->isSVGElement() && n->hasTagName(SVGNames::styleTag))
- sheet = static_cast<SVGStyleElement*>(n)->sheet();
- else
-#endif
- if (e->hasLocalName(linkTag))
- sheet = static_cast<HTMLLinkElement*>(n)->sheet();
- else
- // <STYLE> element
- sheet = static_cast<HTMLStyleElement*>(n)->sheet();
- // Check to see if this sheet belongs to a styleset
- // (thus making it PREFERRED or ALTERNATE rather than
- // PERSISTENT).
- AtomicString rel = e->getAttribute(relAttr);
- if (!enabledViaScript && !title.isEmpty()) {
- // Yes, we have a title.
- if (m_preferredStylesheetSet.isEmpty()) {
- // No preferred set has been established. If
- // we are NOT an alternate sheet, then establish
- // us as the preferred set. Otherwise, just ignore
- // this sheet.
- if (e->hasLocalName(styleTag) || !rel.contains("alternate"))
- m_preferredStylesheetSet = m_selectedStylesheetSet = title;
- }
- if (title != m_preferredStylesheetSet)
- sheet = 0;
- }
-
- if (rel.contains("alternate") && title.isEmpty())
- sheet = 0;
- }
- if (sheet)
- sheets.append(sheet);
- }
-}
-
-bool Document::testAddedStylesheetRequiresStyleRecalc(StyleSheetContents* stylesheet)
-{
- // See if all rules on the sheet are scoped to some specific ids or classes.
- // Then test if we actually have any of those in the tree at the moment.
- HashSet<AtomicStringImpl*> idScopes;
- HashSet<AtomicStringImpl*> classScopes;
- if (!StyleResolver::determineStylesheetSelectorScopes(stylesheet, idScopes, classScopes))
- return true;
- // Invalidate the subtrees that match the scopes.
- Node* node = firstChild();
- while (node) {
- if (!node->isStyledElement()) {
- node = node->traverseNextNode();
- continue;
- }
- StyledElement* element = static_cast<StyledElement*>(node);
- if (SelectorChecker::elementMatchesSelectorScopes(element, idScopes, classScopes)) {
- element->setNeedsStyleRecalc();
- // The whole subtree is now invalidated, we can skip to the next sibling.
- node = node->traverseNextSibling();
- continue;
- }
- node = node->traverseNextNode();
- }
- return false;
-}
-
-void Document::analyzeStylesheetChange(StyleResolverUpdateFlag updateFlag, const Vector<RefPtr<StyleSheet> >& newStylesheets, bool& requiresStyleResolverReset, bool& requiresFullStyleRecalc)
-{
- requiresStyleResolverReset = true;
- requiresFullStyleRecalc = true;
-
- // Stylesheets of <style> elements that @import stylesheets are active but loading. We need to trigger a full recalc when such loads are done.
- bool hasActiveLoadingStylesheet = false;
- unsigned newStylesheetCount = newStylesheets.size();
- for (unsigned i = 0; i < newStylesheetCount; ++i) {
- if (newStylesheets[i]->isLoading())
- hasActiveLoadingStylesheet = true;
- }
- if (m_hadActiveLoadingStylesheet && !hasActiveLoadingStylesheet) {
- m_hadActiveLoadingStylesheet = false;
- return;
- }
- m_hadActiveLoadingStylesheet = hasActiveLoadingStylesheet;
-
- if (updateFlag != RecalcStyleIfNeeded)
- return;
- if (!m_styleResolver)
- return;
-
- // See if we are just adding stylesheets.
- unsigned oldStylesheetCount = m_styleSheets->length();
- if (newStylesheetCount < oldStylesheetCount)
- return;
- for (unsigned i = 0; i < oldStylesheetCount; ++i) {
- if (m_styleSheets->item(i) != newStylesheets[i])
- return;
- }
- requiresStyleResolverReset = false;
-
- // If we are already parsing the body and so may have significant amount of elements, put some effort into trying to avoid style recalcs.
- if (!body() || m_hasNodesWithPlaceholderStyle)
- return;
- for (unsigned i = oldStylesheetCount; i < newStylesheetCount; ++i) {
- if (!newStylesheets[i]->isCSSStyleSheet())
- return;
- if (newStylesheets[i]->disabled())
- continue;
- if (testAddedStylesheetRequiresStyleRecalc(static_cast<CSSStyleSheet*>(newStylesheets[i].get())->contents()))
- return;
- }
- requiresFullStyleRecalc = false;
-}
-
-static bool styleSheetsUseRemUnits(const Vector<RefPtr<StyleSheet> >& sheets)
-{
- for (unsigned i = 0; i < sheets.size(); ++i) {
- if (!sheets[i]->isCSSStyleSheet())
- continue;
- if (static_cast<CSSStyleSheet*>(sheets[i].get())->contents()->usesRemUnits())
- return true;
- }
- return false;
-}
-
void Document::notifySeamlessChildDocumentsOfStylesheetUpdate() const
{
// If we're not in a frame yet any potential child documents won't have a StyleResolver to update.
@@ -3658,43 +3298,6 @@ void Document::notifySeamlessChildDocumentsOfStylesheetUpdate() const
}
}
-bool Document::updateActiveStylesheets(StyleResolverUpdateFlag updateFlag)
-{
- if (m_inStyleRecalc) {
- // SVG <use> element may manage to invalidate style selector in the middle of a style recalc.
- // https://bugs.webkit.org/show_bug.cgi?id=54344
- // FIXME: This should be fixed in SVG and this code replaced with ASSERT(!m_inStyleRecalc).
- m_hasDirtyStyleResolver = true;
- scheduleForcedStyleRecalc();
- return false;
- }
- if (!renderer() || !attached())
- return false;
-
- StyleSheetVector newStylesheets;
- collectActiveStylesheets(newStylesheets);
-
- bool requiresStyleResolverReset;
- bool requiresFullStyleRecalc;
- analyzeStylesheetChange(updateFlag, newStylesheets, requiresStyleResolverReset, requiresFullStyleRecalc);
-
- if (requiresStyleResolverReset)
- clearStyleResolver();
- else {
- m_styleResolver->appendAuthorStylesheets(m_styleSheets->length(), newStylesheets);
- resetCSSFeatureFlags();
- }
- m_styleSheets->swap(newStylesheets);
-
- m_usesRemUnits = styleSheetsUseRemUnits(m_styleSheets->vector());
- m_didCalculateStyleResolver = true;
- m_hasDirtyStyleResolver = false;
-
- notifySeamlessChildDocumentsOfStylesheetUpdate();
-
- return requiresFullStyleRecalc;
-}
-
void Document::setHoverNode(PassRefPtr<Node> newHoverNode)
{
m_hoverNode = newHoverNode;
@@ -3714,12 +3317,16 @@ void Document::removeFocusedNodeOfSubtree(Node* node, bool amongChildrenOnly)
{
if (!m_focusedNode || this->inPageCache()) // If the document is in the page cache, then we don't need to clear out the focused node.
return;
-
+
+ Node* focusedNode = node->treeScope()->focusedNode();
+ if (!focusedNode)
+ return;
+
bool nodeInSubtree = false;
if (amongChildrenOnly)
- nodeInSubtree = m_focusedNode->isDescendantOf(node);
+ nodeInSubtree = focusedNode->isDescendantOf(node);
else
- nodeInSubtree = (m_focusedNode == node) || m_focusedNode->isDescendantOf(node);
+ nodeInSubtree = (focusedNode == node) || focusedNode->isDescendantOf(node);
if (nodeInSubtree)
document()->focusedNodeRemoved();
@@ -6262,7 +5869,7 @@ void Document::reportMemoryUsage(MemoryObjectInfo* memoryObjectInfo) const
MemoryClassInfo info(memoryObjectInfo, this, WebCoreMemoryTypes::DOM);
info.addMember(m_styleResolver);
ContainerNode::reportMemoryUsage(memoryObjectInfo);
- info.addVector(m_customFonts);
+ info.addMember(m_customFonts);
info.addMember(m_url);
info.addMember(m_baseURL);
info.addMember(m_baseURLOverride);
@@ -6274,16 +5881,9 @@ void Document::reportMemoryUsage(MemoryObjectInfo* memoryObjectInfo) const
info.addMember(m_frame);
info.addMember(m_cachedResourceLoader);
info.addMember(m_elemSheet);
- info.addMember(m_pageUserSheet);
- if (m_pageGroupUserSheets)
- info.addInstrumentedVectorPtr(m_pageGroupUserSheets);
- if (m_userSheets)
- info.addInstrumentedVectorPtr(m_userSheets);
+ info.addMember(m_styleSheetCollection);
info.addHashSet(m_nodeIterators);
info.addHashSet(m_ranges);
- info.addListHashSet(m_styleSheetCandidateNodes);
- info.addMember(m_preferredStylesheetSet);
- info.addMember(m_selectedStylesheetSet);
info.addMember(m_title.string());
info.addMember(m_rawTitle.string());
info.addMember(m_xmlEncoding);
@@ -6292,17 +5892,17 @@ void Document::reportMemoryUsage(MemoryObjectInfo* memoryObjectInfo) const
info.addHashMap(m_documentNamedItemCollections);
info.addHashMap(m_windowNamedItemCollections);
#if ENABLE(DASHBOARD_SUPPORT)
- info.addVector(m_dashboardRegions);
+ info.addMember(m_dashboardRegions);
#endif
info.addHashMap(m_cssCanvasElements);
- info.addVector(m_iconURLs);
+ info.addMember(m_iconURLs);
info.addHashSet(m_documentSuspensionCallbackElements);
info.addHashSet(m_mediaVolumeCallbackElements);
info.addHashSet(m_privateBrowsingStateChangedElements);
info.addHashMap(m_elementsByAccessKey);
info.addMember(m_eventQueue);
info.addHashSet(m_mediaCanStartListeners);
- info.addVector(m_pendingTasks);
+ info.addMember(m_pendingTasks);
}
#if ENABLE(UNDO_MANAGER)
@@ -6378,6 +5978,11 @@ PassRefPtr<ElementAttributeData> Document::cachedImmutableAttributeData(const El
return attributeData.release();
}
+bool Document::haveStylesheetsLoaded() const
+{
+ return !m_styleSheetCollection->hasPendingSheets() || m_ignorePendingStylesheets;
+}
+
Localizer& Document::getLocalizer(const AtomicString& locale)
{
AtomicString localeKey = locale;
diff --git a/Source/WebCore/dom/Document.h b/Source/WebCore/dom/Document.h
index d8119c30b..f6d700ac0 100644
--- a/Source/WebCore/dom/Document.h
+++ b/Source/WebCore/dom/Document.h
@@ -78,6 +78,7 @@ class DocumentFragment;
class DocumentLoader;
class DocumentMarkerController;
class DocumentParser;
+class DocumentStyleSheetCollection;
class DocumentType;
class DocumentWeakReference;
class DynamicNodeListCacheBase;
@@ -485,34 +486,14 @@ public:
return m_styleResolver.get();
}
- /**
- * Updates the pending sheet count and then calls updateActiveStylesheets.
- */
- enum RemovePendingSheetNotificationType {
- RemovePendingSheetNotifyImmediately,
- RemovePendingSheetNotifyLater
- };
-
- void removePendingSheet(RemovePendingSheetNotificationType = RemovePendingSheetNotifyImmediately);
void notifyRemovePendingSheetIfNeeded();
- /**
- * This method returns true if all top-level stylesheets have loaded (including
- * any @imports that they may be loading).
- */
- bool haveStylesheetsLoaded() const
- {
- return m_pendingStylesheets <= 0 || m_ignorePendingStylesheets;
- }
+ bool haveStylesheetsLoaded() const;
- /**
- * Increments the number of pending sheets. The <link> elements
- * invoke this to add themselves to the loading list.
- */
- void addPendingSheet() { m_pendingStylesheets++; }
+ // This is a DOM function.
+ StyleSheetList* styleSheets();
- void addStyleSheetCandidateNode(Node*, bool createdByParser);
- void removeStyleSheetCandidateNode(Node*);
+ DocumentStyleSheetCollection* styleSheetCollection() { return m_styleSheetCollection.get(); }
bool gotoAnchorNeededAfterStylesheetsLoad() { return m_gotoAnchorNeededAfterStylesheetsLoad; }
void setGotoAnchorNeededAfterStylesheetsLoad(bool b) { m_gotoAnchorNeededAfterStylesheetsLoad = b; }
@@ -530,17 +511,6 @@ public:
void evaluateMediaQueryList();
- bool usesSiblingRules() const { return m_usesSiblingRules || m_usesSiblingRulesOverride; }
- void setUsesSiblingRules(bool b) { m_usesSiblingRulesOverride = b; }
- bool usesFirstLineRules() const { return m_usesFirstLineRules; }
- bool usesFirstLetterRules() const { return m_usesFirstLetterRules; }
- void setUsesFirstLetterRules(bool b) { m_usesFirstLetterRules = b; }
- bool usesBeforeAfterRules() const { return m_usesBeforeAfterRules || m_usesBeforeAfterRulesOverride; }
- void setUsesBeforeAfterRules(bool b) { m_usesBeforeAfterRulesOverride = b; }
- bool usesRemUnits() const { return m_usesRemUnits; }
- bool usesLinkRules() const { return linkColor() != visitedLinkColor() || m_usesLinkRules; }
- void setUsesLinkRules(bool b) { m_usesLinkRules = b; }
-
// Never returns 0.
FormController* formController();
Vector<String> formElementsState() const;
@@ -556,7 +526,7 @@ public:
PassRefPtr<NodeIterator> createNodeIterator(Node* root, unsigned whatToShow,
PassRefPtr<NodeFilter>, bool expandEntityReferences, ExceptionCode&);
- PassRefPtr<TreeWalker> createTreeWalker(Node* root, unsigned whatToShow,
+ PassRefPtr<TreeWalker> createTreeWalker(Node* root, unsigned whatToShow,
PassRefPtr<NodeFilter>, bool expandEntityReferences, ExceptionCode&);
// Special support for editing
@@ -649,17 +619,6 @@ public:
bool canNavigate(Frame* targetFrame);
Frame* findUnsafeParentScrollPropagationBoundary();
- CSSStyleSheet* pageUserSheet();
- void clearPageUserSheet();
- void updatePageUserSheet();
-
- const Vector<RefPtr<CSSStyleSheet> >* pageGroupUserSheets() const;
- void clearPageGroupUserSheets();
- void updatePageGroupUserSheets();
-
- const Vector<RefPtr<CSSStyleSheet> >* documentUserSheets() const { return m_userSheets.get(); }
- void addUserSheet(PassRefPtr<StyleSheetContents> userSheet);
-
CSSStyleSheet* elementSheet();
virtual PassRefPtr<DocumentParser> createParser();
@@ -716,8 +675,6 @@ public:
MouseEventWithHitTestResults prepareMouseEvent(const HitTestRequest&, const LayoutPoint&, const PlatformMouseEvent&);
- StyleSheetList* styleSheets();
-
/* Newly proposed CSS3 mechanism for selecting alternate
stylesheets using the DOM. May be subject to change as
spec matures. - dwh
@@ -974,7 +931,8 @@ public:
enum PendingSheetLayout { NoLayoutWithPendingSheets, DidLayoutWithPendingSheets, IgnoreLayoutWithPendingSheets };
bool didLayoutWithPendingStylesheets() const { return m_pendingSheetLayout == DidLayoutWithPendingSheets; }
-
+
+ bool hasNodesWithPlaceholderStyle() const { return m_hasNodesWithPlaceholderStyle; }
void setHasNodesWithPlaceholderStyle() { m_hasNodesWithPlaceholderStyle = true; }
const Vector<IconURL>& iconURLs();
@@ -1194,6 +1152,13 @@ public:
PassRefPtr<ElementAttributeData> cachedImmutableAttributeData(const Element*, const Vector<Attribute>&);
+ void didRemoveAllPendingStylesheet();
+ void setNeedsNotifyRemoveAllPendingStylesheet() { m_needsNotifyRemoveAllPendingStylesheet = true; }
+ void clearStyleResolver();
+ void notifySeamlessChildDocumentsOfStylesheetUpdate() const;
+
+ bool inStyleRecalc() { return m_inStyleRecalc; }
+
Localizer& getLocalizer(const AtomicString& locale);
protected:
@@ -1241,19 +1206,8 @@ private:
void buildAccessKeyMap(TreeScope* root);
void createStyleResolver();
- void clearStyleResolver();
- void combineCSSFeatureFlags();
- void resetCSSFeatureFlags();
-
- bool updateActiveStylesheets(StyleResolverUpdateFlag);
- void collectActiveStylesheets(Vector<RefPtr<StyleSheet> >&);
- bool testAddedStylesheetRequiresStyleRecalc(StyleSheetContents*);
- void analyzeStylesheetChange(StyleResolverUpdateFlag, const Vector<RefPtr<StyleSheet> >& newStylesheets, bool& requiresStyleResolverReset, bool& requiresFullStyleRecalc);
- void didRemoveAllPendingStylesheet();
- void setNeedsNotifyRemoveAllPendingStylesheet() { m_needsNotifyRemoveAllPendingStylesheet = true; }
void seamlessParentUpdatedStylesheets();
- void notifySeamlessChildDocumentsOfStylesheetUpdate() const;
void deleteCustomFonts();
@@ -1290,6 +1244,17 @@ private:
OwnPtr<StyleResolver> m_styleResolver;
bool m_didCalculateStyleResolver;
bool m_hasDirtyStyleResolver;
+ bool m_hasNodesWithPlaceholderStyle;
+ bool m_needsNotifyRemoveAllPendingStylesheet;
+ // But sometimes you need to ignore pending stylesheet count to
+ // force an immediate layout when requested by JS.
+ bool m_ignorePendingStylesheets;
+
+ // If we do ignore the pending stylesheet count, then we need to add a boolean
+ // to track that this happened so that we can do a full repaint when the stylesheets
+ // do eventually load.
+ PendingSheetLayout m_pendingSheetLayout;
+
Vector<OwnPtr<FontData> > m_customFonts;
Frame* m_frame;
@@ -1323,29 +1288,7 @@ private:
RefPtr<DocumentType> m_docType;
OwnPtr<DOMImplementation> m_implementation;
- // Track the number of currently loading top-level stylesheets needed for rendering.
- // Sheets loaded using the @import directive are not included in this count.
- // We use this count of pending sheets to detect when we can begin attaching
- // elements and when it is safe to execute scripts.
- int m_pendingStylesheets;
-
- // But sometimes you need to ignore pending stylesheet count to
- // force an immediate layout when requested by JS.
- bool m_ignorePendingStylesheets : 1;
- bool m_needsNotifyRemoveAllPendingStylesheet : 1;
-
- // If we do ignore the pending stylesheet count, then we need to add a boolean
- // to track that this happened so that we can do a full repaint when the stylesheets
- // do eventually load.
- PendingSheetLayout m_pendingSheetLayout;
-
- bool m_hasNodesWithPlaceholderStyle;
-
RefPtr<CSSStyleSheet> m_elemSheet;
- RefPtr<CSSStyleSheet> m_pageUserSheet;
- mutable OwnPtr<Vector<RefPtr<CSSStyleSheet> > > m_pageGroupUserSheets;
- OwnPtr<Vector<RefPtr<CSSStyleSheet> > > m_userSheets;
- mutable bool m_pageGroupUserSheetCacheValid;
bool m_printing;
bool m_paginatedForScreen;
@@ -1374,11 +1317,9 @@ private:
MutationObserverOptions m_mutationObserverTypes;
#endif
- RefPtr<StyleSheetList> m_styleSheets; // All of the stylesheets that are currently in effect for our media type and stylesheet set.
- bool m_hadActiveLoadingStylesheet;
-
- typedef ListHashSet<Node*, 32> StyleSheetCandidateListHashSet;
- StyleSheetCandidateListHashSet m_styleSheetCandidateNodes; // All of the nodes that could potentially provide stylesheets to the document (<link>, <style>, <?xml-stylesheet>)
+
+ OwnPtr<DocumentStyleSheetCollection> m_styleSheetCollection;
+ RefPtr<StyleSheetList> m_styleSheetList;
OwnPtr<FormController> m_formController;
@@ -1386,9 +1327,6 @@ private:
Color m_visitedLinkColor;
Color m_activeLinkColor;
- String m_preferredStylesheetSet;
- String m_selectedStylesheetSet;
-
bool m_loadingSheet;
bool m_visuallyOrdered;
ReadyState m_readyState;
@@ -1399,14 +1337,6 @@ private:
bool m_inStyleRecalc;
bool m_closeAfterStyleRecalc;
- bool m_usesSiblingRules;
- bool m_usesSiblingRulesOverride;
- bool m_usesFirstLineRules;
- bool m_usesFirstLetterRules;
- bool m_usesBeforeAfterRules;
- bool m_usesBeforeAfterRulesOverride;
- bool m_usesRemUnits;
- bool m_usesLinkRules;
bool m_gotoAnchorNeededAfterStylesheetsLoad;
bool m_isDNSPrefetchEnabled;
bool m_haveExplicitlyDisabledDNSPrefetch;
diff --git a/Source/WebCore/dom/DocumentStyleSheetCollection.cpp b/Source/WebCore/dom/DocumentStyleSheetCollection.cpp
new file mode 100644
index 000000000..70f542713
--- /dev/null
+++ b/Source/WebCore/dom/DocumentStyleSheetCollection.cpp
@@ -0,0 +1,484 @@
+/*
+ * Copyright (C) 1999 Lars Knoll (knoll@kde.org)
+ * (C) 1999 Antti Koivisto (koivisto@kde.org)
+ * (C) 2001 Dirk Mueller (mueller@kde.org)
+ * (C) 2006 Alexey Proskuryakov (ap@webkit.org)
+ * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2011, 2012 Apple Inc. All rights reserved.
+ * Copyright (C) 2008, 2009 Torch Mobile Inc. All rights reserved. (http://www.torchmobile.com/)
+ * Copyright (C) 2008, 2009, 2011, 2012 Google Inc. All rights reserved.
+ * Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies)
+ * Copyright (C) Research In Motion Limited 2010-2011. All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#include "config.h"
+#include "DocumentStyleSheetCollection.h"
+
+#include "CSSStyleSheet.h"
+#include "Document.h"
+#include "Element.h"
+#include "HTMLLinkElement.h"
+#include "HTMLNames.h"
+#include "HTMLStyleElement.h"
+#include "Page.h"
+#include "PageGroup.h"
+#include "ProcessingInstruction.h"
+#include "SVGNames.h"
+#include "SVGStyleElement.h"
+#include "SelectorChecker.h"
+#include "Settings.h"
+#include "StyleResolver.h"
+#include "StyleSheetContents.h"
+#include "StyleSheetList.h"
+#include "UserContentURLPattern.h"
+#include "WebCoreMemoryInstrumentation.h"
+#include <wtf/MemoryInstrumentationVector.h>
+
+namespace WebCore {
+
+using namespace HTMLNames;
+
+DocumentStyleSheetCollection::DocumentStyleSheetCollection(Document* document)
+ : m_document(document)
+ , m_pendingStylesheets(0)
+ , m_pageGroupUserSheetCacheValid(false)
+ , m_hadActiveLoadingStylesheet(false)
+ , m_needsUpdateActiveStylesheetsOnStyleRecalc(false)
+ , m_usesSiblingRules(false)
+ , m_usesSiblingRulesOverride(false)
+ , m_usesFirstLineRules(false)
+ , m_usesFirstLetterRules(false)
+ , m_usesBeforeAfterRules(false)
+ , m_usesBeforeAfterRulesOverride(false)
+ , m_usesRemUnits(false)
+{
+}
+
+DocumentStyleSheetCollection::~DocumentStyleSheetCollection()
+{
+ if (m_pageUserSheet)
+ m_pageUserSheet->clearOwnerNode();
+ if (m_pageGroupUserSheets) {
+ for (size_t i = 0; i < m_pageGroupUserSheets->size(); ++i)
+ (*m_pageGroupUserSheets)[i]->clearOwnerNode();
+ }
+ if (m_userSheets) {
+ for (size_t i = 0; i < m_userSheets->size(); ++i)
+ (*m_userSheets)[i]->clearOwnerNode();
+ }
+}
+
+void DocumentStyleSheetCollection::combineCSSFeatureFlags()
+{
+ // Delay resetting the flags until after next style recalc since unapplying the style may not work without these set (this is true at least with before/after).
+ StyleResolver* styleResolver = m_document->styleResolver();
+ m_usesSiblingRules = m_usesSiblingRules || styleResolver->usesSiblingRules();
+ m_usesFirstLineRules = m_usesFirstLineRules || styleResolver->usesFirstLineRules();
+ m_usesBeforeAfterRules = m_usesBeforeAfterRules || styleResolver->usesBeforeAfterRules();
+}
+
+void DocumentStyleSheetCollection::resetCSSFeatureFlags()
+{
+ StyleResolver* styleResolver = m_document->styleResolver();
+ m_usesSiblingRules = styleResolver->usesSiblingRules();
+ m_usesFirstLineRules = styleResolver->usesFirstLineRules();
+ m_usesBeforeAfterRules = styleResolver->usesBeforeAfterRules();
+}
+
+CSSStyleSheet* DocumentStyleSheetCollection::pageUserSheet()
+{
+ if (m_pageUserSheet)
+ return m_pageUserSheet.get();
+
+ Page* owningPage = m_document->page();
+ if (!owningPage)
+ return 0;
+
+ String userSheetText = owningPage->userStyleSheet();
+ if (userSheetText.isEmpty())
+ return 0;
+
+ // Parse the sheet and cache it.
+ m_pageUserSheet = CSSStyleSheet::createInline(m_document, m_document->settings()->userStyleSheetLocation());
+ m_pageUserSheet->contents()->setIsUserStyleSheet(true);
+ m_pageUserSheet->contents()->parseString(userSheetText);
+ return m_pageUserSheet.get();
+}
+
+void DocumentStyleSheetCollection::clearPageUserSheet()
+{
+ if (m_pageUserSheet) {
+ m_pageUserSheet = 0;
+ m_document->styleResolverChanged(DeferRecalcStyle);
+ }
+}
+
+void DocumentStyleSheetCollection::updatePageUserSheet()
+{
+ clearPageUserSheet();
+ if (pageUserSheet())
+ m_document->styleResolverChanged(RecalcStyleImmediately);
+}
+
+const Vector<RefPtr<CSSStyleSheet> >* DocumentStyleSheetCollection::pageGroupUserSheets() const
+{
+ if (m_pageGroupUserSheetCacheValid)
+ return m_pageGroupUserSheets.get();
+
+ m_pageGroupUserSheetCacheValid = true;
+
+ Page* owningPage = m_document->page();
+ if (!owningPage)
+ return 0;
+
+ const PageGroup& pageGroup = owningPage->group();
+ const UserStyleSheetMap* sheetsMap = pageGroup.userStyleSheets();
+ if (!sheetsMap)
+ return 0;
+
+ UserStyleSheetMap::const_iterator end = sheetsMap->end();
+ for (UserStyleSheetMap::const_iterator it = sheetsMap->begin(); it != end; ++it) {
+ const UserStyleSheetVector* sheets = it->second.get();
+ for (unsigned i = 0; i < sheets->size(); ++i) {
+ const UserStyleSheet* sheet = sheets->at(i).get();
+ if (sheet->injectedFrames() == InjectInTopFrameOnly && m_document->ownerElement())
+ continue;
+ if (!UserContentURLPattern::matchesPatterns(m_document->url(), sheet->whitelist(), sheet->blacklist()))
+ continue;
+ RefPtr<CSSStyleSheet> groupSheet = CSSStyleSheet::createInline(const_cast<Document*>(m_document), sheet->url());
+ if (!m_pageGroupUserSheets)
+ m_pageGroupUserSheets = adoptPtr(new Vector<RefPtr<CSSStyleSheet> >);
+ m_pageGroupUserSheets->append(groupSheet);
+ groupSheet->contents()->setIsUserStyleSheet(sheet->level() == UserStyleUserLevel);
+ groupSheet->contents()->parseString(sheet->source());
+ }
+ }
+
+ return m_pageGroupUserSheets.get();
+}
+
+void DocumentStyleSheetCollection::clearPageGroupUserSheets()
+{
+ m_pageGroupUserSheetCacheValid = false;
+ if (m_pageGroupUserSheets && m_pageGroupUserSheets->size()) {
+ m_pageGroupUserSheets->clear();
+ m_document->styleResolverChanged(DeferRecalcStyle);
+ }
+}
+
+void DocumentStyleSheetCollection::updatePageGroupUserSheets()
+{
+ clearPageGroupUserSheets();
+ if (pageGroupUserSheets() && pageGroupUserSheets()->size())
+ m_document->styleResolverChanged(RecalcStyleImmediately);
+}
+
+void DocumentStyleSheetCollection::addUserSheet(PassRefPtr<StyleSheetContents> userSheet)
+{
+ if (!m_userSheets)
+ m_userSheets = adoptPtr(new Vector<RefPtr<CSSStyleSheet> >);
+ m_userSheets->append(CSSStyleSheet::create(userSheet, m_document));
+ m_document->styleResolverChanged(RecalcStyleImmediately);
+}
+
+// This method is called whenever a top-level stylesheet has finished loading.
+void DocumentStyleSheetCollection::removePendingSheet(RemovePendingSheetNotificationType notification)
+{
+ // Make sure we knew this sheet was pending, and that our count isn't out of sync.
+ ASSERT(m_pendingStylesheets > 0);
+
+ m_pendingStylesheets--;
+
+#ifdef INSTRUMENT_LAYOUT_SCHEDULING
+ if (!ownerElement())
+ printf("Stylesheet loaded at time %d. %d stylesheets still remain.\n", elapsedTime(), m_pendingStylesheets);
+#endif
+
+ if (m_pendingStylesheets)
+ return;
+
+ if (notification == RemovePendingSheetNotifyLater) {
+ m_document->setNeedsNotifyRemoveAllPendingStylesheet();
+ return;
+ }
+
+ m_document->didRemoveAllPendingStylesheet();
+}
+
+void DocumentStyleSheetCollection::addStyleSheetCandidateNode(Node* node, bool createdByParser)
+{
+ if (!node->inDocument())
+ return;
+
+ // Until the <body> exists, we have no choice but to compare document positions,
+ // since styles outside of the body and head continue to be shunted into the head
+ // (and thus can shift to end up before dynamically added DOM content that is also
+ // outside the body).
+ if ((createdByParser && m_document->body()) || m_styleSheetCandidateNodes.isEmpty()) {
+ m_styleSheetCandidateNodes.add(node);
+ return;
+ }
+
+ // Determine an appropriate insertion point.
+ StyleSheetCandidateListHashSet::iterator begin = m_styleSheetCandidateNodes.begin();
+ StyleSheetCandidateListHashSet::iterator end = m_styleSheetCandidateNodes.end();
+ StyleSheetCandidateListHashSet::iterator it = end;
+ Node* followingNode = 0;
+ do {
+ --it;
+ Node* n = *it;
+ unsigned short position = n->compareDocumentPosition(node);
+ if (position == Node::DOCUMENT_POSITION_FOLLOWING) {
+ m_styleSheetCandidateNodes.insertBefore(followingNode, node);
+ return;
+ }
+ followingNode = n;
+ } while (it != begin);
+
+ m_styleSheetCandidateNodes.insertBefore(followingNode, node);
+}
+
+void DocumentStyleSheetCollection::removeStyleSheetCandidateNode(Node* node)
+{
+ m_styleSheetCandidateNodes.remove(node);
+}
+
+void DocumentStyleSheetCollection::collectActiveStyleSheets(Vector<RefPtr<StyleSheet> >& sheets)
+{
+ if (m_document->settings() && !m_document->settings()->authorAndUserStylesEnabled())
+ return;
+
+ StyleSheetCandidateListHashSet::iterator begin = m_styleSheetCandidateNodes.begin();
+ StyleSheetCandidateListHashSet::iterator end = m_styleSheetCandidateNodes.end();
+ for (StyleSheetCandidateListHashSet::iterator it = begin; it != end; ++it) {
+ Node* n = *it;
+ StyleSheet* sheet = 0;
+ if (n->nodeType() == Node::PROCESSING_INSTRUCTION_NODE) {
+ // Processing instruction (XML documents only).
+ // We don't support linking to embedded CSS stylesheets, see <https://bugs.webkit.org/show_bug.cgi?id=49281> for discussion.
+ ProcessingInstruction* pi = static_cast<ProcessingInstruction*>(n);
+ sheet = pi->sheet();
+#if ENABLE(XSLT)
+ // Don't apply XSL transforms to already transformed documents -- <rdar://problem/4132806>
+ if (pi->isXSL() && !m_document->transformSourceDocument()) {
+ // Don't apply XSL transforms until loading is finished.
+ if (!m_document->parsing())
+ m_document->applyXSLTransform(pi);
+ return;
+ }
+#endif
+ } else if ((n->isHTMLElement() && (n->hasTagName(linkTag) || n->hasTagName(styleTag)))
+#if ENABLE(SVG)
+ || (n->isSVGElement() && n->hasTagName(SVGNames::styleTag))
+#endif
+ ) {
+ Element* e = static_cast<Element*>(n);
+ AtomicString title = e->getAttribute(titleAttr);
+ bool enabledViaScript = false;
+ if (e->hasLocalName(linkTag)) {
+ // <LINK> element
+ HTMLLinkElement* linkElement = static_cast<HTMLLinkElement*>(n);
+ if (linkElement->isDisabled())
+ continue;
+ enabledViaScript = linkElement->isEnabledViaScript();
+ if (linkElement->styleSheetIsLoading()) {
+ // it is loading but we should still decide which style sheet set to use
+ if (!enabledViaScript && !title.isEmpty() && m_preferredStylesheetSetName.isEmpty()) {
+ const AtomicString& rel = e->getAttribute(relAttr);
+ if (!rel.contains("alternate")) {
+ m_preferredStylesheetSetName = title;
+ m_selectedStylesheetSetName = title;
+ }
+ }
+ continue;
+ }
+ if (!linkElement->sheet())
+ title = nullAtom;
+ }
+ // Get the current preferred styleset. This is the
+ // set of sheets that will be enabled.
+#if ENABLE(SVG)
+ if (n->isSVGElement() && n->hasTagName(SVGNames::styleTag))
+ sheet = static_cast<SVGStyleElement*>(n)->sheet();
+ else
+#endif
+ if (e->hasLocalName(linkTag))
+ sheet = static_cast<HTMLLinkElement*>(n)->sheet();
+ else
+ // <STYLE> element
+ sheet = static_cast<HTMLStyleElement*>(n)->sheet();
+ // Check to see if this sheet belongs to a styleset
+ // (thus making it PREFERRED or ALTERNATE rather than
+ // PERSISTENT).
+ AtomicString rel = e->getAttribute(relAttr);
+ if (!enabledViaScript && !title.isEmpty()) {
+ // Yes, we have a title.
+ if (m_preferredStylesheetSetName.isEmpty()) {
+ // No preferred set has been established. If
+ // we are NOT an alternate sheet, then establish
+ // us as the preferred set. Otherwise, just ignore
+ // this sheet.
+ if (e->hasLocalName(styleTag) || !rel.contains("alternate"))
+ m_preferredStylesheetSetName = m_selectedStylesheetSetName = title;
+ }
+ if (title != m_preferredStylesheetSetName)
+ sheet = 0;
+ }
+
+ if (rel.contains("alternate") && title.isEmpty())
+ sheet = 0;
+ }
+ if (sheet)
+ sheets.append(sheet);
+ }
+}
+
+bool DocumentStyleSheetCollection::testAddedStyleSheetRequiresStyleRecalc(StyleSheetContents* stylesheet)
+{
+ // See if all rules on the sheet are scoped to some specific ids or classes.
+ // Then test if we actually have any of those in the tree at the moment.
+ HashSet<AtomicStringImpl*> idScopes;
+ HashSet<AtomicStringImpl*> classScopes;
+ if (!StyleResolver::determineStylesheetSelectorScopes(stylesheet, idScopes, classScopes))
+ return true;
+ // Invalidate the subtrees that match the scopes.
+ Node* node = m_document->firstChild();
+ while (node) {
+ if (!node->isStyledElement()) {
+ node = node->traverseNextNode();
+ continue;
+ }
+ StyledElement* element = static_cast<StyledElement*>(node);
+ if (SelectorChecker::elementMatchesSelectorScopes(element, idScopes, classScopes)) {
+ element->setNeedsStyleRecalc();
+ // The whole subtree is now invalidated, we can skip to the next sibling.
+ node = node->traverseNextSibling();
+ continue;
+ }
+ node = node->traverseNextNode();
+ }
+ return false;
+}
+
+void DocumentStyleSheetCollection::analyzeStyleSheetChange(UpdateFlag updateFlag, const Vector<RefPtr<StyleSheet> >& newStylesheets, bool& requiresStyleResolverReset, bool& requiresFullStyleRecalc)
+{
+ requiresStyleResolverReset = true;
+ requiresFullStyleRecalc = true;
+
+ // Stylesheets of <style> elements that @import stylesheets are active but loading. We need to trigger a full recalc when such loads are done.
+ bool hasActiveLoadingStylesheet = false;
+ unsigned newStylesheetCount = newStylesheets.size();
+ for (unsigned i = 0; i < newStylesheetCount; ++i) {
+ if (newStylesheets[i]->isLoading())
+ hasActiveLoadingStylesheet = true;
+ }
+ if (m_hadActiveLoadingStylesheet && !hasActiveLoadingStylesheet) {
+ m_hadActiveLoadingStylesheet = false;
+ return;
+ }
+ m_hadActiveLoadingStylesheet = hasActiveLoadingStylesheet;
+
+ if (updateFlag != OptimizedUpdate)
+ return;
+ if (!m_document->styleResolverIfExists())
+ return;
+
+ // See if we are just adding stylesheets.
+ unsigned oldStylesheetCount = m_authorStyleSheets.size();
+ if (newStylesheetCount < oldStylesheetCount)
+ return;
+ for (unsigned i = 0; i < oldStylesheetCount; ++i) {
+ if (m_authorStyleSheets[i] != newStylesheets[i])
+ return;
+ }
+ requiresStyleResolverReset = false;
+
+ // If we are already parsing the body and so may have significant amount of elements, put some effort into trying to avoid style recalcs.
+ if (!m_document->body() || m_document->hasNodesWithPlaceholderStyle())
+ return;
+ for (unsigned i = oldStylesheetCount; i < newStylesheetCount; ++i) {
+ if (!newStylesheets[i]->isCSSStyleSheet())
+ return;
+ if (newStylesheets[i]->disabled())
+ continue;
+ if (testAddedStyleSheetRequiresStyleRecalc(static_cast<CSSStyleSheet*>(newStylesheets[i].get())->contents()))
+ return;
+ }
+ requiresFullStyleRecalc = false;
+}
+
+static bool styleSheetsUseRemUnits(const Vector<RefPtr<StyleSheet> >& sheets)
+{
+ for (unsigned i = 0; i < sheets.size(); ++i) {
+ if (!sheets[i]->isCSSStyleSheet())
+ continue;
+ if (static_cast<CSSStyleSheet*>(sheets[i].get())->contents()->usesRemUnits())
+ return true;
+ }
+ return false;
+}
+
+bool DocumentStyleSheetCollection::updateActiveStyleSheets(UpdateFlag updateFlag)
+{
+ if (m_document->inStyleRecalc()) {
+ // SVG <use> element may manage to invalidate style selector in the middle of a style recalc.
+ // https://bugs.webkit.org/show_bug.cgi?id=54344
+ // FIXME: This should be fixed in SVG and the call site replaced by ASSERT(!m_inStyleRecalc).
+ m_needsUpdateActiveStylesheetsOnStyleRecalc = true;
+ m_document->scheduleForcedStyleRecalc();
+ return false;
+
+ }
+ if (!m_document->renderer() || !m_document->attached())
+ return false;
+
+ Vector<RefPtr<StyleSheet> > newStylesheets;
+ collectActiveStyleSheets(newStylesheets);
+
+ bool requiresStyleResolverReset;
+ bool requiresFullStyleRecalc;
+ analyzeStyleSheetChange(updateFlag, newStylesheets, requiresStyleResolverReset, requiresFullStyleRecalc);
+
+ if (requiresStyleResolverReset)
+ m_document->clearStyleResolver();
+ else {
+ m_document->styleResolver()->appendAuthorStylesheets(m_authorStyleSheets.size(), newStylesheets);
+ resetCSSFeatureFlags();
+ }
+ m_authorStyleSheets.swap(newStylesheets);
+
+ m_usesRemUnits = styleSheetsUseRemUnits(m_authorStyleSheets);
+ m_needsUpdateActiveStylesheetsOnStyleRecalc = false;
+
+ m_document->notifySeamlessChildDocumentsOfStylesheetUpdate();
+
+ return requiresFullStyleRecalc;
+}
+
+void DocumentStyleSheetCollection::reportMemoryUsage(MemoryObjectInfo* memoryObjectInfo) const
+{
+ MemoryClassInfo info(memoryObjectInfo, this, WebCoreMemoryTypes::DOM);
+ info.addMember(m_pageUserSheet);
+ info.addMember(m_pageGroupUserSheets);
+ info.addMember(m_userSheets);
+ info.addMember(m_authorStyleSheets);
+ info.addListHashSet(m_styleSheetCandidateNodes);
+ info.addMember(m_preferredStylesheetSetName);
+ info.addMember(m_selectedStylesheetSetName);
+}
+
+}
diff --git a/Source/WebCore/dom/DocumentStyleSheetCollection.h b/Source/WebCore/dom/DocumentStyleSheetCollection.h
new file mode 100644
index 000000000..a8104dfd9
--- /dev/null
+++ b/Source/WebCore/dom/DocumentStyleSheetCollection.h
@@ -0,0 +1,143 @@
+/*
+ * Copyright (C) 1999 Lars Knoll (knoll@kde.org)
+ * (C) 1999 Antti Koivisto (koivisto@kde.org)
+ * (C) 2001 Dirk Mueller (mueller@kde.org)
+ * (C) 2006 Alexey Proskuryakov (ap@webkit.org)
+ * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2012 Apple Inc. All rights reserved.
+ * Copyright (C) 2008, 2009 Torch Mobile Inc. All rights reserved. (http://www.torchmobile.com/)
+ * Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies)
+ * Copyright (C) 2011 Google Inc. All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef DocumentStyleSheetCollection_h
+#define DocumentStyleSheetCollection_h
+
+#include <wtf/FastAllocBase.h>
+#include <wtf/ListHashSet.h>
+#include <wtf/RefPtr.h>
+#include <wtf/Vector.h>
+#include <wtf/text/WTFString.h>
+
+namespace WebCore {
+
+class CSSStyleSheet;
+class Document;
+class Node;
+class StyleSheet;
+class StyleSheetContents;
+class StyleSheetList;
+
+class DocumentStyleSheetCollection {
+ WTF_MAKE_FAST_ALLOCATED;
+public:
+ DocumentStyleSheetCollection(Document*);
+ ~DocumentStyleSheetCollection();
+
+ const Vector<RefPtr<StyleSheet> >& authorStyleSheets() { return m_authorStyleSheets; }
+
+ CSSStyleSheet* pageUserSheet();
+ const Vector<RefPtr<CSSStyleSheet> >* pageGroupUserSheets() const;
+ const Vector<RefPtr<CSSStyleSheet> >* documentUserSheets() const { return m_userSheets.get(); }
+
+ void addStyleSheetCandidateNode(Node*, bool createdByParser);
+ void removeStyleSheetCandidateNode(Node*);
+
+ void clearPageUserSheet();
+ void updatePageUserSheet();
+ void clearPageGroupUserSheets();
+ void updatePageGroupUserSheets();
+
+ void addUserSheet(PassRefPtr<StyleSheetContents> userSheet);
+
+ bool needsUpdateActiveStylesheetsOnStyleRecalc() { return m_needsUpdateActiveStylesheetsOnStyleRecalc; }
+
+ enum UpdateFlag { FullUpdate, OptimizedUpdate };
+ bool updateActiveStyleSheets(UpdateFlag);
+
+ String preferredStylesheetSetName() const { return m_preferredStylesheetSetName; }
+ String selectedStylesheetSetName() const { return m_selectedStylesheetSetName; }
+ void setPreferredStylesheetSetName(const String& name) { m_preferredStylesheetSetName = name; }
+ void setSelectedStylesheetSetName(const String& name) { m_selectedStylesheetSetName = name; }
+
+ void addPendingSheet() { m_pendingStylesheets++; }
+ enum RemovePendingSheetNotificationType {
+ RemovePendingSheetNotifyImmediately,
+ RemovePendingSheetNotifyLater
+ };
+ void removePendingSheet(RemovePendingSheetNotificationType = RemovePendingSheetNotifyImmediately);
+
+ bool hasPendingSheets() const { return m_pendingStylesheets > 0; }
+
+ bool usesSiblingRules() const { return m_usesSiblingRules || m_usesSiblingRulesOverride; }
+ void setUsesSiblingRulesOverride(bool b) { m_usesSiblingRulesOverride = b; }
+ bool usesFirstLineRules() const { return m_usesFirstLineRules; }
+ bool usesFirstLetterRules() const { return m_usesFirstLetterRules; }
+ void setUsesFirstLetterRules(bool b) { m_usesFirstLetterRules = b; }
+ bool usesBeforeAfterRules() const { return m_usesBeforeAfterRules || m_usesBeforeAfterRulesOverride; }
+ void setUsesBeforeAfterRulesOverride(bool b) { m_usesBeforeAfterRulesOverride = b; }
+ bool usesRemUnits() const { return m_usesRemUnits; }
+ void setUsesRemUnit(bool b) { m_usesRemUnits = b; }
+
+ void combineCSSFeatureFlags();
+ void resetCSSFeatureFlags();
+
+ void reportMemoryUsage(MemoryObjectInfo*) const;
+
+private:
+ void collectActiveStyleSheets(Vector<RefPtr<StyleSheet> >&);
+ bool testAddedStyleSheetRequiresStyleRecalc(StyleSheetContents*);
+ void analyzeStyleSheetChange(UpdateFlag, const Vector<RefPtr<StyleSheet> >& newStylesheets, bool& requiresStyleResolverReset, bool& requiresFullStyleRecalc);
+
+ Document* m_document;
+
+ Vector<RefPtr<StyleSheet> > m_authorStyleSheets;
+
+ // Track the number of currently loading top-level stylesheets needed for rendering.
+ // Sheets loaded using the @import directive are not included in this count.
+ // We use this count of pending sheets to detect when we can begin attaching
+ // elements and when it is safe to execute scripts.
+ int m_pendingStylesheets;
+
+ RefPtr<CSSStyleSheet> m_pageUserSheet;
+ mutable OwnPtr<Vector<RefPtr<CSSStyleSheet> > > m_pageGroupUserSheets;
+ OwnPtr<Vector<RefPtr<CSSStyleSheet> > > m_userSheets;
+ mutable bool m_pageGroupUserSheetCacheValid;
+
+ bool m_hadActiveLoadingStylesheet;
+ bool m_needsUpdateActiveStylesheetsOnStyleRecalc;
+
+ typedef ListHashSet<Node*, 32> StyleSheetCandidateListHashSet;
+ StyleSheetCandidateListHashSet m_styleSheetCandidateNodes;
+
+ String m_preferredStylesheetSetName;
+ String m_selectedStylesheetSetName;
+
+ bool m_usesSiblingRules;
+ bool m_usesSiblingRulesOverride;
+ bool m_usesFirstLineRules;
+ bool m_usesFirstLetterRules;
+ bool m_usesBeforeAfterRules;
+ bool m_usesBeforeAfterRulesOverride;
+ bool m_usesRemUnits;
+};
+
+}
+
+#endif
+
diff --git a/Source/WebCore/dom/DocumentType.idl b/Source/WebCore/dom/DocumentType.idl
index 729023271..4206de70d 100644
--- a/Source/WebCore/dom/DocumentType.idl
+++ b/Source/WebCore/dom/DocumentType.idl
@@ -35,6 +35,9 @@ module core {
readonly attribute [TreatReturnedNullStringAs=Null] DOMString systemId;
readonly attribute [TreatReturnedNullStringAs=Null] DOMString internalSubset;
+ // DOM 4
+ void remove()
+ raises(DOMException);
};
}
diff --git a/Source/WebCore/dom/Element.cpp b/Source/WebCore/dom/Element.cpp
index 15804a3fa..9176f8977 100644
--- a/Source/WebCore/dom/Element.cpp
+++ b/Source/WebCore/dom/Element.cpp
@@ -999,7 +999,7 @@ void Element::removedFrom(ContainerNode* insertionPoint)
void Element::attach()
{
suspendPostAttachCallbacks();
- RenderWidget::suspendWidgetHierarchyUpdates();
+ WidgetHierarchyUpdatesSuspensionScope suspendWidgetHierarchyUpdates;
createRendererIfNeeded();
StyleResolverParentPusher parentPusher(this);
@@ -1028,7 +1028,6 @@ void Element::attach()
}
}
- RenderWidget::resumeWidgetHierarchyUpdates();
resumePostAttachCallbacks();
}
@@ -1042,7 +1041,7 @@ void Element::unregisterNamedFlowContentNode()
void Element::detach()
{
- RenderWidget::suspendWidgetHierarchyUpdates();
+ WidgetHierarchyUpdatesSuspensionScope suspendWidgetHierarchyUpdates;
unregisterNamedFlowContentNode();
cancelFocusAppearanceUpdate();
if (hasRareData()) {
@@ -1055,8 +1054,6 @@ void Element::detach()
shadow->detach();
}
ContainerNode::detach();
-
- RenderWidget::resumeWidgetHierarchyUpdates();
}
bool Element::pseudoStyleCacheIsInvalid(const RenderStyle* currentStyle, RenderStyle* newStyle)
@@ -1176,7 +1173,7 @@ void Element::recalcStyle(StyleChange change)
// If "rem" units are used anywhere in the document, and if the document element's font size changes, then go ahead and force font updating
// all the way down the tree. This is simpler than having to maintain a cache of objects (and such font size changes should be rare anyway).
- if (document()->usesRemUnits() && document()->documentElement() == this && ch != NoChange && currentStyle && newStyle && currentStyle->fontSize() != newStyle->fontSize()) {
+ if (document()->styleSheetCollection()->usesRemUnits() && document()->documentElement() == this && ch != NoChange && currentStyle && newStyle && currentStyle->fontSize() != newStyle->fontSize()) {
// Cached RenderStyles may depend on the rem units.
document()->styleResolver()->invalidateMatchedPropertiesCache();
change = Force;
diff --git a/Source/WebCore/dom/Element.idl b/Source/WebCore/dom/Element.idl
index 4bd64ed4e..6b3427c3a 100644
--- a/Source/WebCore/dom/Element.idl
+++ b/Source/WebCore/dom/Element.idl
@@ -120,6 +120,10 @@ module core {
readonly attribute Element nextElementSibling;
readonly attribute unsigned long childElementCount;
+ // DOM 4
+ void remove()
+ raises(DOMException);
+
#if defined(LANGUAGE_JAVASCRIPT) && LANGUAGE_JAVASCRIPT
// CSSOM View Module API
ClientRectList getClientRects();
diff --git a/Source/WebCore/dom/ElementAttributeData.cpp b/Source/WebCore/dom/ElementAttributeData.cpp
index 03f7b81fc..5a7f34125 100644
--- a/Source/WebCore/dom/ElementAttributeData.cpp
+++ b/Source/WebCore/dom/ElementAttributeData.cpp
@@ -31,6 +31,7 @@
#include "CSSStyleSheet.h"
#include "StyledElement.h"
#include "WebCoreMemoryInstrumentation.h"
+#include <wtf/MemoryInstrumentationVector.h>
namespace WebCore {
@@ -300,7 +301,7 @@ void ElementAttributeData::reportMemoryUsage(MemoryObjectInfo* memoryObjectInfo)
info.addMember(m_classNames);
info.addMember(m_idForStyleResolution);
if (m_isMutable)
- info.addVector(mutableAttributeVector());
+ info.addMember(mutableAttributeVector());
for (unsigned i = 0, len = length(); i < len; i++)
info.addMember(*attributeItem(i));
}
diff --git a/Source/WebCore/dom/EventNames.h b/Source/WebCore/dom/EventNames.h
index b3cd846ea..136f7aac2 100644
--- a/Source/WebCore/dom/EventNames.h
+++ b/Source/WebCore/dom/EventNames.h
@@ -229,7 +229,7 @@ namespace WebCore {
macro(unmute) \
macro(icechange) \
macro(icecandidate) \
- macro(negotationneeded) \
+ macro(negotiationneeded) \
\
macro(show) \
\
diff --git a/Source/WebCore/dom/Node.cpp b/Source/WebCore/dom/Node.cpp
index aef669c50..8ab3352f6 100644
--- a/Source/WebCore/dom/Node.cpp
+++ b/Source/WebCore/dom/Node.cpp
@@ -630,8 +630,6 @@ void Node::remove(ExceptionCode& ec)
{
if (ContainerNode* parent = parentNode())
parent->removeChild(this, ec);
- else
- ec = HIERARCHY_REQUEST_ERR;
}
void Node::normalize()
diff --git a/Source/WebCore/dom/ProcessingInstruction.cpp b/Source/WebCore/dom/ProcessingInstruction.cpp
index ef13b4690..6759becbc 100644
--- a/Source/WebCore/dom/ProcessingInstruction.cpp
+++ b/Source/WebCore/dom/ProcessingInstruction.cpp
@@ -23,9 +23,10 @@
#include "CSSStyleSheet.h"
#include "CachedCSSStyleSheet.h"
+#include "CachedResourceLoader.h"
#include "CachedXSLStyleSheet.h"
#include "Document.h"
-#include "CachedResourceLoader.h"
+#include "DocumentStyleSheetCollection.h"
#include "ExceptionCode.h"
#include "Frame.h"
#include "FrameLoader.h"
@@ -65,7 +66,7 @@ ProcessingInstruction::~ProcessingInstruction()
m_cachedSheet->removeClient(this);
if (inDocument())
- document()->removeStyleSheetCandidateNode(this);
+ document()->styleSheetCollection()->removeStyleSheetCandidateNode(this);
}
void ProcessingInstruction::setData(const String& data, ExceptionCode&)
@@ -160,7 +161,7 @@ void ProcessingInstruction::checkStyleSheet()
return;
m_loading = true;
- document()->addPendingSheet();
+ document()->styleSheetCollection()->addPendingSheet();
ResourceRequest request(document()->completeURL(href));
#if ENABLE(XSLT)
@@ -180,7 +181,7 @@ void ProcessingInstruction::checkStyleSheet()
else {
// The request may have been denied if (for example) the stylesheet is local and the document is remote.
m_loading = false;
- document()->removePendingSheet();
+ document()->styleSheetCollection()->removePendingSheet();
}
}
}
@@ -198,7 +199,7 @@ bool ProcessingInstruction::isLoading() const
bool ProcessingInstruction::sheetLoaded()
{
if (!isLoading()) {
- document()->removePendingSheet();
+ document()->styleSheetCollection()->removePendingSheet();
return true;
}
return false;
@@ -293,7 +294,7 @@ Node::InsertionNotificationRequest ProcessingInstruction::insertedInto(Container
Node::insertedInto(insertionPoint);
if (!insertionPoint->inDocument())
return InsertionDone;
- document()->addStyleSheetCandidateNode(this, m_createdByParser);
+ document()->styleSheetCollection()->addStyleSheetCandidateNode(this, m_createdByParser);
checkStyleSheet();
return InsertionDone;
}
@@ -304,7 +305,7 @@ void ProcessingInstruction::removedFrom(ContainerNode* insertionPoint)
if (!insertionPoint->inDocument())
return;
- document()->removeStyleSheetCandidateNode(this);
+ document()->styleSheetCollection()->removeStyleSheetCandidateNode(this);
if (m_sheet) {
ASSERT(m_sheet->ownerNode() == this);
diff --git a/Source/WebCore/dom/StyleElement.cpp b/Source/WebCore/dom/StyleElement.cpp
index dd4de2901..ff22fe9db 100644
--- a/Source/WebCore/dom/StyleElement.cpp
+++ b/Source/WebCore/dom/StyleElement.cpp
@@ -24,6 +24,7 @@
#include "Attribute.h"
#include "ContentSecurityPolicy.h"
#include "Document.h"
+#include "DocumentStyleSheetCollection.h"
#include "Element.h"
#include "MediaList.h"
#include "MediaQueryEvaluator.h"
@@ -63,7 +64,7 @@ void StyleElement::insertedIntoDocument(Document* document, Element* element)
{
ASSERT(document);
ASSERT(element);
- document->addStyleSheetCandidateNode(element, m_createdByParser);
+ document->styleSheetCollection()->addStyleSheetCandidateNode(element, m_createdByParser);
if (m_createdByParser)
return;
@@ -74,7 +75,7 @@ void StyleElement::removedFromDocument(Document* document, Element* element)
{
ASSERT(document);
ASSERT(element);
- document->removeStyleSheetCandidateNode(element);
+ document->styleSheetCollection()->removeStyleSheetCandidateNode(element);
if (m_sheet)
clearSheet();
@@ -90,7 +91,7 @@ void StyleElement::clearDocumentData(Document* document, Element* element)
m_sheet->clearOwnerNode();
if (element->inDocument())
- document->removeStyleSheetCandidateNode(element);
+ document->styleSheetCollection()->removeStyleSheetCandidateNode(element);
}
void StyleElement::childrenChanged(Element* element)
@@ -152,7 +153,7 @@ void StyleElement::createSheet(Element* e, WTF::OrdinalNumber startLineNumber, c
Document* document = e->document();
if (m_sheet) {
if (m_sheet->isLoading())
- document->removePendingSheet();
+ document->styleSheetCollection()->removePendingSheet();
clearSheet();
}
@@ -168,7 +169,7 @@ void StyleElement::createSheet(Element* e, WTF::OrdinalNumber startLineNumber, c
MediaQueryEvaluator screenEval("screen", true);
MediaQueryEvaluator printEval("print", true);
if (screenEval.eval(mediaQueries.get()) || printEval.eval(mediaQueries.get())) {
- document->addPendingSheet();
+ document->styleSheetCollection()->addPendingSheet();
m_loading = true;
m_sheet = CSSStyleSheet::createInline(e, KURL(), document->inputEncoding());
@@ -197,14 +198,14 @@ bool StyleElement::sheetLoaded(Document* document)
if (isLoading())
return false;
- document->removePendingSheet();
+ document->styleSheetCollection()->removePendingSheet();
return true;
}
void StyleElement::startLoadingDynamicSheet(Document* document)
{
ASSERT(document);
- document->addPendingSheet();
+ document->styleSheetCollection()->addPendingSheet();
}
}
diff --git a/Source/WebCore/html/DateTimeFieldsState.cpp b/Source/WebCore/html/DateTimeFieldsState.cpp
index 8e2bd6c1c..990389dc4 100644
--- a/Source/WebCore/html/DateTimeFieldsState.cpp
+++ b/Source/WebCore/html/DateTimeFieldsState.cpp
@@ -67,6 +67,13 @@ DateTimeFieldsState::DateTimeFieldsState()
{
}
+unsigned DateTimeFieldsState::hour23() const
+{
+ if (!hasHour() || !hasAMPM())
+ return emptyValue;
+ return (m_hour % 12) + (m_ampm == AMPMValuePM ? 12 : 0);
+}
+
DateTimeFieldsState DateTimeFieldsState::restoreFormControlState(const FormControlState& state)
{
DateTimeFieldsState dateTimeFieldsState;
diff --git a/Source/WebCore/html/DateTimeFieldsState.h b/Source/WebCore/html/DateTimeFieldsState.h
index b6240629e..6fb444071 100644
--- a/Source/WebCore/html/DateTimeFieldsState.h
+++ b/Source/WebCore/html/DateTimeFieldsState.h
@@ -57,6 +57,7 @@ public:
AMPMValue ampm() const { return m_ampm; }
unsigned dayOfMonth() const { return m_dayOfMonth; }
unsigned hour() const { return m_hour; }
+ unsigned hour23() const;
unsigned millisecond() const { return m_millisecond; }
unsigned minute() const { return m_minute; }
unsigned month() const { return m_month; }
@@ -88,7 +89,7 @@ private:
unsigned m_year;
unsigned m_month;
unsigned m_dayOfMonth;
- unsigned m_hour;
+ unsigned m_hour; // 1 to 12.
unsigned m_minute;
unsigned m_second;
unsigned m_millisecond;
diff --git a/Source/WebCore/html/HTMLLinkElement.cpp b/Source/WebCore/html/HTMLLinkElement.cpp
index d2868b610..fdc7a5cce 100644
--- a/Source/WebCore/html/HTMLLinkElement.cpp
+++ b/Source/WebCore/html/HTMLLinkElement.cpp
@@ -30,6 +30,7 @@
#include "CachedResource.h"
#include "CachedResourceLoader.h"
#include "Document.h"
+#include "DocumentStyleSheetCollection.h"
#include "EventSender.h"
#include "Frame.h"
#include "FrameLoader.h"
@@ -87,7 +88,7 @@ HTMLLinkElement::~HTMLLinkElement()
m_cachedSheet->removeClient(this);
if (inDocument())
- document()->removeStyleSheetCandidateNode(this);
+ document()->styleSheetCollection()->removeStyleSheetCandidateNode(this);
linkLoadEventSender().cancelEvent(this);
}
@@ -254,7 +255,7 @@ Node::InsertionNotificationRequest HTMLLinkElement::insertedInto(ContainerNode*
if (m_isInShadowTree)
return InsertionDone;
- document()->addStyleSheetCandidateNode(this, m_createdByParser);
+ document()->styleSheetCollection()->addStyleSheetCandidateNode(this, m_createdByParser);
process();
return InsertionDone;
@@ -272,7 +273,7 @@ void HTMLLinkElement::removedFrom(ContainerNode* insertionPoint)
ASSERT(!m_sheet);
return;
}
- document()->removeStyleSheetCandidateNode(this);
+ document()->styleSheetCollection()->removeStyleSheetCandidateNode(this);
if (m_sheet)
clearSheet();
@@ -455,7 +456,7 @@ void HTMLLinkElement::addPendingSheet(PendingSheetType type)
if (m_pendingSheetType == NonBlocking)
return;
- document()->addPendingSheet();
+ document()->styleSheetCollection()->addPendingSheet();
}
void HTMLLinkElement::removePendingSheet(RemovePendingSheetNotificationType notification)
@@ -471,10 +472,10 @@ void HTMLLinkElement::removePendingSheet(RemovePendingSheetNotificationType noti
return;
}
- document()->removePendingSheet(
+ document()->styleSheetCollection()->removePendingSheet(
notification == RemovePendingSheetNotifyImmediately
- ? Document::RemovePendingSheetNotifyImmediately
- : Document::RemovePendingSheetNotifyLater);
+ ? DocumentStyleSheetCollection::RemovePendingSheetNotifyImmediately
+ : DocumentStyleSheetCollection::RemovePendingSheetNotifyLater);
}
DOMSettableTokenList* HTMLLinkElement::sizes() const
diff --git a/Source/WebCore/html/HTMLQuoteElement.cpp b/Source/WebCore/html/HTMLQuoteElement.cpp
index 05a33ab5e..d5be2f2f7 100644
--- a/Source/WebCore/html/HTMLQuoteElement.cpp
+++ b/Source/WebCore/html/HTMLQuoteElement.cpp
@@ -24,6 +24,7 @@
#include "HTMLQuoteElement.h"
#include "Document.h"
+#include "DocumentStyleSheetCollection.h"
#include "HTMLNames.h"
namespace WebCore {
@@ -44,7 +45,7 @@ PassRefPtr<HTMLQuoteElement> HTMLQuoteElement::create(const QualifiedName& tagNa
Node::InsertionNotificationRequest HTMLQuoteElement::insertedInto(ContainerNode* insertionPoint)
{
if (hasTagName(qTag))
- document()->setUsesBeforeAfterRules(true);
+ document()->styleSheetCollection()->setUsesBeforeAfterRulesOverride(true);
return HTMLElement::insertedInto(insertionPoint);
}
diff --git a/Source/WebCore/html/HTMLViewSourceDocument.cpp b/Source/WebCore/html/HTMLViewSourceDocument.cpp
index 3de813770..a4da71a25 100644
--- a/Source/WebCore/html/HTMLViewSourceDocument.cpp
+++ b/Source/WebCore/html/HTMLViewSourceDocument.cpp
@@ -27,6 +27,7 @@
#include "Attribute.h"
#include "DOMImplementation.h"
+#include "DocumentStyleSheetCollection.h"
#include "HTMLAnchorElement.h"
#include "HTMLBRElement.h"
#include "HTMLBaseElement.h"
@@ -52,7 +53,7 @@ HTMLViewSourceDocument::HTMLViewSourceDocument(Frame* frame, const KURL& url, co
: HTMLDocument(frame, url)
, m_type(mimeType)
{
- setUsesBeforeAfterRules(true);
+ styleSheetCollection()->setUsesBeforeAfterRulesOverride(true);
setIsViewSource(true);
setCompatibilityMode(QuirksMode);
diff --git a/Source/WebCore/html/TimeInputType.cpp b/Source/WebCore/html/TimeInputType.cpp
index 4b5bb1f15..a0051513a 100644
--- a/Source/WebCore/html/TimeInputType.cpp
+++ b/Source/WebCore/html/TimeInputType.cpp
@@ -48,6 +48,7 @@
#include "KeyboardEvent.h"
#include "Localizer.h"
#include "ShadowRoot.h"
+#include <wtf/text/WTFString.h>
#endif
namespace WebCore {
@@ -149,13 +150,32 @@ void TimeInputType::DateTimeEditControlOwnerImpl::didFocusOnControl()
void TimeInputType::DateTimeEditControlOwnerImpl::editControlValueChanged()
{
RefPtr<HTMLInputElement> input(m_timeInputType.element());
- input->setValueInternal(m_timeInputType.serialize(Decimal::fromDouble(m_timeInputType.m_dateTimeEditElement->valueAsDouble())), DispatchNoEvent);
+ input->setValueInternal(m_timeInputType.m_dateTimeEditElement->value(), DispatchNoEvent);
input->setNeedsStyleRecalc();
input->dispatchFormControlInputEvent();
input->dispatchFormControlChangeEvent();
input->notifyFormStateChanged();
}
+
+String TimeInputType::DateTimeEditControlOwnerImpl::formatDateTimeFieldsState(const DateTimeFieldsState& dateTimeFieldsState) const
+{
+ if (!dateTimeFieldsState.hasHour() || !dateTimeFieldsState.hasMinute() || !dateTimeFieldsState.hasAMPM())
+ return emptyString();
+ if (dateTimeFieldsState.hasMillisecond() && dateTimeFieldsState.millisecond())
+ return String::format("%02u:%02u:%02u.%03u",
+ dateTimeFieldsState.hour23(),
+ dateTimeFieldsState.minute(),
+ dateTimeFieldsState.hasSecond() ? dateTimeFieldsState.second() : 0,
+ dateTimeFieldsState.millisecond());
+ if (dateTimeFieldsState.hasSecond() && dateTimeFieldsState.second())
+ return String::format("%02u:%02u:%02u",
+ dateTimeFieldsState.hour23(),
+ dateTimeFieldsState.minute(),
+ dateTimeFieldsState.second());
+ return String::format("%02u:%02u", dateTimeFieldsState.hour23(), dateTimeFieldsState.minute());
+}
+
bool TimeInputType::hasCustomFocusLogic() const
{
return false;
@@ -271,7 +291,7 @@ void TimeInputType::restoreFormControlState(const FormControlState& state)
setMillisecondToDateComponents(createStepRange(AnyIsDefaultStep).minimum().toDouble(), &date);
DateTimeFieldsState dateTimeFieldsState = DateTimeFieldsState::restoreFormControlState(state);
m_dateTimeEditElement->setValueAsDateTimeFieldsState(dateTimeFieldsState, date);
- element()->setValueInternal(serialize(Decimal::fromDouble(m_dateTimeEditElement->valueAsDouble())), DispatchNoEvent);
+ element()->setValueInternal(m_dateTimeEditElement->value(), DispatchNoEvent);
}
FormControlState TimeInputType::saveFormControlState() const
diff --git a/Source/WebCore/html/TimeInputType.h b/Source/WebCore/html/TimeInputType.h
index 0787c3a21..59e272102 100644
--- a/Source/WebCore/html/TimeInputType.h
+++ b/Source/WebCore/html/TimeInputType.h
@@ -71,6 +71,7 @@ private:
virtual void didBlurFromControl() OVERRIDE FINAL;
virtual void didFocusOnControl() OVERRIDE FINAL;
virtual void editControlValueChanged() OVERRIDE FINAL;
+ virtual String formatDateTimeFieldsState(const DateTimeFieldsState&) const OVERRIDE FINAL;
virtual bool isEditControlOwnerDisabled() const OVERRIDE FINAL;
virtual bool isEditControlOwnerReadOnly() const OVERRIDE FINAL;
diff --git a/Source/WebCore/html/parser/HTMLTreeBuilder.cpp b/Source/WebCore/html/parser/HTMLTreeBuilder.cpp
index 131cdbff6..940800ef8 100644
--- a/Source/WebCore/html/parser/HTMLTreeBuilder.cpp
+++ b/Source/WebCore/html/parser/HTMLTreeBuilder.cpp
@@ -686,9 +686,7 @@ void HTMLTreeBuilder::processStartTagForInBody(AtomicHTMLToken* token)
}
if (!m_framesetOk)
return;
- ExceptionCode ec = 0;
- m_tree.openElements()->bodyElement()->remove(ec);
- ASSERT(!ec);
+ m_tree.openElements()->bodyElement()->remove(ASSERT_NO_EXCEPTION);
m_tree.openElements()->popUntil(m_tree.openElements()->bodyElement());
m_tree.openElements()->popHTMLBodyElement();
ASSERT(m_tree.openElements()->top() == m_tree.openElements()->htmlElement());
diff --git a/Source/WebCore/html/shadow/DateTimeEditElement.cpp b/Source/WebCore/html/shadow/DateTimeEditElement.cpp
index 07befd874..ad4870ca8 100644
--- a/Source/WebCore/html/shadow/DateTimeEditElement.cpp
+++ b/Source/WebCore/html/shadow/DateTimeEditElement.cpp
@@ -450,6 +450,13 @@ void DateTimeEditElement::updateUIState()
}
}
+String DateTimeEditElement::value() const
+{
+ if (!m_editControlOwner)
+ return emptyString();
+ return m_editControlOwner->formatDateTimeFieldsState(valueAsDateTimeFieldsState());
+}
+
DateTimeFieldsState DateTimeEditElement::valueAsDateTimeFieldsState() const
{
DateTimeFieldsState dateTimeFieldsState;
@@ -458,20 +465,6 @@ DateTimeFieldsState DateTimeEditElement::valueAsDateTimeFieldsState() const
return dateTimeFieldsState;
}
-double DateTimeEditElement::valueAsDouble() const
-{
- double value = 0;
-
- for (size_t fieldIndex = 0; fieldIndex < m_fields.size(); ++fieldIndex) {
- const DateTimeFieldElement* const field = m_fields[fieldIndex];
- if (!field->hasValue())
- return std::numeric_limits<double>::quiet_NaN();
- value += field->valueAsDouble();
- }
-
- return value;
-}
-
} // namespace WebCore
#endif
diff --git a/Source/WebCore/html/shadow/DateTimeEditElement.h b/Source/WebCore/html/shadow/DateTimeEditElement.h
index e547cbdea..84cf229c6 100644
--- a/Source/WebCore/html/shadow/DateTimeEditElement.h
+++ b/Source/WebCore/html/shadow/DateTimeEditElement.h
@@ -55,6 +55,7 @@ public:
virtual void didBlurFromControl() = 0;
virtual void didFocusOnControl() = 0;
virtual void editControlValueChanged() = 0;
+ virtual String formatDateTimeFieldsState(const DateTimeFieldsState&) const = 0;
virtual bool isEditControlOwnerDisabled() const = 0;
virtual bool isEditControlOwnerReadOnly() const = 0;
};
@@ -88,8 +89,8 @@ public:
void setEmptyValue(const LayoutParameters&, const DateComponents& dateForReadOnlyField);
void setValueAsDate(const LayoutParameters&, const DateComponents&);
void setValueAsDateTimeFieldsState(const DateTimeFieldsState&, const DateComponents& dateForReadOnlyField);
+ String value() const;
DateTimeFieldsState valueAsDateTimeFieldsState() const;
- double valueAsDouble() const;
private:
static const size_t invalidFieldIndex = static_cast<size_t>(-1);
diff --git a/Source/WebCore/html/shadow/DateTimeFieldElement.cpp b/Source/WebCore/html/shadow/DateTimeFieldElement.cpp
index 74817570a..a0ec51e59 100644
--- a/Source/WebCore/html/shadow/DateTimeFieldElement.cpp
+++ b/Source/WebCore/html/shadow/DateTimeFieldElement.cpp
@@ -186,11 +186,6 @@ void DateTimeFieldElement::updateVisibleValue(EventBehavior eventBehavior)
m_fieldOwner->fieldValueChanged();
}
-double DateTimeFieldElement::valueAsDouble() const
-{
- return hasValue() ? valueAsInteger() * unitInMillisecond() : std::numeric_limits<double>::quiet_NaN();
-}
-
} // namespace WebCore
#endif
diff --git a/Source/WebCore/html/shadow/DateTimeFieldElement.h b/Source/WebCore/html/shadow/DateTimeFieldElement.h
index e8d25cf91..f5c9810a1 100644
--- a/Source/WebCore/html/shadow/DateTimeFieldElement.h
+++ b/Source/WebCore/html/shadow/DateTimeFieldElement.h
@@ -70,7 +70,6 @@ public:
virtual void stepDown() = 0;
virtual void stepUp() = 0;
virtual String value() const = 0;
- double valueAsDouble() const;
virtual int valueAsInteger() const = 0;
virtual String visibleValue() const = 0;
@@ -83,7 +82,6 @@ protected:
void initialize(const AtomicString& shadowPseudoId, const String& axHelpText);
virtual int maximum() const = 0;
virtual int minimum() const = 0;
- virtual double unitInMillisecond() const = 0;
void updateVisibleValue(EventBehavior);
private:
diff --git a/Source/WebCore/html/shadow/DateTimeFieldElements.cpp b/Source/WebCore/html/shadow/DateTimeFieldElements.cpp
index 2016c69a8..c2f458a21 100644
--- a/Source/WebCore/html/shadow/DateTimeFieldElements.cpp
+++ b/Source/WebCore/html/shadow/DateTimeFieldElements.cpp
@@ -30,7 +30,6 @@
#include "DateComponents.h"
#include "DateTimeFieldsState.h"
#include "LocalizedStrings.h"
-#include <wtf/DateMath.h>
namespace WebCore {
@@ -68,11 +67,6 @@ void DateTimeAMPMFieldElement::setValueAsDateTimeFieldsState(const DateTimeField
setEmptyValue(dateForReadOnlyField);
}
-double DateTimeAMPMFieldElement::unitInMillisecond() const
-{
- return msPerHour * 12;
-}
-
// ----------------------------
DateTimeHourFieldElement::DateTimeHourFieldElement(Document* document, FieldOwner& fieldOwner, int minimum, int maximum)
@@ -173,11 +167,6 @@ void DateTimeHourFieldElement::setValueAsInteger(int valueAsHour23, EventBehavio
DateTimeNumericFieldElement::setValueAsInteger(range().minimum && !value ? m_alignment : value, eventBehavior);
}
-double DateTimeHourFieldElement::unitInMillisecond() const
-{
- return msPerHour;
-}
-
int DateTimeHourFieldElement::valueAsInteger() const
{
return hasValue() ? DateTimeNumericFieldElement::valueAsInteger() % m_alignment : -1;
@@ -224,11 +213,6 @@ void DateTimeMillisecondFieldElement::setValueAsDateTimeFieldsState(const DateTi
setValueAsInteger(value);
}
-double DateTimeMillisecondFieldElement::unitInMillisecond() const
-{
- return 1;
-}
-
// ----------------------------
DateTimeMinuteFieldElement::DateTimeMinuteFieldElement(Document* document, FieldOwner& fieldOwner)
@@ -270,11 +254,6 @@ void DateTimeMinuteFieldElement::setValueAsDateTimeFieldsState(const DateTimeFie
setValueAsInteger(value);
}
-double DateTimeMinuteFieldElement::unitInMillisecond() const
-{
- return msPerMinute;
-}
-
// ----------------------------
DateTimeSecondFieldElement::DateTimeSecondFieldElement(Document* document, FieldOwner& fieldOwner)
@@ -316,11 +295,6 @@ void DateTimeSecondFieldElement::setValueAsDateTimeFieldsState(const DateTimeFie
setValueAsInteger(value);
}
-double DateTimeSecondFieldElement::unitInMillisecond() const
-{
- return msPerSecond;
-}
-
} // namespace WebCore
#endif
diff --git a/Source/WebCore/html/shadow/DateTimeFieldElements.h b/Source/WebCore/html/shadow/DateTimeFieldElements.h
index e141f838f..23f3403ea 100644
--- a/Source/WebCore/html/shadow/DateTimeFieldElements.h
+++ b/Source/WebCore/html/shadow/DateTimeFieldElements.h
@@ -45,7 +45,6 @@ private:
virtual void populateDateTimeFieldsState(DateTimeFieldsState&) OVERRIDE FINAL;
virtual void setValueAsDate(const DateComponents&) OVERRIDE FINAL;
virtual void setValueAsDateTimeFieldsState(const DateTimeFieldsState&, const DateComponents& dateForReadOnlyField) OVERRIDE FINAL;
- virtual double unitInMillisecond() const OVERRIDE FINAL;
};
@@ -69,7 +68,6 @@ private:
virtual void setValueAsDate(const DateComponents&) OVERRIDE FINAL;
virtual void setValueAsDateTimeFieldsState(const DateTimeFieldsState&, const DateComponents& dateForReadOnlyField) OVERRIDE FINAL;
virtual void setValueAsInteger(int, EventBehavior = DispatchNoEvent) OVERRIDE FINAL;
- virtual double unitInMillisecond() const OVERRIDE FINAL;
virtual int valueAsInteger() const OVERRIDE FINAL;
const int m_alignment;
@@ -88,7 +86,6 @@ private:
virtual void populateDateTimeFieldsState(DateTimeFieldsState&) OVERRIDE FINAL;
virtual void setValueAsDate(const DateComponents&) OVERRIDE FINAL;
virtual void setValueAsDateTimeFieldsState(const DateTimeFieldsState&, const DateComponents& dateForReadOnlyField) OVERRIDE FINAL;
- virtual double unitInMillisecond() const OVERRIDE FINAL;
};
class DateTimeMinuteFieldElement : public DateTimeNumericFieldElement {
@@ -104,7 +101,6 @@ private:
virtual void populateDateTimeFieldsState(DateTimeFieldsState&) OVERRIDE FINAL;
virtual void setValueAsDate(const DateComponents&) OVERRIDE FINAL;
virtual void setValueAsDateTimeFieldsState(const DateTimeFieldsState&, const DateComponents& dateForReadOnlyField) OVERRIDE FINAL;
- virtual double unitInMillisecond() const OVERRIDE FINAL;
};
class DateTimeSecondFieldElement : public DateTimeNumericFieldElement {
@@ -120,7 +116,6 @@ private:
virtual void populateDateTimeFieldsState(DateTimeFieldsState&) OVERRIDE FINAL;
virtual void setValueAsDate(const DateComponents&) OVERRIDE FINAL;
virtual void setValueAsDateTimeFieldsState(const DateTimeFieldsState&, const DateComponents& dateForReadOnlyField) OVERRIDE FINAL;
- virtual double unitInMillisecond() const OVERRIDE FINAL;
};
} // namespace WebCore
diff --git a/Source/WebCore/html/track/TextTrackCue.cpp b/Source/WebCore/html/track/TextTrackCue.cpp
index 299fc1b7c..2fd4f1d4b 100644
--- a/Source/WebCore/html/track/TextTrackCue.cpp
+++ b/Source/WebCore/html/track/TextTrackCue.cpp
@@ -742,8 +742,7 @@ PassRefPtr<TextTrackCueBox> TextTrackCue::getDisplayTree()
void TextTrackCue::removeDisplayTree()
{
- if (m_displayTree->parentNode())
- m_displayTree->remove(ASSERT_NO_EXCEPTION);
+ m_displayTree->remove(ASSERT_NO_EXCEPTION);
}
std::pair<double, double> TextTrackCue::getPositionCoordinates() const
diff --git a/Source/WebCore/inspector/InjectedScriptCanvasModule.cpp b/Source/WebCore/inspector/InjectedScriptCanvasModule.cpp
index db278d976..b1f1dca27 100644
--- a/Source/WebCore/inspector/InjectedScriptCanvasModule.cpp
+++ b/Source/WebCore/inspector/InjectedScriptCanvasModule.cpp
@@ -59,20 +59,30 @@ String InjectedScriptCanvasModule::source() const
return String(reinterpret_cast<const char*>(InjectedScriptCanvasModuleSource_js), sizeof(InjectedScriptCanvasModuleSource_js));
}
+ScriptObject InjectedScriptCanvasModule::wrapCanvas2DContext(const ScriptObject& context)
+{
+ return callWrapContextFunction("wrapCanvas2DContext", context);
+}
+
#if ENABLE(WEBGL)
ScriptObject InjectedScriptCanvasModule::wrapWebGLContext(const ScriptObject& glContext)
{
- ScriptFunctionCall function(injectedScriptObject(), "wrapWebGLContext");
- function.appendArgument(glContext);
+ return callWrapContextFunction("wrapWebGLContext", glContext);
+}
+#endif // ENABLE(WEBGL)
+
+ScriptObject InjectedScriptCanvasModule::callWrapContextFunction(const String& functionName, const ScriptObject& context)
+{
+ ScriptFunctionCall function(injectedScriptObject(), functionName);
+ function.appendArgument(context);
bool hadException = false;
ScriptValue resultValue = callFunctionWithEvalEnabled(function, hadException);
if (hadException || resultValue.hasNoValue() || !resultValue.isObject()) {
ASSERT_NOT_REACHED();
return ScriptObject();
}
- return ScriptObject(glContext.scriptState(), resultValue);
+ return ScriptObject(context.scriptState(), resultValue);
}
-#endif // ENABLE(WEBGL)
void InjectedScriptCanvasModule::captureFrame(ErrorString* errorString, String* traceLogId)
{
diff --git a/Source/WebCore/inspector/InjectedScriptCanvasModule.h b/Source/WebCore/inspector/InjectedScriptCanvasModule.h
index 4de223660..2e960aa6e 100644
--- a/Source/WebCore/inspector/InjectedScriptCanvasModule.h
+++ b/Source/WebCore/inspector/InjectedScriptCanvasModule.h
@@ -50,14 +50,18 @@ public:
static InjectedScriptCanvasModule moduleForState(InjectedScriptManager*, ScriptState*);
+ ScriptObject wrapCanvas2DContext(const ScriptObject&);
#if ENABLE(WEBGL)
- ScriptObject wrapWebGLContext(const ScriptObject& glContext);
+ ScriptObject wrapWebGLContext(const ScriptObject&);
#endif
void captureFrame(ErrorString*, String*);
void dropTraceLog(ErrorString*, const String&);
void traceLog(ErrorString*, const String&, RefPtr<TypeBuilder::Canvas::TraceLog>*);
void replayTraceLog(ErrorString*, const String&, int, String*);
+
+private:
+ ScriptObject callWrapContextFunction(const String&, const ScriptObject&);
};
#endif
diff --git a/Source/WebCore/inspector/InjectedScriptCanvasModuleSource.js b/Source/WebCore/inspector/InjectedScriptCanvasModuleSource.js
index 6780af3c4..26afeeb54 100644
--- a/Source/WebCore/inspector/InjectedScriptCanvasModuleSource.js
+++ b/Source/WebCore/inspector/InjectedScriptCanvasModuleSource.js
@@ -743,7 +743,7 @@ Resource.prototype = {
if (isCapturing) {
var call = wrapFunction.call();
call.setStackTrace(StackTrace.create(1, arguments.callee));
- manager.reportCall(call);
+ manager.captureCall(call);
}
return wrapFunction.result();
};
@@ -767,7 +767,7 @@ Resource.prototype = {
var result = originalFunction.apply(originalObject, arguments);
var stackTrace = StackTrace.create(1, arguments.callee);
var call = new Call(resource, functionName, arguments, result, stackTrace);
- manager.reportCall(call);
+ manager.captureCall(call);
return result;
};
},
@@ -833,6 +833,27 @@ Resource.WrapFunction.prototype = {
}
/**
+ * @param {!Function} resourceConstructor
+ * @return {Function}
+ */
+Resource.WrapFunction.resourceFactoryMethod = function(resourceConstructor)
+{
+ /** @this Resource.WrapFunction */
+ return function()
+ {
+ var wrappedObject = this.result();
+ if (!wrappedObject)
+ return;
+ var resource = new resourceConstructor(wrappedObject);
+ var manager = this._resource.manager();
+ if (manager)
+ manager.registerResource(resource);
+ this.overrideResult(resource.proxyObject());
+ resource.pushCall(this.call());
+ }
+}
+
+/**
* @constructor
* @param {Resource} originalResource
* @param {Object} data
@@ -867,6 +888,10 @@ ReplayableResource.replay = function(obj, cache)
return (obj instanceof ReplayableResource) ? obj.replay(cache).wrappedObject() : obj;
}
+////////////////////////////////////////////////////////////////////////////////
+// WebGL
+////////////////////////////////////////////////////////////////////////////////
+
/**
* @constructor
* @extends {Resource}
@@ -1033,8 +1058,10 @@ WebGLTextureResource.prototype = {
var framebufferResource = glResource.currentBinding(gl.FRAMEBUFFER);
if (framebufferResource)
this.pushCall(new Call(glResource, "bindFramebuffer", [gl.FRAMEBUFFER, framebufferResource]));
- else
- console.error("ASSERT_NOT_REACHED: No FRAMEBUFFER bound while calling gl." + call.functionName());
+ else {
+ // FIXME: Implement this case.
+ console.error("ASSERT_NOT_REACHED: Could not properly process a gl." + call.functionName() + " call while the DRAWING BUFFER is bound.");
+ }
this.pushCall(call);
}
}
@@ -1369,10 +1396,10 @@ WebGLRenderingContextResource.forObject = function(obj)
var resource = Resource.forObject(obj);
if (!resource || resource instanceof WebGLRenderingContextResource)
return resource;
- var call = resource.calls();
- if (!call || !call.length)
+ var calls = resource.calls();
+ if (!calls || !calls.length)
return null;
- resource = call[0].resource();
+ resource = calls[0].resource();
return (resource instanceof WebGLRenderingContextResource) ? resource : null;
}
@@ -1593,7 +1620,7 @@ WebGLRenderingContextResource.prototype = {
}
gl.activeTexture(glState.ACTIVE_TEXTURE);
- return Resource.prototype._doReplayCalls.call(this, data, cache);
+ Resource.prototype._doReplayCalls.call(this, data, cache);
},
/**
@@ -1661,33 +1688,13 @@ WebGLRenderingContextResource.prototype = {
if (!wrapFunctions) {
wrapFunctions = Object.create(null);
- /**
- * @param {string} methodName
- * @param {Function} resourceConstructor
- */
- function createResourceWrapFunction(methodName, resourceConstructor)
- {
- /** @this Resource.WrapFunction */
- wrapFunctions[methodName] = function()
- {
- var wrappedObject = this.result();
- if (!wrappedObject)
- return;
- var resource = new resourceConstructor(wrappedObject);
- var manager = this._resource.manager();
- if (manager)
- manager.registerResource(resource);
- this.overrideResult(resource.proxyObject());
- resource.pushCall(this.call());
- }
- }
- createResourceWrapFunction("createBuffer", WebGLBufferResource);
- createResourceWrapFunction("createShader", WebGLShaderResource);
- createResourceWrapFunction("createProgram", WebGLProgramResource);
- createResourceWrapFunction("createTexture", WebGLTextureResource);
- createResourceWrapFunction("createFramebuffer", WebGLFramebufferResource);
- createResourceWrapFunction("createRenderbuffer", WebGLRenderbufferResource);
- createResourceWrapFunction("getUniformLocation", Resource);
+ wrapFunctions["createBuffer"] = Resource.WrapFunction.resourceFactoryMethod(WebGLBufferResource);
+ wrapFunctions["createShader"] = Resource.WrapFunction.resourceFactoryMethod(WebGLShaderResource);
+ wrapFunctions["createProgram"] = Resource.WrapFunction.resourceFactoryMethod(WebGLProgramResource);
+ wrapFunctions["createTexture"] = Resource.WrapFunction.resourceFactoryMethod(WebGLTextureResource);
+ wrapFunctions["createFramebuffer"] = Resource.WrapFunction.resourceFactoryMethod(WebGLFramebufferResource);
+ wrapFunctions["createRenderbuffer"] = Resource.WrapFunction.resourceFactoryMethod(WebGLRenderbufferResource);
+ wrapFunctions["getUniformLocation"] = Resource.WrapFunction.resourceFactoryMethod(Resource);
/**
* @param {string} methodName
@@ -1753,6 +1760,227 @@ WebGLRenderingContextResource.prototype = {
WebGLRenderingContextResource.prototype.__proto__ = Resource.prototype;
+////////////////////////////////////////////////////////////////////////////////
+// 2D Canvas
+////////////////////////////////////////////////////////////////////////////////
+
+/**
+ * @constructor
+ * @extends {Resource}
+ * @param {CanvasRenderingContext2D} context
+ * @param {Function} replayContextCallback
+ */
+function CanvasRenderingContext2DResource(context, replayContextCallback)
+{
+ Resource.call(this, context);
+ this._replayContextCallback = replayContextCallback;
+ this._attributesStack = [];
+}
+
+/**
+ * @const
+ * @type {Array.<string>}
+ */
+CanvasRenderingContext2DResource.AttributeProperties = [
+ "strokeStyle",
+ "fillStyle",
+ "globalAlpha",
+ "lineWidth",
+ "lineCap",
+ "lineJoin",
+ "miterLimit",
+ "shadowOffsetX",
+ "shadowOffsetY",
+ "shadowBlur",
+ "shadowColor",
+ "globalCompositeOperation",
+ "font",
+ "textAlign",
+ "textBaseline"
+];
+
+/**
+ * @const
+ * @type {Array.<string>}
+ */
+CanvasRenderingContext2DResource.PathMethods = [
+ "beginPath",
+ "moveTo",
+ "closePath",
+ "lineTo",
+ "quadraticCurveTo",
+ "bezierCurveTo",
+ "arcTo",
+ "arc",
+ "rect"
+];
+
+/**
+ * @const
+ * @type {Array.<string>}
+ */
+CanvasRenderingContext2DResource.TransformationMatrixMethods = [
+ "scale",
+ "rotate",
+ "translate",
+ "transform",
+ "setTransform"
+];
+
+CanvasRenderingContext2DResource.prototype = {
+ /**
+ * @override
+ * @param {Object} data
+ * @param {Cache} cache
+ */
+ _populateReplayableData: function(data, cache)
+ {
+ data.replayContextCallback = this._replayContextCallback;
+ data.attributesStack = this._attributesStack.slice(0);
+ data.currentAttributes = this._currentAttributesState();
+ },
+
+ /**
+ * @override
+ * @param {Object} data
+ * @param {Cache} cache
+ */
+ _doReplayCalls: function(data, cache)
+ {
+ this._replayContextCallback = data.replayContextCallback;
+ this._attributesStack = data.attributesStack.slice(0);
+
+ var ctx = Resource.wrappedObject(this._replayContextCallback());
+ this.setWrappedObject(ctx);
+
+ var saveCalls = 0;
+ for (var i = 0, n = data.calls.length; i < n; ++i) {
+ var replayableCall = data.calls[i];
+ if (replayableCall.functionName() === "save") {
+ console.assert(saveCalls < this._attributesStack.length, "Size of attributes stack is less than 'save' calls");
+ this._applyAttributesState(this._attributesStack[saveCalls++]);
+ }
+ this._calls.push(replayableCall.replay(cache));
+ }
+ console.assert(saveCalls === this._attributesStack.length, "Size of attributes stack should be equal to the number of 'save' calls");
+ this._applyAttributesState(data.currentAttributes);
+ },
+
+ /**
+ * @param {Call} call
+ */
+ pushCall_setTransform: function(call)
+ {
+ // FIXME: Remove obsolete transform matrix methods.
+ this.pushCall(call);
+ },
+
+ /**
+ * @param {Call} call
+ */
+ pushCall_beginPath: function(call)
+ {
+ // FIXME: Remove obsolete path methods.
+ this.pushCall(call);
+ },
+
+ /**
+ * @param {Call} call
+ */
+ pushCall_save: function(call)
+ {
+ this._attributesStack.push(this._currentAttributesState());
+ this.pushCall(call);
+ },
+
+ /**
+ * @param {Call} call
+ */
+ pushCall_restore: function(call)
+ {
+ this._attributesStack.pop();
+ // FIXME: Remove obsolete clip,save methods.
+ this.pushCall(call);
+ },
+
+ /**
+ * @return {!Object.<string, string>}
+ */
+ _currentAttributesState: function()
+ {
+ var ctx = this.wrappedObject();
+ var state = {};
+ CanvasRenderingContext2DResource.AttributeProperties.forEach(function(attribute) {
+ state[attribute] = ctx[attribute];
+ });
+ return state;
+ },
+
+ /**
+ * @param {!Object.<string, string>} state
+ */
+ _applyAttributesState: function(state)
+ {
+ var ctx = this.wrappedObject();
+ Object.keys(state).forEach(function(attribute) {
+ ctx[attribute] = state[attribute];
+ });
+ },
+
+ /**
+ * @override
+ * @return {Object.<string, Function>}
+ */
+ _customWrapFunctions: function()
+ {
+ var wrapFunctions = CanvasRenderingContext2DResource._wrapFunctions;
+ if (!wrapFunctions) {
+ wrapFunctions = Object.create(null);
+
+ wrapFunctions["createLinearGradient"] = Resource.WrapFunction.resourceFactoryMethod(Resource);
+ wrapFunctions["createRadialGradient"] = Resource.WrapFunction.resourceFactoryMethod(Resource);
+ wrapFunctions["createPattern"] = Resource.WrapFunction.resourceFactoryMethod(Resource);
+
+ /**
+ * @param {string} methodName
+ * @param {Function=} func
+ */
+ function stateModifyingWrapFunction(methodName, func)
+ {
+ if (func) {
+ /** @this Resource.WrapFunction */
+ wrapFunctions[methodName] = function()
+ {
+ func.call(this._resource, this.call());
+ }
+ } else {
+ /** @this Resource.WrapFunction */
+ wrapFunctions[methodName] = function()
+ {
+ this._resource.pushCall(this.call());
+ }
+ }
+ }
+ CanvasRenderingContext2DResource.TransformationMatrixMethods.forEach(function(methodName) {
+ var func = methodName === "setTransform" ? this.pushCall_setTransform : null;
+ stateModifyingWrapFunction(methodName, func);
+ });
+ CanvasRenderingContext2DResource.PathMethods.forEach(function(methodName) {
+ var func = methodName === "beginPath" ? this.pushCall_beginPath : null;
+ stateModifyingWrapFunction(methodName, func);
+ });
+ stateModifyingWrapFunction("save", this.pushCall_save);
+ stateModifyingWrapFunction("restore", this.pushCall_restore);
+ stateModifyingWrapFunction("clip");
+
+ CanvasRenderingContext2DResource._wrapFunctions = wrapFunctions;
+ }
+ return wrapFunctions;
+ }
+};
+
+CanvasRenderingContext2DResource.prototype.__proto__ = Resource.prototype;
+
/**
* @constructor
*/
@@ -1942,7 +2170,7 @@ ResourceTrackingManager.prototype = {
/**
* @param {Call} call
*/
- reportCall: function(call)
+ captureCall: function(call)
{
if (!this._capturing)
return;
@@ -1988,8 +2216,18 @@ InjectedScript.prototype = {
{
var resource = Resource.forObject(glContext) || new WebGLRenderingContextResource(glContext, this._constructWebGLReplayContext.bind(this, glContext));
this._manager.registerResource(resource);
- var proxy = resource.proxyObject();
- return proxy;
+ return resource.proxyObject();
+ },
+
+ /**
+ * @param {CanvasRenderingContext2D} context
+ * @return {Object}
+ */
+ wrapCanvas2DContext: function(context)
+ {
+ var resource = Resource.forObject(context) || new CanvasRenderingContext2DResource(context, this._constructCanvas2DReplayContext.bind(this, context));
+ this._manager.registerResource(resource);
+ return resource.proxyObject();
},
captureFrame: function()
@@ -2104,6 +2342,29 @@ InjectedScript.prototype = {
// FIXME: Reset the replay GL state and clear the canvas.
}
return replayContext;
+ },
+
+ /**
+ * @param {CanvasRenderingContext2D} originalContext
+ * @return {CanvasRenderingContext2D}
+ */
+ _constructCanvas2DReplayContext: function(originalContext)
+ {
+ var replayContext = originalContext["__replayContext"];
+ if (!replayContext) {
+ var canvas = originalContext.canvas.cloneNode(true);
+ replayContext = /** @type {CanvasRenderingContext2D} */ Resource.wrappedObject(canvas.getContext("2d"));
+ Object.defineProperty(originalContext, "__replayContext", {
+ value: replayContext,
+ writable: false,
+ enumerable: false,
+ configurable: true
+ });
+ this._replayContext = replayContext;
+ } else {
+ // FIXME: Clear the canvas.
+ }
+ return replayContext;
}
}
diff --git a/Source/WebCore/inspector/Inspector.json b/Source/WebCore/inspector/Inspector.json
index 5c18dad95..21d927c21 100644
--- a/Source/WebCore/inspector/Inspector.json
+++ b/Source/WebCore/inspector/Inspector.json
@@ -1567,6 +1567,7 @@
{ "name": "children", "type": "array", "optional": true, "items": { "$ref": "Node" }, "description": "Child nodes of this node when requested with children." },
{ "name": "attributes", "type": "array", "optional": true, "items": { "type": "string" }, "description": "Attributes of the <code>Element</code> node in the form of flat array <code>[name1, value1, name2, value2]</code>." },
{ "name": "documentURL", "type": "string", "optional": true, "description": "Document URL that <code>Document</code> or <code>FrameOwner</code> node points to." },
+ { "name": "baseURL", "type": "string", "optional": true, "description": "Base URL that <code>Document</code> or <code>FrameOwner</code> node uses for URL completion." },
{ "name": "publicId", "type": "string", "optional": true, "description": "<code>DocumentType</code>'s publicId." },
{ "name": "systemId", "type": "string", "optional": true, "description": "<code>DocumentType</code>'s systemId." },
{ "name": "internalSubset", "type": "string", "optional": true, "description": "<code>DocumentType</code>'s internalSubset." },
@@ -2006,11 +2007,11 @@
"description": "This object identifies a CSS rule in a unique way."
},
{
- "id": "PseudoIdRules",
+ "id": "PseudoIdMatches",
"type": "object",
"properties": [
{ "name": "pseudoId", "type": "integer", "description": "Pseudo style identifier (see <code>enum PseudoId</code> in <code>RenderStyleConstants.h</code>)."},
- { "name": "rules", "type": "array", "items": { "$ref": "CSSRule" }, "description": "CSS rules applicable to the pseudo style."}
+ { "name": "matches", "type": "array", "items": { "$ref": "RuleMatch" }, "description": "Matches of CSS rules applicable to the pseudo style."}
],
"description": "CSS rule collection for a single pseudo style."
},
@@ -2019,11 +2020,30 @@
"type": "object",
"properties": [
{ "name": "inlineStyle", "$ref": "CSSStyle", "optional": true, "description": "The ancestor node's inline style, if any, in the style inheritance chain." },
- { "name": "matchedCSSRules", "type": "array", "items": { "$ref": "CSSRule" }, "description": "CSS rules matching the ancestor node in the style inheritance chain." }
+ { "name": "matchedCSSRules", "type": "array", "items": { "$ref": "RuleMatch" }, "description": "Matches of CSS rules matching the ancestor node in the style inheritance chain." }
],
"description": "CSS rule collection for a single pseudo style."
},
{
+ "id": "RuleMatch",
+ "type": "object",
+ "properties": [
+ { "name": "rule", "$ref": "CSSRule", "description": "CSS rule in the match." },
+ { "name": "matchingSelectors", "type": "array", "items": { "type": "integer" }, "description": "Matching selector indices in the rule's selectorList selectors (0-based)." }
+ ],
+ "description": "Match data for a CSS rule."
+ },
+ {
+ "id": "SelectorList",
+ "type": "object",
+ "properties": [
+ { "name": "selectors", "type": "array", "items": { "type": "string" }, "description": "Selectors in the list." },
+ { "name": "text", "type": "string", "description": "Rule selector text." },
+ { "name": "range", "$ref": "SourceRange", "optional": true, "description": "Rule selector range in the underlying resource (if available)." }
+ ],
+ "description": "Selector list data."
+ },
+ {
"id": "CSSStyleAttribute",
"type": "object",
"properties": [
@@ -2060,12 +2080,11 @@
"type": "object",
"properties": [
{ "name": "ruleId", "$ref": "CSSRuleId", "optional": true, "description": "The CSS rule identifier (absent for user agent stylesheet and user-specified stylesheet rules)."},
- { "name": "selectorText", "type": "string", "description": "Rule selector."},
+ { "name": "selectorList", "$ref": "SelectorList", "description": "Rule selector data." },
{ "name": "sourceURL", "type": "string", "optional": true, "description": "Parent stylesheet resource URL (for regular rules)."},
{ "name": "sourceLine", "type": "integer", "description": "Line ordinal of the rule selector start character in the resource."},
{ "name": "origin", "$ref": "StyleSheetOrigin", "description": "Parent stylesheet's origin."},
{ "name": "style", "$ref": "CSSStyle", "description": "Associated style declaration." },
- { "name": "selectorRange", "$ref": "SourceRange", "optional": true, "description": "The rule selector range in the underlying resource (if available)." },
{ "name": "media", "type": "array", "items": { "$ref": "CSSMedia" }, "optional": true, "description": "Media list array (for rules involving media queries). The array enumerates media queries starting with the innermost one, going outwards." }
],
"description": "CSS rule representation."
@@ -2205,8 +2224,8 @@
{ "name": "includeInherited", "type": "boolean", "optional": true, "description": "Whether to include inherited styles (default: true)." }
],
"returns": [
- { "name": "matchedCSSRules", "type": "array", "items": { "$ref": "CSSRule" }, "optional": true, "description": "CSS rules matching this node, from all applicable stylesheets." },
- { "name": "pseudoElements", "type": "array", "items": { "$ref": "PseudoIdRules" }, "optional": true, "description": "Pseudo style rules for this node." },
+ { "name": "matchedCSSRules", "type": "array", "items": { "$ref": "RuleMatch" }, "optional": true, "description": "CSS rules matching this node, from all applicable stylesheets." },
+ { "name": "pseudoElements", "type": "array", "items": { "$ref": "PseudoIdMatches" }, "optional": true, "description": "Pseudo style matches for this node." },
{ "name": "inherited", "type": "array", "items": { "$ref": "InheritedStyleEntry" }, "optional": true, "description": "A chain of inherited styles (from the immediate node parent up to the DOM tree root)." }
],
"description": "Returns requested styles for a DOM node identified by <code>nodeId</code>."
diff --git a/Source/WebCore/inspector/InspectorCSSAgent.cpp b/Source/WebCore/inspector/InspectorCSSAgent.cpp
index 60ebd9312..bbe88d2c0 100644
--- a/Source/WebCore/inspector/InspectorCSSAgent.cpp
+++ b/Source/WebCore/inspector/InspectorCSSAgent.cpp
@@ -678,7 +678,7 @@ bool InspectorCSSAgent::forcePseudoState(Element* element, CSSSelector::PseudoTy
}
}
-void InspectorCSSAgent::getMatchedStylesForNode(ErrorString* errorString, int nodeId, const bool* includePseudo, const bool* includeInherited, RefPtr<TypeBuilder::Array<TypeBuilder::CSS::CSSRule> >& matchedCSSRules, RefPtr<TypeBuilder::Array<TypeBuilder::CSS::PseudoIdRules> >& pseudoIdRules, RefPtr<TypeBuilder::Array<TypeBuilder::CSS::InheritedStyleEntry> >& inheritedEntries)
+void InspectorCSSAgent::getMatchedStylesForNode(ErrorString* errorString, int nodeId, const bool* includePseudo, const bool* includeInherited, RefPtr<TypeBuilder::Array<TypeBuilder::CSS::RuleMatch> >& matchedCSSRules, RefPtr<TypeBuilder::Array<TypeBuilder::CSS::PseudoIdMatches> >& pseudoIdMatches, RefPtr<TypeBuilder::Array<TypeBuilder::CSS::InheritedStyleEntry> >& inheritedEntries)
{
Element* element = elementForId(errorString, nodeId);
if (!element)
@@ -687,44 +687,44 @@ void InspectorCSSAgent::getMatchedStylesForNode(ErrorString* errorString, int no
// Matched rules.
StyleResolver* styleResolver = element->ownerDocument()->styleResolver();
RefPtr<CSSRuleList> matchedRules = styleResolver->styleRulesForElement(element, StyleResolver::AllCSSRules);
- matchedCSSRules = buildArrayForRuleList(matchedRules.get(), styleResolver);
+ matchedCSSRules = buildArrayForMatchedRuleList(matchedRules.get(), styleResolver, element);
// Pseudo elements.
if (!includePseudo || *includePseudo) {
- RefPtr<TypeBuilder::Array<TypeBuilder::CSS::PseudoIdRules> > pseudoElements = TypeBuilder::Array<TypeBuilder::CSS::PseudoIdRules>::create();
+ RefPtr<TypeBuilder::Array<TypeBuilder::CSS::PseudoIdMatches> > pseudoElements = TypeBuilder::Array<TypeBuilder::CSS::PseudoIdMatches>::create();
for (PseudoId pseudoId = FIRST_PUBLIC_PSEUDOID; pseudoId < AFTER_LAST_INTERNAL_PSEUDOID; pseudoId = static_cast<PseudoId>(pseudoId + 1)) {
RefPtr<CSSRuleList> matchedRules = styleResolver->pseudoStyleRulesForElement(element, pseudoId, StyleResolver::AllCSSRules);
if (matchedRules && matchedRules->length()) {
- RefPtr<TypeBuilder::CSS::PseudoIdRules> pseudoStyles = TypeBuilder::CSS::PseudoIdRules::create()
+ RefPtr<TypeBuilder::CSS::PseudoIdMatches> matches = TypeBuilder::CSS::PseudoIdMatches::create()
.setPseudoId(static_cast<int>(pseudoId))
- .setRules(buildArrayForRuleList(matchedRules.get(), styleResolver));
- pseudoElements->addItem(pseudoStyles.release());
+ .setMatches(buildArrayForMatchedRuleList(matchedRules.get(), styleResolver, element));
+ pseudoElements->addItem(matches.release());
}
}
- pseudoIdRules = pseudoElements.release();
+ pseudoIdMatches = pseudoElements.release();
}
// Inherited styles.
if (!includeInherited || *includeInherited) {
- RefPtr<TypeBuilder::Array<TypeBuilder::CSS::InheritedStyleEntry> > inheritedStyles = TypeBuilder::Array<TypeBuilder::CSS::InheritedStyleEntry>::create();
+ RefPtr<TypeBuilder::Array<TypeBuilder::CSS::InheritedStyleEntry> > entries = TypeBuilder::Array<TypeBuilder::CSS::InheritedStyleEntry>::create();
Element* parentElement = element->parentElement();
while (parentElement) {
- StyleResolver* parentStyleResolver= parentElement->ownerDocument()->styleResolver();
+ StyleResolver* parentStyleResolver = parentElement->ownerDocument()->styleResolver();
RefPtr<CSSRuleList> parentMatchedRules = parentStyleResolver->styleRulesForElement(parentElement, StyleResolver::AllCSSRules);
- RefPtr<TypeBuilder::CSS::InheritedStyleEntry> parentStyle = TypeBuilder::CSS::InheritedStyleEntry::create()
- .setMatchedCSSRules(buildArrayForRuleList(parentMatchedRules.get(), styleResolver));
+ RefPtr<TypeBuilder::CSS::InheritedStyleEntry> entry = TypeBuilder::CSS::InheritedStyleEntry::create()
+ .setMatchedCSSRules(buildArrayForMatchedRuleList(parentMatchedRules.get(), styleResolver, parentElement));
if (parentElement->style() && parentElement->style()->length()) {
InspectorStyleSheetForInlineStyle* styleSheet = asInspectorStyleSheet(parentElement);
if (styleSheet)
- parentStyle->setInlineStyle(styleSheet->buildObjectForStyle(styleSheet->styleForId(InspectorCSSId(styleSheet->id(), 0))));
+ entry->setInlineStyle(styleSheet->buildObjectForStyle(styleSheet->styleForId(InspectorCSSId(styleSheet->id(), 0))));
}
- inheritedStyles->addItem(parentStyle.release());
+ entries->addItem(entry.release());
parentElement = parentElement->parentElement();
}
- inheritedEntries = inheritedStyles.release();
+ inheritedEntries = entries.release();
}
}
@@ -1116,6 +1116,23 @@ TypeBuilder::CSS::StyleSheetOrigin::Enum InspectorCSSAgent::detectOrigin(CSSStyl
return origin;
}
+PassRefPtr<TypeBuilder::CSS::CSSRule> InspectorCSSAgent::buildObjectForRule(CSSStyleRule* rule, StyleResolver* styleResolver)
+{
+ if (!rule)
+ return 0;
+
+ // CSSRules returned by StyleResolver::styleRulesForElement lack parent pointers since that infomation is not cheaply available.
+ // Since the inspector wants to walk the parent chain, we construct the full wrappers here.
+ // FIXME: This could be factored better. StyleResolver::styleRulesForElement should return a StyleRule vector, not a CSSRuleList.
+ if (!rule->parentStyleSheet()) {
+ rule = styleResolver->ensureFullCSSOMWrapperForInspector(rule->styleRule());
+ if (!rule)
+ return 0;
+ }
+ InspectorStyleSheet* inspectorStyleSheet = bindStyleSheet(rule->parentStyleSheet());
+ return inspectorStyleSheet ? inspectorStyleSheet->buildObjectForRule(rule) : 0;
+}
+
PassRefPtr<TypeBuilder::Array<TypeBuilder::CSS::CSSRule> > InspectorCSSAgent::buildArrayForRuleList(CSSRuleList* ruleList, StyleResolver* styleResolver)
{
RefPtr<TypeBuilder::Array<TypeBuilder::CSS::CSSRule> > result = TypeBuilder::Array<TypeBuilder::CSS::CSSRule>::create();
@@ -1124,22 +1141,42 @@ PassRefPtr<TypeBuilder::Array<TypeBuilder::CSS::CSSRule> > InspectorCSSAgent::bu
for (unsigned i = 0, size = ruleList->length(); i < size; ++i) {
CSSStyleRule* rule = asCSSStyleRule(ruleList->item(i));
- if (!rule)
+ RefPtr<TypeBuilder::CSS::CSSRule> ruleObject = buildObjectForRule(rule, styleResolver);
+ if (!ruleObject)
continue;
+ result->addItem(ruleObject);
+ }
+ return result.release();
+}
+
+PassRefPtr<TypeBuilder::Array<TypeBuilder::CSS::RuleMatch> > InspectorCSSAgent::buildArrayForMatchedRuleList(CSSRuleList* ruleList, StyleResolver* styleResolver, Element* element)
+{
+ RefPtr<TypeBuilder::Array<TypeBuilder::CSS::RuleMatch> > result = TypeBuilder::Array<TypeBuilder::CSS::RuleMatch>::create();
+ if (!ruleList)
+ return result.release();
- // CSSRules returned by StyleResolver::styleRulesForElement lack parent pointers since that infomation is not cheaply available.
- // Since the inspector wants to walk the parent chain, we construct the full wrappers here.
- // FIXME: This could be factored better. StyleResolver::styleRulesForElement should return a StyleRule vector, not a CSSRuleList.
- if (!rule->parentStyleSheet()) {
- rule = styleResolver->ensureFullCSSOMWrapperForInspector(rule->styleRule());
- if (!rule)
- continue;
+ for (unsigned i = 0, size = ruleList->length(); i < size; ++i) {
+ CSSStyleRule* rule = asCSSStyleRule(ruleList->item(i));
+ RefPtr<TypeBuilder::CSS::CSSRule> ruleObject = buildObjectForRule(rule, styleResolver);
+ if (!ruleObject)
+ continue;
+ RefPtr<TypeBuilder::Array<int> > matchingSelectors = TypeBuilder::Array<int>::create();
+ const CSSSelectorList& selectorList = rule->styleRule()->selectorList();
+ long index = 0;
+ for (CSSSelector* selector = selectorList.first(); selector; selector = CSSSelectorList::next(selector)) {
+ ExceptionCode ec;
+ bool matched = element->webkitMatchesSelector(selector->selectorText(), ec);
+ if (matched)
+ matchingSelectors->addItem(index);
+ ++index;
}
- InspectorStyleSheet* inspectorStyleSheet = bindStyleSheet(rule->parentStyleSheet());
- if (inspectorStyleSheet)
- result->addItem(inspectorStyleSheet->buildObjectForRule(rule));
+ RefPtr<TypeBuilder::CSS::RuleMatch> match = TypeBuilder::CSS::RuleMatch::create()
+ .setRule(ruleObject)
+ .setMatchingSelectors(matchingSelectors);
+ result->addItem(match);
}
- return result.release();
+
+ return result;
}
PassRefPtr<TypeBuilder::CSS::CSSStyle> InspectorCSSAgent::buildObjectForAttributesStyle(Element* element)
diff --git a/Source/WebCore/inspector/InspectorCSSAgent.h b/Source/WebCore/inspector/InspectorCSSAgent.h
index c9aa3a48e..3ea451c2c 100644
--- a/Source/WebCore/inspector/InspectorCSSAgent.h
+++ b/Source/WebCore/inspector/InspectorCSSAgent.h
@@ -107,7 +107,7 @@ public:
virtual void getComputedStyleForNode(ErrorString*, int nodeId, RefPtr<TypeBuilder::Array<TypeBuilder::CSS::CSSComputedStyleProperty> >&);
virtual void getInlineStylesForNode(ErrorString*, int nodeId, RefPtr<TypeBuilder::CSS::CSSStyle>& inlineStyle, RefPtr<TypeBuilder::CSS::CSSStyle>& attributes);
- virtual void getMatchedStylesForNode(ErrorString*, int nodeId, const bool* includePseudo, const bool* includeInherited, RefPtr<TypeBuilder::Array<TypeBuilder::CSS::CSSRule> >& matchedCSSRules, RefPtr<TypeBuilder::Array<TypeBuilder::CSS::PseudoIdRules> >& pseudoRules, RefPtr<TypeBuilder::Array<TypeBuilder::CSS::InheritedStyleEntry> >& inheritedEntries);
+ virtual void getMatchedStylesForNode(ErrorString*, int nodeId, const bool* includePseudo, const bool* includeInherited, RefPtr<TypeBuilder::Array<TypeBuilder::CSS::RuleMatch> >& matchedCSSRules, RefPtr<TypeBuilder::Array<TypeBuilder::CSS::PseudoIdMatches> >& pseudoIdMatches, RefPtr<TypeBuilder::Array<TypeBuilder::CSS::InheritedStyleEntry> >& inheritedEntries);
virtual void getAllStyleSheets(ErrorString*, RefPtr<TypeBuilder::Array<TypeBuilder::CSS::CSSStyleSheetHeader> >& styleSheetInfos);
virtual void getStyleSheet(ErrorString*, const String& styleSheetId, RefPtr<TypeBuilder::CSS::CSSStyleSheetBody>& result);
virtual void getStyleSheetText(ErrorString*, const String& styleSheetId, String* result);
@@ -156,7 +156,9 @@ private:
InspectorStyleSheet* assertStyleSheetForId(ErrorString*, const String&);
TypeBuilder::CSS::StyleSheetOrigin::Enum detectOrigin(CSSStyleSheet* pageStyleSheet, Document* ownerDocument);
+ PassRefPtr<TypeBuilder::CSS::CSSRule> buildObjectForRule(CSSStyleRule*, StyleResolver*);
PassRefPtr<TypeBuilder::Array<TypeBuilder::CSS::CSSRule> > buildArrayForRuleList(CSSRuleList*, StyleResolver*);
+ PassRefPtr<TypeBuilder::Array<TypeBuilder::CSS::RuleMatch> > buildArrayForMatchedRuleList(CSSRuleList*, StyleResolver*, Element*);
PassRefPtr<TypeBuilder::CSS::CSSStyle> buildObjectForAttributesStyle(Element*);
PassRefPtr<TypeBuilder::Array<TypeBuilder::CSS::Region> > buildArrayForRegions(ErrorString*, PassRefPtr<NodeList>, int documentNodeId);
PassRefPtr<TypeBuilder::CSS::NamedFlow> buildObjectForNamedFlow(ErrorString*, WebKitNamedFlow*, int documentNodeId);
diff --git a/Source/WebCore/inspector/InspectorCanvasAgent.cpp b/Source/WebCore/inspector/InspectorCanvasAgent.cpp
index dff293845..10bef0cd2 100644
--- a/Source/WebCore/inspector/InspectorCanvasAgent.cpp
+++ b/Source/WebCore/inspector/InspectorCanvasAgent.cpp
@@ -55,14 +55,11 @@ InspectorCanvasAgent::InspectorCanvasAgent(InstrumentingAgents* instrumentingAge
, m_inspectedPage(page)
, m_injectedScriptManager(injectedScriptManager)
, m_frontend(0)
- , m_enabled(false)
{
- m_instrumentingAgents->setInspectorCanvasAgent(this);
}
InspectorCanvasAgent::~InspectorCanvasAgent()
{
- m_instrumentingAgents->setInspectorCanvasAgent(0);
}
void InspectorCanvasAgent::setFrontend(InspectorFrontend* frontend)
@@ -79,23 +76,22 @@ void InspectorCanvasAgent::clearFrontend()
void InspectorCanvasAgent::restore()
{
- m_enabled = m_state->getBoolean(CanvasAgentState::canvasAgentEnabled);
+ if (m_state->getBoolean(CanvasAgentState::canvasAgentEnabled)) {
+ ErrorString error;
+ enable(&error);
+ }
}
void InspectorCanvasAgent::enable(ErrorString*)
{
- if (m_enabled)
- return;
- m_enabled = true;
- m_state->setBoolean(CanvasAgentState::canvasAgentEnabled, m_enabled);
+ m_state->setBoolean(CanvasAgentState::canvasAgentEnabled, true);
+ m_instrumentingAgents->setInspectorCanvasAgent(this);
}
void InspectorCanvasAgent::disable(ErrorString*)
{
- if (!m_enabled)
- return;
- m_enabled = false;
- m_state->setBoolean(CanvasAgentState::canvasAgentEnabled, m_enabled);
+ m_instrumentingAgents->setInspectorCanvasAgent(0);
+ m_state->setBoolean(CanvasAgentState::canvasAgentEnabled, false);
}
void InspectorCanvasAgent::dropTraceLog(ErrorString* errorString, const String& traceLogId)
@@ -130,6 +126,20 @@ void InspectorCanvasAgent::replayTraceLog(ErrorString* errorString, const String
module.replayTraceLog(errorString, traceLogId, stepNo, result);
}
+ScriptObject InspectorCanvasAgent::wrapCanvas2DRenderingContextForInstrumentation(const ScriptObject& context)
+{
+ if (context.hasNoValue()) {
+ ASSERT_NOT_REACHED();
+ return ScriptObject();
+ }
+ InjectedScriptCanvasModule module = InjectedScriptCanvasModule::moduleForState(m_injectedScriptManager, context.scriptState());
+ if (module.hasNoValue()) {
+ ASSERT_NOT_REACHED();
+ return ScriptObject();
+ }
+ return module.wrapCanvas2DContext(context);
+}
+
#if ENABLE(WEBGL)
ScriptObject InspectorCanvasAgent::wrapWebGLRenderingContextForInstrumentation(const ScriptObject& glContext)
{
diff --git a/Source/WebCore/inspector/InspectorCanvasAgent.h b/Source/WebCore/inspector/InspectorCanvasAgent.h
index f460c6410..ef4cbd58c 100644
--- a/Source/WebCore/inspector/InspectorCanvasAgent.h
+++ b/Source/WebCore/inspector/InspectorCanvasAgent.h
@@ -64,8 +64,7 @@ public:
virtual void clearFrontend();
virtual void restore();
- bool enabled() { return m_enabled; }
-
+ ScriptObject wrapCanvas2DRenderingContextForInstrumentation(const ScriptObject&);
#if ENABLE(WEBGL)
ScriptObject wrapWebGLRenderingContextForInstrumentation(const ScriptObject&);
#endif
@@ -90,7 +89,6 @@ private:
Page* m_inspectedPage;
InjectedScriptManager* m_injectedScriptManager;
InspectorFrontend::Canvas* m_frontend;
- bool m_enabled;
};
} // namespace WebCore
diff --git a/Source/WebCore/inspector/InspectorCanvasInstrumentation.h b/Source/WebCore/inspector/InspectorCanvasInstrumentation.h
index 5904b8789..2c2bea9d0 100644
--- a/Source/WebCore/inspector/InspectorCanvasInstrumentation.h
+++ b/Source/WebCore/inspector/InspectorCanvasInstrumentation.h
@@ -38,13 +38,23 @@
namespace WebCore {
+ScriptObject InspectorInstrumentation::wrapCanvas2DRenderingContextForInstrumentation(Document* document, const ScriptObject& context)
+{
+#if ENABLE(INSPECTOR)
+ if (InstrumentingAgents* instrumentingAgents = instrumentingAgentsForDocument(document)) {
+ if (InspectorCanvasAgent* canvasAgent = instrumentingAgents->inspectorCanvasAgent())
+ return canvasAgent->wrapCanvas2DRenderingContextForInstrumentation(context);
+ }
+#endif
+ return ScriptObject();
+}
+
#if ENABLE(WEBGL)
ScriptObject InspectorInstrumentation::wrapWebGLRenderingContextForInstrumentation(Document* document, const ScriptObject& glContext)
{
#if ENABLE(INSPECTOR)
if (InstrumentingAgents* instrumentingAgents = instrumentingAgentsForDocument(document)) {
- InspectorCanvasAgent* canvasAgent = instrumentingAgents->inspectorCanvasAgent();
- if (canvasAgent && canvasAgent->enabled())
+ if (InspectorCanvasAgent* canvasAgent = instrumentingAgents->inspectorCanvasAgent())
return canvasAgent->wrapWebGLRenderingContextForInstrumentation(glContext);
}
#endif
diff --git a/Source/WebCore/inspector/InspectorClient.h b/Source/WebCore/inspector/InspectorClient.h
index fc8d0247f..e8d2659d5 100644
--- a/Source/WebCore/inspector/InspectorClient.h
+++ b/Source/WebCore/inspector/InspectorClient.h
@@ -71,7 +71,7 @@ public:
virtual bool supportsFrameInstrumentation() { return false; }
- bool doDispatchMessageOnFrontendPage(Page* frontendPage, const String& message);
+ static bool doDispatchMessageOnFrontendPage(Page* frontendPage, const String& message);
};
} // namespace WebCore
diff --git a/Source/WebCore/inspector/InspectorDOMAgent.cpp b/Source/WebCore/inspector/InspectorDOMAgent.cpp
index 4491487b3..a533e5253 100644
--- a/Source/WebCore/inspector/InspectorDOMAgent.cpp
+++ b/Source/WebCore/inspector/InspectorDOMAgent.cpp
@@ -1176,6 +1176,11 @@ String InspectorDOMAgent::documentURLString(Document* document)
return document->url().string();
}
+static String documentBaseURLString(Document* document)
+{
+ return document->completeURL("").string();
+}
+
PassRefPtr<TypeBuilder::DOM::Node> InspectorDOMAgent::buildObjectForNode(Node* node, int depth, NodeToIdMap* nodesMap)
{
int id = bind(node, nodesMap);
@@ -1240,6 +1245,7 @@ PassRefPtr<TypeBuilder::DOM::Node> InspectorDOMAgent::buildObjectForNode(Node* n
} else if (node->isDocumentNode()) {
Document* document = static_cast<Document*>(node);
value->setDocumentURL(documentURLString(document));
+ value->setBaseURL(documentBaseURLString(document));
value->setXmlVersion(document->xmlVersion());
} else if (node->nodeType() == Node::DOCUMENT_TYPE_NODE) {
DocumentType* docType = static_cast<DocumentType*>(node);
diff --git a/Source/WebCore/inspector/InspectorInstrumentation.h b/Source/WebCore/inspector/InspectorInstrumentation.h
index 217d98d02..400c443b8 100644
--- a/Source/WebCore/inspector/InspectorInstrumentation.h
+++ b/Source/WebCore/inspector/InspectorInstrumentation.h
@@ -251,6 +251,7 @@ public:
static void didReceiveWebSocketFrameError(Document*, unsigned long identifier, const String& errorMessage);
#endif
+ static ScriptObject wrapCanvas2DRenderingContextForInstrumentation(Document*, const ScriptObject&);
#if ENABLE(WEBGL)
static ScriptObject wrapWebGLRenderingContextForInstrumentation(Document*, const ScriptObject&);
#endif
diff --git a/Source/WebCore/inspector/InspectorOverlay.cpp b/Source/WebCore/inspector/InspectorOverlay.cpp
index 5241545e1..7a87b0f0e 100644
--- a/Source/WebCore/inspector/InspectorOverlay.cpp
+++ b/Source/WebCore/inspector/InspectorOverlay.cpp
@@ -271,6 +271,9 @@ void InspectorOverlay::update()
}
FrameView* view = m_page->mainFrame()->view();
+ if (!view)
+ return;
+
FrameView* overlayView = overlayPage()->mainFrame()->view();
IntRect visibleRect = enclosingIntRect(view->visibleContentRect());
overlayView->resize(visibleRect.width(), visibleRect.height());
diff --git a/Source/WebCore/inspector/InspectorPageAgent.cpp b/Source/WebCore/inspector/InspectorPageAgent.cpp
index fa23aaaf9..ef39e6f13 100644
--- a/Source/WebCore/inspector/InspectorPageAgent.cpp
+++ b/Source/WebCore/inspector/InspectorPageAgent.cpp
@@ -349,13 +349,6 @@ void InspectorPageAgent::restore()
ErrorString error;
enable(&error);
- // When restoring the agent, override values are restored into the FrameView.
- int width = static_cast<int>(m_state->getLong(PageAgentState::pageAgentScreenWidthOverride));
- int height = static_cast<int>(m_state->getLong(PageAgentState::pageAgentScreenHeightOverride));
- double fontScaleFactor = m_state->getDouble(PageAgentState::pageAgentFontScaleFactorOverride);
- bool fitWindow = m_state->getBoolean(PageAgentState::pageAgentFitWindow);
- updateViewMetrics(width, height, fontScaleFactor, fitWindow);
-
if (m_inspectorAgent->didCommitLoadFired())
frameNavigated(m_page->mainFrame()->loader()->documentLoader());
#if ENABLE(TOUCH_EVENTS)
diff --git a/Source/WebCore/inspector/InspectorProfilerAgent.cpp b/Source/WebCore/inspector/InspectorProfilerAgent.cpp
index 4540aa7cd..9c864c5dd 100644
--- a/Source/WebCore/inspector/InspectorProfilerAgent.cpp
+++ b/Source/WebCore/inspector/InspectorProfilerAgent.cpp
@@ -48,6 +48,7 @@
#include "ScriptObject.h"
#include "ScriptProfile.h"
#include "ScriptProfiler.h"
+#include "WorkerScriptDebugServer.h"
#include <wtf/OwnPtr.h>
#include <wtf/text/StringConcatenate.h>
@@ -70,6 +71,11 @@ public:
virtual ~PageProfilerAgent() { }
private:
+ virtual void recompileScript()
+ {
+ PageScriptDebugServer::shared().recompileAllJSFunctionsSoon();
+ }
+
virtual void startProfiling(const String& title)
{
ScriptProfiler::startForPage(m_inspectedPage, title);
@@ -88,7 +94,6 @@ PassOwnPtr<InspectorProfilerAgent> InspectorProfilerAgent::create(InstrumentingA
return adoptPtr(new PageProfilerAgent(instrumentingAgents, consoleAgent, inspectedPage, inspectorState, injectedScriptManager));
}
-
#if ENABLE(WORKERS)
class WorkerProfilerAgent : public InspectorProfilerAgent {
public:
@@ -97,6 +102,8 @@ public:
virtual ~WorkerProfilerAgent() { }
private:
+ virtual void recompileScript() { }
+
virtual void startProfiling(const String& title)
{
ScriptProfiler::startForWorkerContext(m_workerContext, title);
@@ -222,7 +229,7 @@ void InspectorProfilerAgent::disable()
return;
m_enabled = false;
m_headersRequested = false;
- PageScriptDebugServer::shared().recompileAllJSFunctionsSoon();
+ recompileScript();
}
void InspectorProfilerAgent::enable(bool skipRecompile)
@@ -231,7 +238,7 @@ void InspectorProfilerAgent::enable(bool skipRecompile)
return;
m_enabled = true;
if (!skipRecompile)
- PageScriptDebugServer::shared().recompileAllJSFunctionsSoon();
+ recompileScript();
}
String InspectorProfilerAgent::getCurrentUserInitiatedProfileName(bool incrementProfileNumber)
diff --git a/Source/WebCore/inspector/InspectorProfilerAgent.h b/Source/WebCore/inspector/InspectorProfilerAgent.h
index c35536fae..d548bbfa4 100644
--- a/Source/WebCore/inspector/InspectorProfilerAgent.h
+++ b/Source/WebCore/inspector/InspectorProfilerAgent.h
@@ -73,6 +73,7 @@ public:
void resetState();
virtual void causesRecompilation(ErrorString*, bool*);
+ virtual void recompileScript() = 0;
virtual void isSampling(ErrorString*, bool*);
virtual void hasHeapProfiler(ErrorString*, bool*);
diff --git a/Source/WebCore/inspector/InspectorStyleSheet.cpp b/Source/WebCore/inspector/InspectorStyleSheet.cpp
index 2de8d9cba..5b94de6c1 100644
--- a/Source/WebCore/inspector/InspectorStyleSheet.cpp
+++ b/Source/WebCore/inspector/InspectorStyleSheet.cpp
@@ -911,6 +911,25 @@ PassRefPtr<TypeBuilder::CSS::CSSStyleSheetHeader> InspectorStyleSheet::buildObje
return result.release();
}
+PassRefPtr<TypeBuilder::CSS::SelectorList> InspectorStyleSheet::buildObjectForSelectorList(CSSStyleRule* rule)
+{
+ RefPtr<TypeBuilder::Array<String> > selectors = TypeBuilder::Array<String>::create();
+ const CSSSelectorList& selectorList = rule->styleRule()->selectorList();
+ for (CSSSelector* selector = selectorList.first(); selector; selector = CSSSelectorList::next(selector))
+ selectors->addItem(selector->selectorText());
+
+ RefPtr<TypeBuilder::CSS::SelectorList> result = TypeBuilder::CSS::SelectorList::create()
+ .setSelectors(selectors)
+ .setText(rule->selectorText());
+
+ RefPtr<CSSRuleSourceData> sourceData;
+ if (ensureParsedDataReady())
+ sourceData = ruleSourceDataFor(rule->style());
+ if (sourceData)
+ result->setRange(buildSourceRangeObject(sourceData->ruleHeaderRange));
+ return result.release();
+}
+
PassRefPtr<TypeBuilder::CSS::CSSRule> InspectorStyleSheet::buildObjectForRule(CSSStyleRule* rule)
{
CSSStyleSheet* styleSheet = pageStyleSheet();
@@ -918,7 +937,7 @@ PassRefPtr<TypeBuilder::CSS::CSSRule> InspectorStyleSheet::buildObjectForRule(CS
return 0;
RefPtr<TypeBuilder::CSS::CSSRule> result = TypeBuilder::CSS::CSSRule::create()
- .setSelectorText(rule->selectorText())
+ .setSelectorList(buildObjectForSelectorList(rule))
.setSourceLine(rule->styleRule()->sourceLine())
.setOrigin(m_origin)
.setStyle(buildObjectForStyle(rule->style()));
@@ -933,12 +952,6 @@ PassRefPtr<TypeBuilder::CSS::CSSRule> InspectorStyleSheet::buildObjectForRule(CS
result->setRuleId(id.asProtocolValue<TypeBuilder::CSS::CSSRuleId>());
}
- RefPtr<CSSRuleSourceData> sourceData;
- if (ensureParsedDataReady())
- sourceData = ruleSourceDataFor(rule->style());
- if (sourceData)
- result->setSelectorRange(buildSourceRangeObject(sourceData->ruleHeaderRange));
-
RefPtr<Array<TypeBuilder::CSS::CSSMedia> > mediaArray = Array<TypeBuilder::CSS::CSSMedia>::create();
fillMediaListChain(rule, mediaArray.get());
diff --git a/Source/WebCore/inspector/InspectorStyleSheet.h b/Source/WebCore/inspector/InspectorStyleSheet.h
index d426d579f..d8d4e481d 100644
--- a/Source/WebCore/inspector/InspectorStyleSheet.h
+++ b/Source/WebCore/inspector/InspectorStyleSheet.h
@@ -234,6 +234,7 @@ private:
bool resourceStyleSheetText(String* result) const;
bool inlineStyleSheetText(String* result) const;
PassRefPtr<TypeBuilder::Array<TypeBuilder::CSS::CSSRule> > buildArrayForRuleList(CSSRuleList*);
+ PassRefPtr<TypeBuilder::CSS::SelectorList> buildObjectForSelectorList(CSSStyleRule*);
InspectorPageAgent* m_pageAgent;
String m_id;
diff --git a/Source/WebCore/inspector/front-end/AuditRules.js b/Source/WebCore/inspector/front-end/AuditRules.js
index e91f27064..14b59ac47 100644
--- a/Source/WebCore/inspector/front-end/AuditRules.js
+++ b/Source/WebCore/inspector/front-end/AuditRules.js
@@ -755,8 +755,8 @@ WebInspector.AuditRules.ImageDimensionsRule.prototype = {
var src = node.getAttribute("src");
if (!src.asParsedURL()) {
for (var frameOwnerCandidate = node; frameOwnerCandidate; frameOwnerCandidate = frameOwnerCandidate.parentNode) {
- if (frameOwnerCandidate.documentURL) {
- var completeSrc = WebInspector.ParsedURL.completeURL(frameOwnerCandidate.documentURL, src);
+ if (frameOwnerCandidate.baseURL) {
+ var completeSrc = WebInspector.ParsedURL.completeURL(frameOwnerCandidate.baseURL, src);
break;
}
}
@@ -902,7 +902,7 @@ WebInspector.AuditRules.CssInHeadRule.prototype = {
var externalStylesheetHrefs = [];
for (var j = 0; j < externalStylesheetNodeIds.length; ++j) {
var linkNode = WebInspector.domAgent.nodeForId(externalStylesheetNodeIds[j]);
- var completeHref = WebInspector.ParsedURL.completeURL(linkNode.ownerDocument.documentURL, linkNode.getAttribute("href"));
+ var completeHref = WebInspector.ParsedURL.completeURL(linkNode.ownerDocument.baseURL, linkNode.getAttribute("href"));
externalStylesheetHrefs.push(completeHref || "<empty>");
}
urlToViolationsArray[root.documentURL] = [inlineStyleNodeIds.length, externalStylesheetHrefs];
@@ -989,7 +989,7 @@ WebInspector.AuditRules.StylesScriptsOrderRule.prototype = {
var lateStyleUrls = [];
for (var i = 0; i < lateStyleIds.length; ++i) {
var lateStyleNode = WebInspector.domAgent.nodeForId(lateStyleIds[i]);
- var completeHref = WebInspector.ParsedURL.completeURL(lateStyleNode.ownerDocument.documentURL, lateStyleNode.getAttribute("href"));
+ var completeHref = WebInspector.ParsedURL.completeURL(lateStyleNode.ownerDocument.baseURL, lateStyleNode.getAttribute("href"));
lateStyleUrls.push(completeHref || "<empty>");
}
result = [ lateStyleUrls, cssBeforeInlineCount ];
diff --git a/Source/WebCore/inspector/front-end/CSSStyleModel.js b/Source/WebCore/inspector/front-end/CSSStyleModel.js
index 6e99dac82..e071f60fa 100644
--- a/Source/WebCore/inspector/front-end/CSSStyleModel.js
+++ b/Source/WebCore/inspector/front-end/CSSStyleModel.js
@@ -56,6 +56,17 @@ WebInspector.CSSStyleModel.parseRuleArrayPayload = function(ruleArray)
return result;
}
+/**
+ * @param {Array.<CSSAgent.RuleMatch>} matchArray
+ */
+WebInspector.CSSStyleModel.parseRuleMatchArrayPayload = function(matchArray)
+{
+ var result = [];
+ for (var i = 0; i < matchArray.length; ++i)
+ result.push(WebInspector.CSSRule.parsePayload(matchArray[i].rule, matchArray[i].matchingSelectors));
+ return result;
+}
+
WebInspector.CSSStyleModel.Events = {
StyleSheetChanged: "StyleSheetChanged",
MediaQueryResultChanged: "MediaQueryResultChanged",
@@ -90,13 +101,13 @@ WebInspector.CSSStyleModel.prototype = {
var result = {};
if (matchedPayload)
- result.matchedCSSRules = WebInspector.CSSStyleModel.parseRuleArrayPayload(matchedPayload);
+ result.matchedCSSRules = WebInspector.CSSStyleModel.parseRuleMatchArrayPayload(matchedPayload);
if (pseudoPayload) {
result.pseudoElements = [];
for (var i = 0; i < pseudoPayload.length; ++i) {
var entryPayload = pseudoPayload[i];
- result.pseudoElements.push({ pseudoId: entryPayload.pseudoId, rules: WebInspector.CSSStyleModel.parseRuleArrayPayload(entryPayload.rules) });
+ result.pseudoElements.push({ pseudoId: entryPayload.pseudoId, rules: WebInspector.CSSStyleModel.parseRuleMatchArrayPayload(entryPayload.matches) });
}
}
@@ -108,7 +119,7 @@ WebInspector.CSSStyleModel.prototype = {
if (entryPayload.inlineStyle)
entry.inlineStyle = WebInspector.CSSStyleDeclaration.parsePayload(entryPayload.inlineStyle);
if (entryPayload.matchedCSSRules)
- entry.matchedCSSRules = WebInspector.CSSStyleModel.parseRuleArrayPayload(entryPayload.matchedCSSRules);
+ entry.matchedCSSRules = WebInspector.CSSStyleModel.parseRuleMatchArrayPayload(entryPayload.matchedCSSRules);
result.inherited.push(entry);
}
}
@@ -724,11 +735,16 @@ WebInspector.CSSStyleDeclaration.prototype = {
/**
* @constructor
* @param {CSSAgent.CSSRule} payload
+ * @param {Array.<number>=} matchingSelectors
*/
-WebInspector.CSSRule = function(payload)
+WebInspector.CSSRule = function(payload, matchingSelectors)
{
this.id = payload.ruleId;
- this.selectorText = payload.selectorText;
+ if (matchingSelectors)
+ this.matchingSelectors = matchingSelectors;
+ this.selectors = payload.selectorList.selectors;
+ this.selectorText = payload.selectorList.text;
+ this.selectorRange = payload.selectorList.range;
this.sourceLine = payload.sourceLine;
this.sourceURL = payload.sourceURL;
if (payload.sourceURL)
@@ -736,18 +752,18 @@ WebInspector.CSSRule = function(payload)
this.origin = payload.origin;
this.style = WebInspector.CSSStyleDeclaration.parsePayload(payload.style);
this.style.parentRule = this;
- this.selectorRange = payload.selectorRange;
if (payload.media)
this.media = WebInspector.CSSMedia.parseMediaArrayPayload(payload.media);
}
/**
* @param {CSSAgent.CSSRule} payload
+ * @param {Array.<number>=} matchingIndices
* @return {WebInspector.CSSRule}
*/
-WebInspector.CSSRule.parsePayload = function(payload)
+WebInspector.CSSRule.parsePayload = function(payload, matchingIndices)
{
- return new WebInspector.CSSRule(payload);
+ return new WebInspector.CSSRule(payload, matchingIndices);
}
WebInspector.CSSRule.prototype = {
diff --git a/Source/WebCore/inspector/front-end/DOMAgent.js b/Source/WebCore/inspector/front-end/DOMAgent.js
index 811fd2e6d..5f4f06162 100644
--- a/Source/WebCore/inspector/front-end/DOMAgent.js
+++ b/Source/WebCore/inspector/front-end/DOMAgent.js
@@ -747,8 +747,8 @@ WebInspector.DOMNode.prototype = {
if (!url)
return url;
for (var frameOwnerCandidate = this; frameOwnerCandidate; frameOwnerCandidate = frameOwnerCandidate.parentNode) {
- if (frameOwnerCandidate.documentURL)
- return WebInspector.ParsedURL.completeURL(frameOwnerCandidate.documentURL, url);
+ if (frameOwnerCandidate.baseURL)
+ return WebInspector.ParsedURL.completeURL(frameOwnerCandidate.baseURL, url);
}
return null;
}
@@ -764,6 +764,7 @@ WebInspector.DOMDocument = function(domAgent, payload)
{
WebInspector.DOMNode.call(this, domAgent, this, false, payload);
this.documentURL = payload.documentURL || "";
+ this.baseURL = payload.baseURL;
this.xmlVersion = payload.xmlVersion;
this._listeners = {};
}
diff --git a/Source/WebCore/inspector/front-end/DefaultTextEditor.js b/Source/WebCore/inspector/front-end/DefaultTextEditor.js
index f90b902e3..69c87ce12 100644
--- a/Source/WebCore/inspector/front-end/DefaultTextEditor.js
+++ b/Source/WebCore/inspector/front-end/DefaultTextEditor.js
@@ -1863,10 +1863,21 @@ WebInspector.TextEditorMainPanel.prototype = {
if (!highlight)
return;
- lineRow.removeChildren();
+ var decorationsElement = lineRow.decorationsElement;
+ if (!decorationsElement)
+ lineRow.removeChildren();
+ else {
+ while (true) {
+ var child = lineRow.firstChild;
+ if (!child || child === decorationsElement)
+ break;
+ lineRow.removeChild(child);
+ }
+ }
+
var line = this._textModel.line(lineNumber);
if (!line)
- lineRow.appendChild(document.createElement("br"));
+ lineRow.insertBefore(document.createElement("br"), decorationsElement);
var plainTextStart = -1;
for (var j = 0; j < line.length;) {
@@ -1883,21 +1894,19 @@ WebInspector.TextEditorMainPanel.prototype = {
j++;
} else {
if (plainTextStart !== -1) {
- this._appendTextNode(lineRow, line.substring(plainTextStart, j));
+ this._insertTextNodeBefore(lineRow, decorationsElement, line.substring(plainTextStart, j));
plainTextStart = -1;
--this._paintLinesOperationsCredit;
}
- this._appendSpan(lineRow, line.substring(j, j + attribute.length), attribute.tokenType);
+ this._insertSpanBefore(lineRow, decorationsElement, line.substring(j, j + attribute.length), attribute.tokenType);
j += attribute.length;
--this._paintLinesOperationsCredit;
}
}
if (plainTextStart !== -1) {
- this._appendTextNode(lineRow, line.substring(plainTextStart, line.length));
+ this._insertTextNodeBefore(lineRow, decorationsElement, line.substring(plainTextStart, line.length));
--this._paintLinesOperationsCredit;
}
- if (lineRow.decorationsElement)
- lineRow.appendChild(lineRow.decorationsElement);
} finally {
if (this._rangeToMark && this._rangeToMark.startLine === lineNumber)
this._markedRangeElement = WebInspector.highlightSearchResult(lineRow, this._rangeToMark.startColumn, this._rangeToMark.endColumn - this._rangeToMark.startColumn);
@@ -2050,20 +2059,21 @@ WebInspector.TextEditorMainPanel.prototype = {
/**
* @param {Element} element
+ * @param {Element} oldChild
* @param {string} content
* @param {string} className
*/
- _appendSpan: function(element, content, className)
+ _insertSpanBefore: function(element, oldChild, content, className)
{
if (className === "html-resource-link" || className === "html-external-link") {
- element.appendChild(this._createLink(content, className === "html-external-link"));
+ element.insertBefore(this._createLink(content, className === "html-external-link"), oldChild);
return;
}
var span = this._cachedSpans.pop() || document.createElement("span");
span.className = "webkit-" + className;
span.textContent = content;
- element.appendChild(span);
+ element.insertBefore(span, oldChild);
if (!("spans" in element))
element.spans = [];
element.spans.push(span);
@@ -2071,16 +2081,17 @@ WebInspector.TextEditorMainPanel.prototype = {
/**
* @param {Element} element
+ * @param {Element} oldChild
* @param {string} text
*/
- _appendTextNode: function(element, text)
+ _insertTextNodeBefore: function(element, oldChild, text)
{
var textNode = this._cachedTextNodes.pop();
if (textNode)
textNode.nodeValue = text;
else
textNode = document.createTextNode(text);
- element.appendChild(textNode);
+ element.insertBefore(textNode, oldChild);
if (!("textNodes" in element))
element.textNodes = [];
element.textNodes.push(textNode);
diff --git a/Source/WebCore/inspector/front-end/FilteredItemSelectionDialog.js b/Source/WebCore/inspector/front-end/FilteredItemSelectionDialog.js
index e086dadaf..41340a894 100644
--- a/Source/WebCore/inspector/front-end/FilteredItemSelectionDialog.js
+++ b/Source/WebCore/inspector/front-end/FilteredItemSelectionDialog.js
@@ -192,23 +192,17 @@ WebInspector.FilteredItemSelectionDialog.prototype = {
*/
_innerCreateSearchRegExp: function(query, isGlobal)
{
- query = query ? query.trim() : query;
if (!query)
return new RegExp(".*");
+ query = query.trim();
var ignoreCase = (query === query.toLowerCase());
-
- const toEscape = "^[]{}()\\.$*+?|";
-
- var regExpString = "";
- for (var i = 0; i < query.length; ++i) {
- var c = query.charAt(i);
- if (toEscape.indexOf(c) !== -1)
- c = "\\" + c;
- if (i)
- regExpString += "[^" + c + "]*";
- regExpString += c;
- }
+ var regExpString = query.escapeForRegExp().replace(/\\\*/g, ".*").replace(/\\\?/g, ".")
+ if (ignoreCase)
+ regExpString = regExpString.replace(/(?!^)(\\\.|[_:-])/g, "[^._:-]*$1");
+ else
+ regExpString = regExpString.replace(/(?!^)(\\\.|[A-Z_:-])/g, "[^.A-Z_:-]*$1");
+ regExpString = "^" + "[^a-zA-Z0-9]*" + regExpString;
return new RegExp(regExpString, (ignoreCase ? "i" : "") + (isGlobal ? "g" : ""));
},
@@ -393,7 +387,7 @@ WebInspector.FilteredItemSelectionDialog.prototype = {
var ranges = [];
var match;
- while ((match = regex.exec(key)) !== null) {
+ while ((match = regex.exec(key)) !== null && match[0]) {
ranges.push({ offset: match.index, length: regex.lastIndex - match.index });
}
diff --git a/Source/WebCore/inspector/front-end/InspectorFrontendAPI.js b/Source/WebCore/inspector/front-end/InspectorFrontendAPI.js
index bab529ef0..06363986e 100644
--- a/Source/WebCore/inspector/front-end/InspectorFrontendAPI.js
+++ b/Source/WebCore/inspector/front-end/InspectorFrontendAPI.js
@@ -101,7 +101,7 @@ InspectorFrontendAPI = {
enterInspectElementMode: function()
{
- WebInspector.panel("elements").toggleSearchingForNode();
+ WebInspector.toggleSearchingForNode();
},
savedURL: function(url)
diff --git a/Source/WebCore/inspector/front-end/ObjectPropertiesSection.js b/Source/WebCore/inspector/front-end/ObjectPropertiesSection.js
index e9a097045..c58ff53fe 100644
--- a/Source/WebCore/inspector/front-end/ObjectPropertiesSection.js
+++ b/Source/WebCore/inspector/front-end/ObjectPropertiesSection.js
@@ -438,6 +438,8 @@ WebInspector.FunctionScopeMainTreeElement.prototype = {
this.removeChildren();
var scopeChain = response.scopeChain;
+ if (!scopeChain)
+ return;
for (var i = 0; i < scopeChain.length; ++i) {
var scope = scopeChain[i];
var title = null;
diff --git a/Source/WebCore/inspector/front-end/ResourceScriptMapping.js b/Source/WebCore/inspector/front-end/ResourceScriptMapping.js
index 02eb62e72..6dfeb11ff 100644
--- a/Source/WebCore/inspector/front-end/ResourceScriptMapping.js
+++ b/Source/WebCore/inspector/front-end/ResourceScriptMapping.js
@@ -45,6 +45,7 @@ WebInspector.ResourceScriptMapping = function(workspace)
this._temporaryUISourceCodes = new Map();
/** @type {Object.<string, number>} */
this._nextDynamicScriptIndexForURL = {};
+ this._scripts = [];
}
WebInspector.ResourceScriptMapping.prototype = {
@@ -82,6 +83,7 @@ WebInspector.ResourceScriptMapping.prototype = {
var isDynamicScript = false;
if (!script.isAnonymousScript()) {
+ this._scripts.push(script);
var uiSourceCode = this._workspace.uiSourceCodeForURL(script.sourceURL);
isDynamicScript = !!uiSourceCode && uiSourceCode.contentType() === WebInspector.resourceTypes.Document && !script.isInlineScript();
if (uiSourceCode && !isDynamicScript && !this._temporaryUISourceCodes.get(uiSourceCode))
@@ -122,7 +124,7 @@ WebInspector.ResourceScriptMapping.prototype = {
return script.sourceURL === sourceURL && script.isInlineScript() === isInlineScript;
}
- return Object.values(WebInspector.debuggerModel.scripts).filter(filter);
+ return this._scripts.filter(filter.bind(this));
},
/**
@@ -220,5 +222,6 @@ WebInspector.ResourceScriptMapping.prototype = {
this._scriptIdForUISourceCode.clear();
this._temporaryUISourceCodes.clear();
this._nextDynamicScriptIndexForURL = {};
+ this._scripts = [];
},
}
diff --git a/Source/WebCore/inspector/front-end/SettingsScreen.js b/Source/WebCore/inspector/front-end/SettingsScreen.js
index 728389c7f..1c98e3e40 100644
--- a/Source/WebCore/inspector/front-end/SettingsScreen.js
+++ b/Source/WebCore/inspector/front-end/SettingsScreen.js
@@ -541,7 +541,7 @@ WebInspector.UserAgentSettingsTab.prototype = {
const checkboxElement = labelElement.createChild("input");
checkboxElement.id = "metrics-override-checkbox";
checkboxElement.type = "checkbox";
- checkboxElement.checked = !metrics || (metrics.width && metrics.height && metrics.fontScaleFactor);
+ checkboxElement.checked = false;
checkboxElement.addEventListener("click", this._onMetricsCheckboxClicked.bind(this), false);
this._metricsCheckboxElement = checkboxElement;
labelElement.appendChild(document.createTextNode(WebInspector.UIString("Device metrics")));
@@ -549,8 +549,7 @@ WebInspector.UserAgentSettingsTab.prototype = {
const metricsSectionElement = this._createDeviceMetricsElement(metrics);
p.appendChild(metricsSectionElement);
this._metricsSectionElement = metricsSectionElement;
-
- this._setDeviceMetricsOverride(metrics, false, true);
+ this._onMetricsCheckboxClicked();
return p;
},
@@ -564,16 +563,18 @@ WebInspector.UserAgentSettingsTab.prototype = {
this._swapDimensionsElement.disabled = controlsDisabled;
this._fitWindowCheckboxElement.disabled = controlsDisabled;
- if (this._metricsCheckboxElement.checked) {
- var metrics = WebInspector.UserAgentSupport.DeviceMetrics.parseUserInput(this._widthOverrideElement.value, this._heightOverrideElement.value, this._fontScaleFactorOverrideElement.value);
- if (metrics && metrics.isValid() && metrics.width && metrics.height)
- this._setDeviceMetricsOverride(metrics, false, false);
- if (!this._widthOverrideElement.value)
- this._widthOverrideElement.focus();
- } else {
- if (WebInspector.settings.deviceMetrics.get())
- WebInspector.settings.deviceMetrics.set("");
+ if (controlsDisabled) {
+ WebInspector.userAgentSupport.toggleDeviceMetricsOverride(false);
+ return;
+ }
+
+ var metrics = WebInspector.UserAgentSupport.DeviceMetrics.parseUserInput(this._widthOverrideElement.value, this._heightOverrideElement.value, this._fontScaleFactorOverrideElement.value);
+ if (metrics && metrics.isValid() && metrics.width && metrics.height) {
+ this._setDeviceMetricsOverride(metrics, false, false);
+ WebInspector.userAgentSupport.toggleDeviceMetricsOverride(true);
}
+ if (!this._widthOverrideElement.value)
+ this._widthOverrideElement.focus();
},
_applyDeviceMetricsUserInput: function()
@@ -675,7 +676,7 @@ WebInspector.UserAgentSettingsTab.prototype = {
var checkboxElement = labelElement.createChild("input");
checkboxElement.id = "geolocation-override-checkbox";
checkboxElement.type = "checkbox";
- checkboxElement.checked = !geolocation || (((typeof geolocation.latitude === "number") && (typeof geolocation.longitude === "number")) || geolocation.error);
+ checkboxElement.checked = false;
checkboxElement.addEventListener("click", this._onGeolocationOverrideCheckboxClicked.bind(this), false);
this._geolocationOverrideCheckboxElement = checkboxElement;
labelElement.appendChild(document.createTextNode(WebInspector.UIString("Override Geolocation")));
@@ -683,7 +684,7 @@ WebInspector.UserAgentSettingsTab.prototype = {
var geolocationSectionElement = this._createGeolocationOverrideElement(geolocation);
p.appendChild(geolocationSectionElement);
this._geolocationSectionElement = geolocationSectionElement;
- this._setGeolocationPosition(geolocation, false, true);
+ this._onGeolocationOverrideCheckboxClicked();
return p;
},
@@ -694,14 +695,18 @@ WebInspector.UserAgentSettingsTab.prototype = {
this._longitudeElement.disabled = controlsDisabled;
this._geolocationErrorElement.disabled = controlsDisabled;
- if (this._geolocationOverrideCheckboxElement.checked) {
- var geolocation = WebInspector.UserAgentSupport.GeolocationPosition.parseUserInput(this._latitudeElement.value, this._longitudeElement.value, this._geolocationErrorElement.checked);
- if (geolocation)
- this._setGeolocationPosition(geolocation, false, false);
- if (!this._latitudeElement.value)
- this._latitudeElement.focus();
- } else
- WebInspector.UserAgentSupport.GeolocationPosition.clearGeolocationOverride();
+ if (controlsDisabled) {
+ WebInspector.userAgentSupport.toggleGeolocationPositionOverride(false);
+ return;
+ }
+
+ var geolocation = WebInspector.UserAgentSupport.GeolocationPosition.parseUserInput(this._latitudeElement.value, this._longitudeElement.value, this._geolocationErrorElement.checked);
+ if (geolocation) {
+ this._setGeolocationPosition(geolocation, false, false);
+ WebInspector.userAgentSupport.toggleGeolocationPositionOverride(true);
+ }
+ if (!this._latitudeElement.value)
+ this._latitudeElement.focus();
},
_applyGeolocationUserInput: function()
@@ -774,7 +779,7 @@ WebInspector.UserAgentSettingsTab.prototype = {
var checkboxElement = labelElement.createChild("input");
checkboxElement.id = "device-orientation-override-checkbox";
checkboxElement.type = "checkbox";
- checkboxElement.checked = !deviceOrientation;
+ checkboxElement.checked = false;
checkboxElement.addEventListener("click", this._onDeviceOrientationOverrideCheckboxClicked.bind(this), false);
this._deviceOrientationOverrideCheckboxElement = checkboxElement;
labelElement.appendChild(document.createTextNode(WebInspector.UIString("Override Device Orientation")));
@@ -782,9 +787,7 @@ WebInspector.UserAgentSettingsTab.prototype = {
var deviceOrientationSectionElement = this._createDeviceOrientationOverrideElement(deviceOrientation);
p.appendChild(deviceOrientationSectionElement);
this._deviceOrientationSectionElement = deviceOrientationSectionElement;
-
- this._setDeviceOrientation(deviceOrientation, false, true);
-
+ this._onDeviceOrientationOverrideCheckboxClicked();
return p;
},
@@ -795,14 +798,18 @@ WebInspector.UserAgentSettingsTab.prototype = {
this._betaElement.disabled = controlsDisabled;
this._gammaElement.disabled = controlsDisabled;
- if (this._deviceOrientationOverrideCheckboxElement.checked) {
- var deviceOrientation = WebInspector.UserAgentSupport.DeviceOrientation.parseUserInput(this._alphaElement.value, this._betaElement.value, this._gammaElement.value);
- if (deviceOrientation)
- this._setDeviceOrientation(deviceOrientation, false, false);
- if (!this._alphaElement.value)
- this._alphaElement.focus();
- } else
- WebInspector.UserAgentSupport.DeviceOrientation.clearDeviceOrientationOverride();
+ if (controlsDisabled) {
+ WebInspector.userAgentSupport.toggleDeviceOrientationOverride(false);
+ return;
+ }
+
+ var deviceOrientation = WebInspector.UserAgentSupport.DeviceOrientation.parseUserInput(this._alphaElement.value, this._betaElement.value, this._gammaElement.value);
+ if (deviceOrientation) {
+ this._setDeviceOrientation(deviceOrientation, false, false);
+ WebInspector.userAgentSupport.toggleDeviceOrientationOverride(true);
+ }
+ if (!this._alphaElement.value)
+ this._alphaElement.focus();
},
_applyDeviceOrientationUserInput: function()
diff --git a/Source/WebCore/inspector/front-end/StylesSidebarPane.js b/Source/WebCore/inspector/front-end/StylesSidebarPane.js
index 6ce7b7989..e18c6359c 100644
--- a/Source/WebCore/inspector/front-end/StylesSidebarPane.js
+++ b/Source/WebCore/inspector/front-end/StylesSidebarPane.js
@@ -358,7 +358,6 @@ WebInspector.StylesSidebarPane.prototype = {
var usedProperties = {};
this._markUsedProperties(styleRules, usedProperties);
this.sections[0] = this._rebuildSectionsForStyleRules(styleRules, usedProperties, 0, null);
- var responsesLeft = this.sections[0].length;
var anchorElement = this.sections[0].inheritedPropertiesSeparatorElement;
if (styles.computedStyle)
@@ -381,28 +380,9 @@ WebInspector.StylesSidebarPane.prototype = {
usedProperties = {};
this._markUsedProperties(styleRules, usedProperties);
this.sections[pseudoId] = this._rebuildSectionsForStyleRules(styleRules, usedProperties, pseudoId, anchorElement);
- responsesLeft += this.sections[pseudoId].length;
}
- // Mark matching selectors in comma-delimited selector groups.
- var boundMarkCallback = markCallback.bind(this);
- for (var id in this.sections) {
- var sectionsForPseudoId = this.sections[id].slice();
- for (var j = 0; j < sectionsForPseudoId.length; ++j) {
- var section = sectionsForPseudoId[j];
- if (!section.styleRule || section.isBlank || section.styleRule.computedStyle || section.styleRule.isAttribute) {
- boundMarkCallback();
- continue;
- }
- section._markMatchedSelectorsInGroup(boundMarkCallback);
- }
- }
-
- function markCallback()
- {
- if (!(--responsesLeft))
- this._nodeStylesUpdatedForTest(node, true);
- }
+ this._nodeStylesUpdatedForTest(node, true);
},
_nodeStylesUpdatedForTest: function(node, rebuild)
@@ -606,8 +586,10 @@ WebInspector.StylesSidebarPane.prototype = {
if (computedStyle)
var section = new WebInspector.ComputedStylePropertiesSection(this, styleRule, usedProperties);
- else
+ else {
var section = new WebInspector.StylePropertiesSection(this, styleRule, editable, styleRule.isInherited, lastWasSeparator);
+ section._markSelectorMatches();
+ }
section.expanded = true;
if (computedStyle) {
@@ -1124,89 +1106,38 @@ WebInspector.StylePropertiesSection.prototype = {
return null;
},
- /**
- * @param {function()=} callback
- */
- _markMatchedSelectorsInGroup: function(callback)
+ _markSelectorMatches: function()
{
- var self = this;
- function mycallback()
- {
- if (callback)
- callback();
- }
-
- var selectorText = this._selectorElement.textContent;
- if (!selectorText || selectorText.indexOf(",") === -1) {
- mycallback();
+ var rule = this.styleRule.rule;
+ if (!rule)
return;
- }
- var paneNode = this._parentPane.node;
- var relatedNode = this.styleRule.parentNode || paneNode;
- if (!relatedNode) {
- mycallback();
+ var selectors = rule.selectors;
+ var matchingSelectors = rule.matchingSelectors;
+ if (selectors.length < 2 || !matchingSelectors)
return;
- }
-
- function trim(text)
- {
- return text.trim();
- }
- var selectors = selectorText.split(",").map(trim);
-
- WebInspector.RemoteObject.resolveNode(relatedNode, "", resolvedCallback);
- function resolvedCallback(object)
- {
- if (!object) {
- mycallback();
- return;
- }
-
- for (var i = 0, size = selectors.length; i < size; ++i) {
- var selector = selectors[i];
- object.callFunctionJSON(matchesSelector, [{ value: selectors[i] }], matchesCallback.bind(this, i));
- }
- }
-
- function matchesSelector(selector)
- {
- return this.webkitMatchesSelector(selector);
- }
-
- var result = [];
- var matchFound;
- function matchesCallback(selectorIndex, matches)
- {
- var isLast = selectorIndex === selectors.length - 1;
- var fragment = document.createDocumentFragment();
- result[selectorIndex] = fragment;
+ var fragment = document.createDocumentFragment();
+ var currentMatch = 0;
+ for (var i = 0, lastSelectorIndex = selectors.length - 1; i <= lastSelectorIndex ; ++i) {
var selectorNode;
- if (matches && paneNode === self._parentPane.node) {
+ var textNode = document.createTextNode(selectors[i]);
+ if (matchingSelectors[currentMatch] === i) {
+ ++currentMatch;
selectorNode = document.createElement("span");
selectorNode.className = "selector-matches";
- selectorNode.appendChild(document.createTextNode(selectors[selectorIndex]));
- matchFound = true;
+ selectorNode.appendChild(textNode);
} else
- selectorNode = document.createTextNode(selectors[selectorIndex]);
+ selectorNode = textNode;
fragment.appendChild(selectorNode);
- if (!isLast) {
+ if (i !== lastSelectorIndex)
fragment.appendChild(document.createTextNode(", "));
- return;
- }
-
- // This check is here in case the element class has been changed from JS during the roundtrip,
- // so the element matches none of the distinct selectors. Fall back to "all selectors match".
- if (matchFound) {
- self._selectorElement.className = "selector";
- self._selectorElement.removeChildren();
- for (var i = 0; i < result.length; ++i)
- self._selectorElement.appendChild(result[i]);
- }
- mycallback();
}
+
+ this._selectorElement.className = "selector";
+ this._selectorElement.removeChildren();
+ this._selectorElement.appendChild(fragment);
},
_checkWillCancelEditing: function()
@@ -1350,32 +1281,27 @@ WebInspector.StylePropertiesSection.prototype = {
_moveEditorFromSelector: function(moveDirection)
{
+ this._markSelectorMatches();
- if (!moveDirection) {
- this._markMatchedSelectorsInGroup();
+ if (!moveDirection)
return;
- }
-
- this._markMatchedSelectorsInGroup(markCallback.bind(this));
- function markCallback() {
- if (moveDirection === "forward") {
- this.expand();
- var firstChild = this.propertiesTreeOutline.children[0];
- while (firstChild && firstChild.inherited)
- firstChild = firstChild.nextSibling;
- if (!firstChild)
- this.addNewBlankProperty().startEditing();
- else
- firstChild.startEditing(firstChild.nameElement);
- } else {
- var previousSection = this.previousEditableSibling();
- if (!previousSection)
- return;
+ if (moveDirection === "forward") {
+ this.expand();
+ var firstChild = this.propertiesTreeOutline.children[0];
+ while (firstChild && firstChild.inherited)
+ firstChild = firstChild.nextSibling;
+ if (!firstChild)
+ this.addNewBlankProperty().startEditing();
+ else
+ firstChild.startEditing(firstChild.nameElement);
+ } else {
+ var previousSection = this.previousEditableSibling();
+ if (!previousSection)
+ return;
- previousSection.expand();
- previousSection.addNewBlankProperty().startEditing();
- }
+ previousSection.expand();
+ previousSection.addNewBlankProperty().startEditing();
}
},
@@ -1415,7 +1341,7 @@ WebInspector.StylePropertiesSection.prototype = {
{
// Do nothing but mark the selectors in group if necessary.
// This is overridden by BlankStylePropertiesSection.
- this._markMatchedSelectorsInGroup();
+ this._markSelectorMatches();
}
}
diff --git a/Source/WebCore/inspector/front-end/UserAgentSupport.js b/Source/WebCore/inspector/front-end/UserAgentSupport.js
index 794d11a96..ebed8079c 100644
--- a/Source/WebCore/inspector/front-end/UserAgentSupport.js
+++ b/Source/WebCore/inspector/front-end/UserAgentSupport.js
@@ -33,8 +33,10 @@
*/
WebInspector.UserAgentSupport = function()
{
- if (WebInspector.settings.deviceMetrics.get())
- this._deviceMetricsChanged();
+ this._deviceMetricsOverrideEnabled = false;
+ this._geolocationPositionOverrideEnabled = false;
+ this._deviceOrientationOverrideEnabled = false;
+
WebInspector.settings.deviceMetrics.addChangeListener(this._deviceMetricsChanged, this);
WebInspector.settings.deviceFitWindow.addChangeListener(this._deviceMetricsChanged, this);
WebInspector.settings.geolocationOverride.addChangeListener(this._geolocationPositionChanged, this);
@@ -305,15 +307,43 @@ WebInspector.UserAgentSupport.DeviceOrientation.clearDeviceOrientationOverride =
}
WebInspector.UserAgentSupport.prototype = {
+ toggleDeviceMetricsOverride: function(enabled)
+ {
+ if (enabled === this._deviceMetricsOverrideEnabled)
+ return;
+ this._deviceMetricsOverrideEnabled = enabled;
+ this._deviceMetricsChanged();
+ },
+
+ toggleGeolocationPositionOverride: function(enabled)
+ {
+ if (enabled === this._geolocationPositionOverrideEnabled)
+ return;
+ this._geolocationPositionOverrideEnabled = enabled;
+ this._geolocationPositionChanged();
+ },
+
+ toggleDeviceOrientationOverride: function(enabled)
+ {
+ if (enabled === this._deviceOrientationOverrideEnabled)
+ return;
+ this._deviceOrientationOverrideEnabled = enabled;
+ this._deviceOrientationChanged();
+ },
+
_deviceMetricsChanged: function()
{
- var metrics = WebInspector.UserAgentSupport.DeviceMetrics.parseSetting(WebInspector.settings.deviceMetrics.get());
+ var metrics = WebInspector.UserAgentSupport.DeviceMetrics.parseSetting(this._deviceMetricsOverrideEnabled ? WebInspector.settings.deviceMetrics.get() : "");
if (metrics.isValid())
PageAgent.setDeviceMetricsOverride(metrics.width, metrics.height, metrics.fontScaleFactor, WebInspector.settings.deviceFitWindow.get());
},
_geolocationPositionChanged: function()
{
+ if (!this._geolocationPositionOverrideEnabled) {
+ PageAgent.clearGeolocationOverride();
+ return;
+ }
var geolocation = WebInspector.UserAgentSupport.GeolocationPosition.parseSetting(WebInspector.settings.geolocationOverride.get());
if (geolocation.error)
PageAgent.setGeolocationOverride();
@@ -321,11 +351,12 @@ WebInspector.UserAgentSupport.prototype = {
PageAgent.setGeolocationOverride(geolocation.latitude, geolocation.longitude, 150);
},
- /**
- * @param {WebInspector.Event} event
- */
- _deviceOrientationChanged: function(event)
+ _deviceOrientationChanged: function()
{
+ if (!this._deviceOrientationOverrideEnabled) {
+ PageAgent.clearDeviceOrientationOverride();
+ return;
+ }
var deviceOrientation = WebInspector.UserAgentSupport.DeviceOrientation.parseSetting(WebInspector.settings.deviceOrientationOverride.get());
PageAgent.setDeviceOrientationOverride(deviceOrientation.alpha, deviceOrientation.beta, deviceOrientation.gamma);
}
diff --git a/Source/WebCore/inspector/front-end/externs.js b/Source/WebCore/inspector/front-end/externs.js
index 8cf53d26c..21d61a00a 100644
--- a/Source/WebCore/inspector/front-end/externs.js
+++ b/Source/WebCore/inspector/front-end/externs.js
@@ -262,6 +262,11 @@ WebInspector.showPanel = function(panel)
*/
WebInspector.inspectedPageDomain;
+/**
+ * @type {WebInspector.UserAgentSupport}
+ */
+WebInspector.userAgentSupport;
+
WebInspector.isCompactMode = function() { return false; }
WebInspector.SourceJavaScriptTokenizer = {}
diff --git a/Source/WebCore/inspector/front-end/inspector.css b/Source/WebCore/inspector/front-end/inspector.css
index d5b13097b..1c126ea8e 100644
--- a/Source/WebCore/inspector/front-end/inspector.css
+++ b/Source/WebCore/inspector/front-end/inspector.css
@@ -2348,6 +2348,7 @@ li.breakpoint-hit .breakpoint-hit-marker {
-webkit-border-radius: 7px;
border: 2px solid rgb(169, 172, 203);
width: 90%;
+ pointer-events: auto;
}
.source-frame-breakpoint-message {
diff --git a/Source/WebCore/inspector/front-end/inspector.js b/Source/WebCore/inspector/front-end/inspector.js
index ab67c474c..e77a90bfa 100644
--- a/Source/WebCore/inspector/front-end/inspector.js
+++ b/Source/WebCore/inspector/front-end/inspector.js
@@ -86,7 +86,7 @@ var WebInspector = {
if (!WebInspector.WorkerManager.isWorkerFrontend()) {
this._nodeSearchButton = new WebInspector.StatusBarButton(WebInspector.UIString("Select an element in the page to inspect it."), "node-search-status-bar-item");
- this._nodeSearchButton.addEventListener("click", this._toggleSearchingForNode, this);
+ this._nodeSearchButton.addEventListener("click", this.toggleSearchingForNode, this);
mainStatusBar.insertBefore(this._nodeSearchButton.element, bottomStatusBarContainer);
}
@@ -356,7 +356,7 @@ var WebInspector = {
InspectorFrontendHost.setZoomFactor(Math.pow(1.2, this._zoomLevel));
},
- _toggleSearchingForNode: function()
+ toggleSearchingForNode: function()
{
var enabled = !this._nodeSearchButton.toggled;
/**
@@ -862,7 +862,7 @@ WebInspector.documentKeyDown = function(event)
var isNodeSearchKey = event.ctrlKey && !event.metaKey && !event.altKey && event.shiftKey;
if (isNodeSearchKey) {
- this._toggleSearchingForNode();
+ this.toggleSearchingForNode();
event.consume(true);
return;
}
diff --git a/Source/WebCore/loader/DocumentLoader.cpp b/Source/WebCore/loader/DocumentLoader.cpp
index 8368041cf..900af978a 100644
--- a/Source/WebCore/loader/DocumentLoader.cpp
+++ b/Source/WebCore/loader/DocumentLoader.cpp
@@ -53,6 +53,7 @@
#include "TextResourceDecoder.h"
#include "WebCoreMemoryInstrumentation.h"
#include <wtf/Assertions.h>
+#include <wtf/MemoryInstrumentationVector.h>
#include <wtf/text/CString.h>
#include <wtf/text/WTFString.h>
#include <wtf/unicode/Unicode.h>
@@ -368,16 +369,16 @@ void DocumentLoader::reportMemoryUsage(MemoryObjectInfo* memoryObjectInfo) const
info.addMember(m_substituteData);
info.addMember(m_pageTitle.string());
info.addMember(m_overrideEncoding);
- info.addVector(m_responses);
+ info.addMember(m_responses);
info.addMember(m_originalRequest);
info.addMember(m_originalRequestCopy);
info.addMember(m_request);
info.addMember(m_response);
info.addMember(m_lastCheckedRequest);
- info.addInstrumentedVector(m_responses);
+ info.addMember(m_responses);
info.addHashMap(m_pendingSubstituteResources);
info.addInstrumentedHashSet(m_resourcesClientKnowsAbout);
- info.addVector(m_resourcesLoadedFromMemoryCacheForClientNotification);
+ info.addMember(m_resourcesLoadedFromMemoryCacheForClientNotification);
info.addMember(m_clientRedirectSourceForHistory);
info.addMember(m_mainResourceData);
}
diff --git a/Source/WebCore/loader/FrameLoader.cpp b/Source/WebCore/loader/FrameLoader.cpp
index b26b6d4cc..89f876242 100644
--- a/Source/WebCore/loader/FrameLoader.cpp
+++ b/Source/WebCore/loader/FrameLoader.cpp
@@ -647,7 +647,10 @@ void FrameLoader::didBeginDocument(bool dispatch)
m_frame->document()->initContentSecurityPolicy();
Settings* settings = m_frame->document()->settings();
- m_frame->document()->cachedResourceLoader()->setAutoLoadImages(settings && settings->loadsImagesAutomatically());
+ if (settings) {
+ m_frame->document()->cachedResourceLoader()->setImagesEnabled(settings->areImagesEnabled());
+ m_frame->document()->cachedResourceLoader()->setAutoLoadImages(settings->loadsImagesAutomatically());
+ }
if (m_documentLoader) {
String dnsPrefetchControl = m_documentLoader->response().httpHeaderField("X-DNS-Prefetch-Control");
diff --git a/Source/WebCore/loader/SubresourceLoader.cpp b/Source/WebCore/loader/SubresourceLoader.cpp
index ff3be6edf..56de0d341 100644
--- a/Source/WebCore/loader/SubresourceLoader.cpp
+++ b/Source/WebCore/loader/SubresourceLoader.cpp
@@ -167,11 +167,13 @@ void SubresourceLoader::willSendRequest(ResourceRequest& newRequest, const Resou
ResourceLoader::willSendRequest(newRequest, redirectResponse);
if (!previousURL.isNull() && !newRequest.isNull() && previousURL != newRequest.url()) {
- if (!m_document->cachedResourceLoader()->canRequest(m_resource->type(), newRequest.url())) {
- cancel();
- return;
+ if (m_document->cachedResourceLoader()->canRequest(m_resource->type(), newRequest.url())) {
+ if (m_resource->type() != CachedResource::ImageResource || !m_document->cachedResourceLoader()->shouldDeferImageLoad(newRequest.url())) {
+ m_resource->willSendRequest(newRequest, redirectResponse);
+ return;
+ }
}
- m_resource->willSendRequest(newRequest, redirectResponse);
+ cancel();
}
}
diff --git a/Source/WebCore/loader/cache/CachedImage.cpp b/Source/WebCore/loader/cache/CachedImage.cpp
index 4316616b3..41075a7b3 100644
--- a/Source/WebCore/loader/cache/CachedImage.cpp
+++ b/Source/WebCore/loader/cache/CachedImage.cpp
@@ -29,7 +29,6 @@
#include "CachedResourceClient.h"
#include "CachedResourceClientWalker.h"
#include "CachedResourceLoader.h"
-#include "Frame.h"
#include "FrameLoaderClient.h"
#include "FrameLoaderTypes.h"
#include "FrameView.h"
diff --git a/Source/WebCore/loader/cache/CachedImage.h b/Source/WebCore/loader/cache/CachedImage.h
index 4865c7e24..078f7ab1c 100644
--- a/Source/WebCore/loader/cache/CachedImage.h
+++ b/Source/WebCore/loader/cache/CachedImage.h
@@ -82,8 +82,7 @@ public:
virtual bool shouldIgnoreHTTPStatusCodeErrors() const { return true; }
virtual bool isImage() const { return true; }
- bool stillNeedsLoad() const { return !errorOccurred() && status() == Unknown && !isLoading(); }
- void load();
+ virtual bool stillNeedsLoad() const OVERRIDE { return !errorOccurred() && status() == Unknown && !isLoading(); }
// ImageObserver
virtual void decodedSizeChanged(const Image* image, int delta);
diff --git a/Source/WebCore/loader/cache/CachedResource.cpp b/Source/WebCore/loader/cache/CachedResource.cpp
index 43c3d144f..33d1ba823 100755
--- a/Source/WebCore/loader/cache/CachedResource.cpp
+++ b/Source/WebCore/loader/cache/CachedResource.cpp
@@ -32,7 +32,6 @@
#include "CachedResourceLoader.h"
#include "CrossOriginAccessControl.h"
#include "Document.h"
-#include "Frame.h"
#include "FrameLoaderClient.h"
#include "InspectorInstrumentation.h"
#include "KURL.h"
@@ -390,7 +389,7 @@ void CachedResource::didAddClient(CachedResourceClient* c)
m_clients.add(c);
m_clientsAwaitingCallback.remove(c);
}
- if (!isLoading())
+ if (!isLoading() && !stillNeedsLoad())
c->notifyFinished(this);
}
diff --git a/Source/WebCore/loader/cache/CachedResource.h b/Source/WebCore/loader/cache/CachedResource.h
index 0cad3ee7c..b739d68af 100644
--- a/Source/WebCore/loader/cache/CachedResource.h
+++ b/Source/WebCore/loader/cache/CachedResource.h
@@ -45,7 +45,6 @@ class CachedMetadata;
class CachedResourceClient;
class CachedResourceHandleBase;
class CachedResourceLoader;
-class Frame;
class InspectorResource;
class PurgeableBuffer;
class SecurityOrigin;
@@ -144,6 +143,7 @@ public:
bool isLoading() const { return m_loading; }
void setLoading(bool b) { m_loading = b; }
+ virtual bool stillNeedsLoad() const { return false; }
SubresourceLoader* loader() { return m_loader.get(); }
diff --git a/Source/WebCore/loader/cache/CachedResourceLoader.cpp b/Source/WebCore/loader/cache/CachedResourceLoader.cpp
index 353a62aa6..593d532a1 100644
--- a/Source/WebCore/loader/cache/CachedResourceLoader.cpp
+++ b/Source/WebCore/loader/cache/CachedResourceLoader.cpp
@@ -115,6 +115,7 @@ CachedResourceLoader::CachedResourceLoader(Document* document)
, m_requestCount(0)
, m_garbageCollectDocumentResourcesTimer(this, &CachedResourceLoader::garbageCollectDocumentResourcesTimerFired)
, m_autoLoadImages(true)
+ , m_imagesEnabled(true)
, m_allowStaleResources(false)
{
}
@@ -159,10 +160,7 @@ CachedResourceHandle<CachedImage> CachedResourceLoader::requestImage(ResourceReq
return 0;
}
}
- CachedResourceHandle<CachedImage> resource(static_cast<CachedImage*>(requestResource(CachedResource::ImageResource, request, String(), defaultCachedResourceOptions()).get()));
- if (autoLoadImages() && resource && resource->stillNeedsLoad())
- resource->load(this, defaultCachedResourceOptions());
- return resource;
+ return static_cast<CachedImage*>(requestResource(CachedResource::ImageResource, request, String(), defaultCachedResourceOptions(), ResourceLoadPriorityUnresolved, false, clientDefersImage(request.url()) ? DeferredByClient : NoDefer).get());
}
CachedResourceHandle<CachedFont> CachedResourceLoader::requestFont(ResourceRequest& request)
@@ -362,12 +360,6 @@ bool CachedResourceLoader::canRequest(CachedResource::Type type, const KURL& url
case CachedResource::ImageResource:
if (!m_document->contentSecurityPolicy()->allowImageFromSource(url))
return false;
-
- if (frame()) {
- Settings* settings = frame()->settings();
- if (!frame()->loader()->client()->allowImage(!settings || settings->areImagesEnabled(), url))
- return false;
- }
break;
case CachedResource::FontResource: {
if (!m_document->contentSecurityPolicy()->allowFontFromSource(url))
@@ -401,7 +393,7 @@ bool CachedResourceLoader::canRequest(CachedResource::Type type, const KURL& url
return true;
}
-CachedResourceHandle<CachedResource> CachedResourceLoader::requestResource(CachedResource::Type type, ResourceRequest& request, const String& charset, const ResourceLoaderOptions& options, ResourceLoadPriority priority, bool forPreload)
+CachedResourceHandle<CachedResource> CachedResourceLoader::requestResource(CachedResource::Type type, ResourceRequest& request, const String& charset, const ResourceLoaderOptions& options, ResourceLoadPriority priority, bool forPreload, DeferOption defer)
{
KURL url = request.url();
@@ -430,16 +422,16 @@ CachedResourceHandle<CachedResource> CachedResourceLoader::requestResource(Cache
if (request.url() != url)
request.setURL(url);
- switch (determineRevalidationPolicy(type, request, forPreload, resource.get())) {
- case Load:
- resource = loadResource(type, request, charset, priority, options);
- break;
+ const RevalidationPolicy policy = determineRevalidationPolicy(type, request, forPreload, resource.get(), defer);
+ switch (policy) {
case Reload:
memoryCache()->remove(resource.get());
- resource = loadResource(type, request, charset, priority, options);
+ // Fall through
+ case Load:
+ resource = loadResource(type, request, charset);
break;
case Revalidate:
- resource = revalidateResource(resource.get(), priority, options);
+ resource = revalidateResource(resource.get());
break;
case Use:
memoryCache()->resourceAccessed(resource.get());
@@ -450,12 +442,27 @@ CachedResourceHandle<CachedResource> CachedResourceLoader::requestResource(Cache
if (!resource)
return 0;
+ resource->setLoadPriority(priority);
+ if ((policy != Use || resource->stillNeedsLoad()) && NoDefer == defer) {
+ resource->load(this, options);
+
+ // We don't support immediate loads, but we do support immediate failure.
+ if (resource->errorOccurred()) {
+ if (resource->inCache())
+ memoryCache()->remove(resource.get());
+ return 0;
+ }
+ }
+
+ if (!request.url().protocolIsData())
+ m_validatedURLs.add(request.url());
+
ASSERT(resource->url() == url.string());
m_documentResources.set(resource->url(), resource);
return resource;
}
-CachedResourceHandle<CachedResource> CachedResourceLoader::revalidateResource(CachedResource* resource, ResourceLoadPriority priority, const ResourceLoaderOptions& options)
+CachedResourceHandle<CachedResource> CachedResourceLoader::revalidateResource(CachedResource* resource)
{
ASSERT(resource);
ASSERT(resource->inCache());
@@ -465,7 +472,6 @@ CachedResourceHandle<CachedResource> CachedResourceLoader::revalidateResource(Ca
// Copy the URL out of the resource to be revalidated in case it gets deleted by the remove() call below.
String url = resource->url();
- bool urlProtocolIsData = resource->url().protocolIsData();
CachedResourceHandle<CachedResource> newResource = createResource(resource->type(), resource->resourceRequest(), resource->encoding());
LOG(ResourceLoading, "Resource %p created to revalidate %p", newResource.get(), resource);
@@ -473,16 +479,10 @@ CachedResourceHandle<CachedResource> CachedResourceLoader::revalidateResource(Ca
memoryCache()->remove(resource);
memoryCache()->add(newResource.get());
-
- newResource->setLoadPriority(priority);
- newResource->load(this, options);
-
- if (!urlProtocolIsData)
- m_validatedURLs.add(url);
return newResource;
}
-CachedResourceHandle<CachedResource> CachedResourceLoader::loadResource(CachedResource::Type type, ResourceRequest& request, const String& charset, ResourceLoadPriority priority, const ResourceLoaderOptions& options)
+CachedResourceHandle<CachedResource> CachedResourceLoader::loadResource(CachedResource::Type type, ResourceRequest& request, const String& charset)
{
ASSERT(!memoryCache()->resourceForURL(request.url()));
@@ -490,35 +490,20 @@ CachedResourceHandle<CachedResource> CachedResourceLoader::loadResource(CachedRe
CachedResourceHandle<CachedResource> resource = createResource(type, request, charset);
- bool inCache = memoryCache()->add(resource.get());
-
- resource->setLoadPriority(priority);
- resource->load(this, options);
-
- if (!inCache)
+ if (!memoryCache()->add(resource.get()))
resource->setOwningCachedResourceLoader(this);
-
- // We don't support immediate loads, but we do support immediate failure.
- if (resource->errorOccurred()) {
- if (inCache)
- memoryCache()->remove(resource.get());
- return 0;
- }
-
- if (!request.url().protocolIsData())
- m_validatedURLs.add(request.url());
return resource;
}
-CachedResourceLoader::RevalidationPolicy CachedResourceLoader::determineRevalidationPolicy(CachedResource::Type type, ResourceRequest& request, bool forPreload, CachedResource* existingResource) const
+CachedResourceLoader::RevalidationPolicy CachedResourceLoader::determineRevalidationPolicy(CachedResource::Type type, ResourceRequest& request, bool forPreload, CachedResource* existingResource, DeferOption defer) const
{
if (!existingResource)
return Load;
-
+
// We already have a preload going for this URL.
if (forPreload && existingResource->isPreloaded())
return Use;
-
+
// If the same URL has been loaded as a different type, we need to reload.
if (existingResource->type() != type) {
LOG(ResourceLoading, "CachedResourceLoader::determineRevalidationPolicy reloading due to type mismatch.");
@@ -533,6 +518,11 @@ CachedResourceLoader::RevalidationPolicy CachedResourceLoader::determineRevalida
// of things about how revalidation works that manual headers violate, so punt to Reload instead.
if (request.isConditional())
return Reload;
+
+ // Do not load from cache if images are not enabled. The load for this image will be blocked
+ // in CachedImage::load.
+ if (DeferredByClient == defer)
+ return Reload;
// Don't reload resources while pasting.
if (m_allowStaleResources)
@@ -629,15 +619,39 @@ void CachedResourceLoader::setAutoLoadImages(bool enable)
if (!m_autoLoadImages)
return;
+ reloadImagesIfNotDeferred();
+}
+
+void CachedResourceLoader::setImagesEnabled(bool enable)
+{
+ if (enable == m_imagesEnabled)
+ return;
+
+ m_imagesEnabled = enable;
+
+ if (!m_imagesEnabled)
+ return;
+
+ reloadImagesIfNotDeferred();
+}
+
+bool CachedResourceLoader::clientDefersImage(const KURL& url) const
+{
+ return frame() && !frame()->loader()->client()->allowImage(m_imagesEnabled, url);
+}
+
+bool CachedResourceLoader::shouldDeferImageLoad(const KURL& url) const
+{
+ return clientDefersImage(url) || !m_autoLoadImages;
+}
+
+void CachedResourceLoader::reloadImagesIfNotDeferred()
+{
DocumentResourceMap::iterator end = m_documentResources.end();
for (DocumentResourceMap::iterator it = m_documentResources.begin(); it != end; ++it) {
CachedResource* resource = it->second.get();
- if (resource->type() == CachedResource::ImageResource) {
- CachedImage* image = const_cast<CachedImage*>(static_cast<const CachedImage*>(resource));
-
- if (image->stillNeedsLoad())
- image->load(this, defaultCachedResourceOptions());
- }
+ if (resource->type() == CachedResource::ImageResource && resource->stillNeedsLoad() && !clientDefersImage(resource->url()))
+ const_cast<CachedResource*>(resource)->load(this, defaultCachedResourceOptions());
}
}
diff --git a/Source/WebCore/loader/cache/CachedResourceLoader.h b/Source/WebCore/loader/cache/CachedResourceLoader.h
index f4755c22f..b5dc69482 100644
--- a/Source/WebCore/loader/cache/CachedResourceLoader.h
+++ b/Source/WebCore/loader/cache/CachedResourceLoader.h
@@ -97,6 +97,10 @@ public:
bool autoLoadImages() const { return m_autoLoadImages; }
void setAutoLoadImages(bool);
+
+ void setImagesEnabled(bool);
+
+ bool shouldDeferImageLoad(const KURL&) const;
CachePolicy cachePolicy() const;
@@ -122,19 +126,23 @@ public:
void reportMemoryUsage(MemoryObjectInfo*) const;
private:
- CachedResourceHandle<CachedResource> requestResource(CachedResource::Type, ResourceRequest&, const String& charset, const ResourceLoaderOptions&, ResourceLoadPriority = ResourceLoadPriorityUnresolved, bool isPreload = false);
- CachedResourceHandle<CachedResource> revalidateResource(CachedResource*, ResourceLoadPriority, const ResourceLoaderOptions&);
- CachedResourceHandle<CachedResource> loadResource(CachedResource::Type, ResourceRequest&, const String& charset, ResourceLoadPriority, const ResourceLoaderOptions&);
+ enum DeferOption { NoDefer, DeferredByClient };
+ CachedResourceHandle<CachedResource> requestResource(CachedResource::Type, ResourceRequest&, const String& charset, const ResourceLoaderOptions&, ResourceLoadPriority = ResourceLoadPriorityUnresolved, bool isPreload = false, DeferOption = NoDefer);
+ CachedResourceHandle<CachedResource> revalidateResource(CachedResource*);
+ CachedResourceHandle<CachedResource> loadResource(CachedResource::Type, ResourceRequest&, const String& charset);
void requestPreload(CachedResource::Type, ResourceRequest&, const String& charset);
enum RevalidationPolicy { Use, Revalidate, Reload, Load };
- RevalidationPolicy determineRevalidationPolicy(CachedResource::Type, ResourceRequest&, bool forPreload, CachedResource* existingResource) const;
+ RevalidationPolicy determineRevalidationPolicy(CachedResource::Type, ResourceRequest&, bool forPreload, CachedResource* existingResource, DeferOption) const;
void notifyLoadedFromMemoryCache(CachedResource*);
bool checkInsecureContent(CachedResource::Type, const KURL&) const;
void garbageCollectDocumentResourcesTimerFired(Timer<CachedResourceLoader>*);
void performPostLoadActions();
+
+ bool clientDefersImage(const KURL&) const;
+ void reloadImagesIfNotDeferred();
HashSet<String> m_validatedURLs;
mutable DocumentResourceMap m_documentResources;
@@ -152,8 +160,9 @@ private:
Timer<CachedResourceLoader> m_garbageCollectDocumentResourcesTimer;
- // 30 bits left
+ // 29 bits left
bool m_autoLoadImages : 1;
+ bool m_imagesEnabled : 1;
bool m_allowStaleResources : 1;
};
diff --git a/Source/WebCore/loader/cache/MemoryCache.cpp b/Source/WebCore/loader/cache/MemoryCache.cpp
index 66d3201eb..c1af09d69 100644
--- a/Source/WebCore/loader/cache/MemoryCache.cpp
+++ b/Source/WebCore/loader/cache/MemoryCache.cpp
@@ -45,6 +45,7 @@
#include "WorkerThread.h"
#include <stdio.h>
#include <wtf/CurrentTime.h>
+#include <wtf/MemoryInstrumentationVector.h>
#include <wtf/TemporaryChange.h>
#include <wtf/text/CString.h>
@@ -724,7 +725,7 @@ void MemoryCache::reportMemoryUsage(MemoryObjectInfo* memoryObjectInfo) const
info.addMember(i->first);
info.addMember(i->second);
}
- info.addVector(m_allResources);
+ info.addMember(m_allResources);
info.addMember(m_liveDecodedResources);
}
diff --git a/Source/WebCore/mathml/MathMLMathElement.cpp b/Source/WebCore/mathml/MathMLMathElement.cpp
index 80d915700..bc50d9b8a 100644
--- a/Source/WebCore/mathml/MathMLMathElement.cpp
+++ b/Source/WebCore/mathml/MathMLMathElement.cpp
@@ -47,7 +47,7 @@ Node::InsertionNotificationRequest MathMLMathElement::insertedInto(ContainerNode
{
// There are sibling rules in the MathML default style.
if (insertionPoint->inDocument())
- document()->setUsesSiblingRules(true);
+ document()->styleSheetCollection()->setUsesSiblingRulesOverride(true);
return MathMLInlineContainerElement::insertedInto(insertionPoint);
}
diff --git a/Source/WebCore/page/FeatureObserver.h b/Source/WebCore/page/FeatureObserver.h
index 9096ec596..6a50c53df 100644
--- a/Source/WebCore/page/FeatureObserver.h
+++ b/Source/WebCore/page/FeatureObserver.h
@@ -48,6 +48,7 @@ public:
LegacyWebAudioNoteOn,
WebAudioStart,
PrefixedContentSecurityPolicy,
+ UnprefixedIndexedDB,
// Add new features above this line.
NumberOfFeatures, // This enum value must be last.
};
diff --git a/Source/WebCore/page/Page.cpp b/Source/WebCore/page/Page.cpp
index cf4d0fec9..62b4c55b5 100644
--- a/Source/WebCore/page/Page.cpp
+++ b/Source/WebCore/page/Page.cpp
@@ -29,6 +29,7 @@
#include "ContextMenuController.h"
#include "DOMWindow.h"
#include "DocumentMarkerController.h"
+#include "DocumentStyleSheetCollection.h"
#include "DragController.h"
#include "EditorClient.h"
#include "Event.h"
@@ -838,7 +839,7 @@ void Page::userStyleSheetLocationChanged()
for (Frame* frame = mainFrame(); frame; frame = frame->tree()->traverseNext()) {
if (frame->document())
- frame->document()->updatePageUserSheet();
+ frame->document()->styleSheetCollection()->updatePageUserSheet();
}
}
diff --git a/Source/WebCore/page/PageGroup.cpp b/Source/WebCore/page/PageGroup.cpp
index 45d25f552..0fed49138 100644
--- a/Source/WebCore/page/PageGroup.cpp
+++ b/Source/WebCore/page/PageGroup.cpp
@@ -29,6 +29,7 @@
#include "Chrome.h"
#include "ChromeClient.h"
#include "Document.h"
+#include "DocumentStyleSheetCollection.h"
#include "Frame.h"
#include "GroupSettings.h"
#include "Page.h"
@@ -391,7 +392,7 @@ void PageGroup::resetUserStyleCacheInAllFrames()
HashSet<Page*>::const_iterator end = m_pages.end();
for (HashSet<Page*>::const_iterator it = m_pages.begin(); it != end; ++it) {
for (Frame* frame = (*it)->mainFrame(); frame; frame = frame->tree()->traverseNext())
- frame->document()->updatePageGroupUserSheets();
+ frame->document()->styleSheetCollection()->updatePageGroupUserSheets();
}
}
diff --git a/Source/WebCore/page/Settings.cpp b/Source/WebCore/page/Settings.cpp
index df425964d..30666c561 100644
--- a/Source/WebCore/page/Settings.cpp
+++ b/Source/WebCore/page/Settings.cpp
@@ -46,10 +46,12 @@ using namespace std;
namespace WebCore {
-static void setLoadsImagesAutomaticallyInAllFrames(Page* page)
+static void setImageLoadingSettings(Page* page)
{
- for (Frame* frame = page->mainFrame(); frame; frame = frame->tree()->traverseNext())
+ for (Frame* frame = page->mainFrame(); frame; frame = frame->tree()->traverseNext()) {
+ frame->document()->cachedResourceLoader()->setImagesEnabled(page->settings()->areImagesEnabled());
frame->document()->cachedResourceLoader()->setAutoLoadImages(page->settings()->loadsImagesAutomatically());
+ }
}
// Sets the entry in the font map for the given script. If family is the empty string, removes the entry instead.
@@ -291,7 +293,7 @@ Settings::Settings(Page* page)
, m_windowFocusRestricted(true)
, m_diagnosticLoggingEnabled(false)
, m_scrollingPerformanceLoggingEnabled(false)
- , m_loadsImagesAutomaticallyTimer(this, &Settings::loadsImagesAutomaticallyTimerFired)
+ , m_setImageLoadingSettingsTimer(this, &Settings::imageLoadingSettingsTimerFired)
, m_incrementalRenderingSuppressionTimeoutInSeconds(defaultIncrementalRenderingSuppressionTimeoutInSeconds)
{
// A Frame may not have been created yet, so we initialize the AtomicString
@@ -466,12 +468,12 @@ void Settings::setLoadsImagesAutomatically(bool loadsImagesAutomatically)
// Starting these loads synchronously is not important. By putting it on a 0-delay, properly closing the Page cancels them
// before they have a chance to really start.
// See http://webkit.org/b/60572 for more discussion.
- m_loadsImagesAutomaticallyTimer.startOneShot(0);
+ m_setImageLoadingSettingsTimer.startOneShot(0);
}
-void Settings::loadsImagesAutomaticallyTimerFired(Timer<Settings>*)
+void Settings::imageLoadingSettingsTimerFired(Timer<Settings>*)
{
- setLoadsImagesAutomaticallyInAllFrames(m_page);
+ setImageLoadingSettings(m_page);
}
void Settings::setLoadsSiteIconsIgnoringImageLoadingSetting(bool loadsSiteIcons)
@@ -517,6 +519,9 @@ void Settings::setJavaEnabledForLocalFiles(bool isJavaEnabledForLocalFiles)
void Settings::setImagesEnabled(bool areImagesEnabled)
{
m_areImagesEnabled = areImagesEnabled;
+
+ // See comment in setLoadsImagesAutomatically.
+ m_setImageLoadingSettingsTimer.startOneShot(0);
}
void Settings::setMediaEnabled(bool isMediaEnabled)
diff --git a/Source/WebCore/page/Settings.h b/Source/WebCore/page/Settings.h
index 83986f697..c18dfd730 100644
--- a/Source/WebCore/page/Settings.h
+++ b/Source/WebCore/page/Settings.h
@@ -818,8 +818,8 @@ namespace WebCore {
bool m_scrollingPerformanceLoggingEnabled : 1;
- Timer<Settings> m_loadsImagesAutomaticallyTimer;
- void loadsImagesAutomaticallyTimerFired(Timer<Settings>*);
+ Timer<Settings> m_setImageLoadingSettingsTimer;
+ void imageLoadingSettingsTimerFired(Timer<Settings>*);
double m_incrementalRenderingSuppressionTimeoutInSeconds;
diff --git a/Source/WebCore/page/ValidationMessageClient.h b/Source/WebCore/page/ValidationMessageClient.h
index 5c8a3556c..3beaca09f 100644
--- a/Source/WebCore/page/ValidationMessageClient.h
+++ b/Source/WebCore/page/ValidationMessageClient.h
@@ -26,6 +26,8 @@
#ifndef ValidationMessageClient_h
#define ValidationMessageClient_h
+#include <wtf/Forward.h>
+
namespace WebCore {
class Element;
diff --git a/Source/WebCore/page/mac/EventHandlerMac.mm b/Source/WebCore/page/mac/EventHandlerMac.mm
index bd8ee4704..d2020c771 100644
--- a/Source/WebCore/page/mac/EventHandlerMac.mm
+++ b/Source/WebCore/page/mac/EventHandlerMac.mm
@@ -225,9 +225,10 @@ bool EventHandler::passMouseDownEventToWidget(Widget* pWidget)
ASSERT(!m_sendingEventToSubview);
m_sendingEventToSubview = true;
- RenderWidget::suspendWidgetHierarchyUpdates();
- [view mouseDown:currentNSEvent()];
- RenderWidget::resumeWidgetHierarchyUpdates();
+ {
+ WidgetHierarchyUpdatesSuspensionScope suspendWidgetHierarchyUpdates;
+ [view mouseDown:currentNSEvent()];
+ }
m_sendingEventToSubview = false;
diff --git a/Source/WebCore/platform/FractionalLayoutUnit.h b/Source/WebCore/platform/FractionalLayoutUnit.h
index 0f3a86a1f..06be89787 100644
--- a/Source/WebCore/platform/FractionalLayoutUnit.h
+++ b/Source/WebCore/platform/FractionalLayoutUnit.h
@@ -227,6 +227,15 @@ public:
#endif
}
+ FractionalLayoutUnit fraction() const
+ {
+ // Add the fraction to the size (as opposed to the full location) to avoid overflows.
+ // Compute fraction using the mod operator to preserve the sign of the value as it may affect rounding.
+ FractionalLayoutUnit fraction;
+ fraction.setRawValue(rawValue() % kFixedPointDenominator);
+ return fraction;
+ }
+
#if ENABLE(SUBPIXEL_LAYOUT)
static float epsilon() { return 1.0f / kFixedPointDenominator; }
#else
@@ -807,7 +816,7 @@ inline float& operator/=(float& a, const FractionalLayoutUnit& b)
inline int snapSizeToPixel(FractionalLayoutUnit size, FractionalLayoutUnit location)
{
- FractionalLayoutUnit fraction = location - location.floor();
+ FractionalLayoutUnit fraction = location.fraction();
return (fraction + size).round() - fraction.round();
}
diff --git a/Source/WebCore/platform/KURLWTFURL.cpp b/Source/WebCore/platform/KURLWTFURL.cpp
index f030b8719..9a3484d41 100644
--- a/Source/WebCore/platform/KURLWTFURL.cpp
+++ b/Source/WebCore/platform/KURLWTFURL.cpp
@@ -26,7 +26,11 @@
#include "config.h"
#include "KURL.h"
+#include <TextEncoding.h>
#include <wtf/DataLog.h>
+#include <wtf/text/CString.h>
+#include <wtf/url/api/URLBuffer.h>
+#include <wtf/url/api/URLQueryCharsetConverter.h>
#if USE(WTFURL)
@@ -51,29 +55,55 @@ static inline void detach(RefPtr<KURLWTFURLImpl>& urlImpl)
KURL::KURL(ParsedURLStringTag, const String& urlString)
: m_urlImpl(adoptRef(new KURLWTFURLImpl()))
{
- m_urlImpl->m_parsedURL = ParsedURL(urlString);
+ m_urlImpl->m_parsedURL = ParsedURL(urlString, ParsedURL::ParsedURLString);
// FIXME: Frame::init() actually create empty URL, investigate why not just null URL.
// ASSERT(m_urlImpl->m_parsedURL.isValid());
}
+class CharsetConverter : public URLQueryCharsetConverter {
+public:
+ CharsetConverter(const TextEncoding& encoding)
+ : m_encoding(encoding)
+ {
+ }
+
+ virtual void convertFromUTF16(const UChar* input, unsigned inputLength, URLBuffer<char>& output) OVERRIDE
+ {
+ CString encoded = m_encoding.encode(input, inputLength, URLEncodedEntitiesForUnencodables);
+ output.append(encoded.data(), static_cast<int>(encoded.length()));
+ }
+
+private:
+ const TextEncoding& m_encoding;
+};
+
KURL::KURL(const KURL& baseURL, const String& relative)
: m_urlImpl(adoptRef(new KURLWTFURLImpl()))
{
// FIXME: the case with a null baseURL is common. We should have a separate constructor in KURL.
// FIXME: the case of an empty Base is useless, we should get rid of empty URLs.
+ CharsetConverter charsetConverter(UTF8Encoding());
if (baseURL.isEmpty())
- m_urlImpl->m_parsedURL = ParsedURL(relative);
+ m_urlImpl->m_parsedURL = ParsedURL(relative, &charsetConverter);
else
- m_urlImpl->m_parsedURL = ParsedURL(baseURL.m_urlImpl->m_parsedURL, relative);
+ m_urlImpl->m_parsedURL = ParsedURL(baseURL.m_urlImpl->m_parsedURL, relative, &charsetConverter);
if (!m_urlImpl->m_parsedURL.isValid())
m_urlImpl->m_invalidUrlString = relative;
}
-KURL::KURL(const KURL&, const String&, const TextEncoding&)
+KURL::KURL(const KURL& baseURL, const String& relative, const TextEncoding& encoding)
+ : m_urlImpl(adoptRef(new KURLWTFURLImpl()))
{
- // FIXME: Add WTFURL Implementation.
+ CharsetConverter charsetConverter(encoding.encodingForFormSubmission());
+ if (baseURL.isEmpty())
+ m_urlImpl->m_parsedURL = ParsedURL(relative, &charsetConverter);
+ else
+ m_urlImpl->m_parsedURL = ParsedURL(baseURL.m_urlImpl->m_parsedURL, relative, &charsetConverter);
+
+ if (!m_urlImpl->m_parsedURL.isValid())
+ m_urlImpl->m_invalidUrlString = relative;
}
KURL KURL::copy() const
@@ -141,7 +171,10 @@ String KURL::host() const
bool KURL::hasPort() const
{
- ASSERT(isValid());
+ // This should be an ASSERT. HTMLAnchorElement::port() does not check the validity of the URL.
+ if (!isValid())
+ return false;
+
return !m_urlImpl->m_parsedURL.port().isNull();
}
@@ -164,25 +197,37 @@ unsigned short KURL::port() const
String KURL::user() const
{
- ASSERT(isValid());
+ // FIXME: this should be an ASSERT(), call site should not use invalid URLs.
+ if (!isValid())
+ return String();
+
return m_urlImpl->m_parsedURL.username();
}
String KURL::pass() const
{
- ASSERT(isValid());
+ // FIXME: this should be an ASSERT(), call site should not use invalid URLs.
+ if (!isValid())
+ return String();
+
return m_urlImpl->m_parsedURL.password();
}
bool KURL::hasPath() const
{
- ASSERT(isValid());
+ // FIXME: this should be an ASSERTION, call site should not use invalid URLs.
+ if (!isValid())
+ return false;
+
return !path().isEmpty();
}
String KURL::path() const
{
- ASSERT(isValid());
+ // FIXME: this should be an ASSERTION, HTMLAnchorElement should not use invalid URLs.
+ if (!isValid())
+ return String();
+
return m_urlImpl->m_parsedURL.path();
}
@@ -201,7 +246,10 @@ String KURL::lastPathComponent() const
String KURL::query() const
{
- ASSERT(isValid());
+ // FIXME: this should be an ASSERTION, HTMLAnchorElement should not use invalid URLs.
+ if (!isValid())
+ return String();
+
return m_urlImpl->m_parsedURL.query();
}
@@ -221,6 +269,7 @@ String KURL::fragmentIdentifier() const
// ASSERT(isValid());
if (!isValid())
return String();
+
return m_urlImpl->m_parsedURL.fragment();
}
@@ -234,7 +283,7 @@ String KURL::baseAsString() const
// FIXME: Get rid of this function from KURL.
String KURL::fileSystemPath() const
{
- return String();
+ return string();
}
bool KURL::protocolIs(const char* testProtocol) const
diff --git a/Source/WebCore/platform/SharedBuffer.cpp b/Source/WebCore/platform/SharedBuffer.cpp
index 68c3196a7..de5f71dc2 100644
--- a/Source/WebCore/platform/SharedBuffer.cpp
+++ b/Source/WebCore/platform/SharedBuffer.cpp
@@ -29,6 +29,7 @@
#include "PlatformMemoryInstrumentation.h"
#include "PurgeableBuffer.h"
+#include <wtf/MemoryInstrumentationVector.h>
#include <wtf/PassOwnPtr.h>
#include <wtf/unicode/UTF8.h>
#include <wtf/unicode/Unicode.h>
@@ -251,8 +252,8 @@ const Vector<char>& SharedBuffer::buffer() const
void SharedBuffer::reportMemoryUsage(MemoryObjectInfo* memoryObjectInfo) const
{
MemoryClassInfo info(memoryObjectInfo, this);
- info.addVector(m_buffer);
- info.addVector(m_segments);
+ info.addMember(m_buffer);
+ info.addMember(m_segments);
for (unsigned i = 0; i < m_segments.size(); ++i)
info.addRawBuffer(m_segments[i], segmentSize);
info.addMember(m_purgeableBuffer.get());
diff --git a/Source/WebCore/platform/blackberry/AuthenticationChallengeManager.cpp b/Source/WebCore/platform/blackberry/AuthenticationChallengeManager.cpp
deleted file mode 100644
index e40a42b7e..000000000
--- a/Source/WebCore/platform/blackberry/AuthenticationChallengeManager.cpp
+++ /dev/null
@@ -1,253 +0,0 @@
-/*
- * Copyright (C) 2012 Research In Motion Limited. All rights reserved.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
-#include "config.h"
-#include "AuthenticationChallengeManager.h"
-
-#include "Credential.h"
-#include "KURL.h"
-#include "PageClientBlackBerry.h"
-#include "ProtectionSpace.h"
-
-#include <BlackBerryPlatformAssert.h>
-#include <BlackBerryPlatformLog.h>
-#include <wtf/Assertions.h>
-#include <wtf/HashMap.h>
-#include <wtf/Vector.h>
-#include <wtf/text/CString.h>
-
-namespace WebCore {
-
-typedef HashMap<PageClientBlackBerry*, bool> PageVisibilityMap;
-
-struct ChallengeInfo {
- ChallengeInfo(const KURL&, const ProtectionSpace&, const Credential&, AuthenticationChallengeClient*, PageClientBlackBerry*);
-
- KURL url;
- ProtectionSpace space;
- Credential credential;
- AuthenticationChallengeClient* authClient;
- PageClientBlackBerry* pageClient;
- bool blocked;
-};
-
-ChallengeInfo::ChallengeInfo(const KURL& aUrl,
- const ProtectionSpace& aSpace,
- const Credential& aCredential,
- AuthenticationChallengeClient* anAuthClient,
- PageClientBlackBerry* aPageClient)
- : url(aUrl)
- , space(aSpace)
- , credential(aCredential)
- , authClient(anAuthClient)
- , pageClient(aPageClient)
- , blocked(false)
-{
-}
-
-class AuthenticationChallengeManagerPrivate {
-public:
- AuthenticationChallengeManagerPrivate();
-
- bool resumeAuthenticationChallenge(PageClientBlackBerry*);
- void startAuthenticationChallenge(ChallengeInfo*);
- bool pageExists(PageClientBlackBerry*);
-
- ChallengeInfo* m_activeChallenge;
- PageVisibilityMap m_pageVisibilityMap;
- Vector<OwnPtr<ChallengeInfo> > m_challenges;
-};
-
-AuthenticationChallengeManagerPrivate::AuthenticationChallengeManagerPrivate()
- : m_activeChallenge(0)
-{
-}
-
-bool AuthenticationChallengeManagerPrivate::resumeAuthenticationChallenge(PageClientBlackBerry* client)
-{
- ASSERT(!m_activeChallenge);
-
- for (size_t i = 0; i < m_challenges.size(); ++i) {
- if (m_challenges[i]->pageClient == client && m_challenges[i]->blocked) {
- startAuthenticationChallenge(m_challenges[i].get());
- return true;
- }
- }
-
- return false;
-}
-
-void AuthenticationChallengeManagerPrivate::startAuthenticationChallenge(ChallengeInfo* info)
-{
- m_activeChallenge = info;
- m_activeChallenge->blocked = false;
- m_activeChallenge->pageClient->authenticationChallenge(m_activeChallenge->url,
- m_activeChallenge->space,
- m_activeChallenge->credential);
-}
-
-bool AuthenticationChallengeManagerPrivate::pageExists(PageClientBlackBerry* client)
-{
- return m_pageVisibilityMap.find(client) != m_pageVisibilityMap.end();
-}
-
-AuthenticationChallengeManager::AuthenticationChallengeManager()
- : d(adoptPtr(new AuthenticationChallengeManagerPrivate))
-{
-}
-
-void AuthenticationChallengeManager::pageCreated(PageClientBlackBerry* client)
-{
- d->m_pageVisibilityMap.add(client, true);
-}
-
-void AuthenticationChallengeManager::pageDeleted(PageClientBlackBerry* client)
-{
- d->m_pageVisibilityMap.remove(client);
-
- if (d->m_activeChallenge && d->m_activeChallenge->pageClient == client)
- d->m_activeChallenge = 0;
-
- Vector<OwnPtr<ChallengeInfo> > existing;
- d->m_challenges.swap(existing);
-
- for (size_t i = 0; i < existing.size(); ++i) {
- if (existing[i]->pageClient != client)
- d->m_challenges.append(existing[i].release());
- }
-}
-
-void AuthenticationChallengeManager::pageVisibilityChanged(PageClientBlackBerry* client, bool visible)
-{
- PageVisibilityMap::iterator iter = d->m_pageVisibilityMap.find(client);
-
- ASSERT(iter != d->m_pageVisibilityMap.end());
- if (iter == d->m_pageVisibilityMap.end()) {
- d->m_pageVisibilityMap.add(client, visible);
- return;
- }
-
- if (iter->second == visible)
- return;
-
- iter->second = visible;
- if (!visible)
- return;
-
- if (d->m_activeChallenge)
- return;
-
- d->resumeAuthenticationChallenge(client);
-}
-
-void AuthenticationChallengeManager::authenticationChallenge(const KURL& url,
- const ProtectionSpace& space,
- const Credential& credential,
- AuthenticationChallengeClient* authClient,
- PageClientBlackBerry* pageClient)
-{
- BLACKBERRY_ASSERT(authClient);
- BLACKBERRY_ASSERT(pageClient);
-
- ChallengeInfo* info = new ChallengeInfo(url, space, credential, authClient, pageClient);
- d->m_challenges.append(adoptPtr(info));
-
- if (d->m_activeChallenge || !pageClient->isVisible()) {
- info->blocked = true;
- return;
- }
-
- d->startAuthenticationChallenge(info);
-}
-
-void AuthenticationChallengeManager::cancelAuthenticationChallenge(AuthenticationChallengeClient* client)
-{
- BLACKBERRY_ASSERT(client);
-
- if (d->m_activeChallenge && d->m_activeChallenge->authClient == client)
- d->m_activeChallenge = 0;
-
- Vector<OwnPtr<ChallengeInfo> > existing;
- d->m_challenges.swap(existing);
-
- ChallengeInfo* next = 0;
- PageClientBlackBerry* page = 0;
-
- for (size_t i = 0; i < existing.size(); ++i) {
- if (existing[i]->authClient != client) {
- if (page && !next && existing[i]->pageClient == page)
- next = existing[i].get();
- d->m_challenges.append(existing[i].release());
- } else if (d->m_activeChallenge == existing[i].get())
- page = existing[i]->pageClient;
- }
-
- if (next)
- d->startAuthenticationChallenge(next);
-}
-
-void AuthenticationChallengeManager::notifyChallengeResult(const KURL& url,
- const ProtectionSpace& space,
- AuthenticationChallengeResult result,
- const Credential& credential)
-{
- d->m_activeChallenge = 0;
-
- Vector<OwnPtr<ChallengeInfo> > existing;
- d->m_challenges.swap(existing);
-
- ChallengeInfo* next = 0;
- PageClientBlackBerry* page = 0;
-
- for (size_t i = 0; i < existing.size(); ++i) {
- if (existing[i]->space != space) {
- if (page && !next && existing[i]->pageClient == page)
- next = existing[i].get();
- d->m_challenges.append(existing[i].release());
- } else {
- page = existing[i]->pageClient;
- existing[i]->authClient->notifyChallengeResult(existing[i]->url, space, result, credential);
-
- // After calling notifyChallengeResult(), page could be destroyed or something.
- if (!d->pageExists(page) || !page->isVisible())
- page = 0;
- }
- }
-
- if (next)
- d->startAuthenticationChallenge(next);
-}
-
-// Keep following code at the end of this file!!!
-static AuthenticationChallengeManager* s_manager = 0;
-
-AuthenticationChallengeManager* AuthenticationChallengeManager::instance()
-{
- ASSERT(s_manager);
- return s_manager;
-}
-
-void AuthenticationChallengeManager::init()
-{
- ASSERT(!s_manager);
- s_manager = new AuthenticationChallengeManager();
-}
-
-// No more code after this line, all new code should come before s_manager declaration!!!
-
-} // namespace WebCore
diff --git a/Source/WebCore/platform/blackberry/AuthenticationChallengeManager.h b/Source/WebCore/platform/blackberry/AuthenticationChallengeManager.h
index 20e799bb3..52224f511 100644
--- a/Source/WebCore/platform/blackberry/AuthenticationChallengeManager.h
+++ b/Source/WebCore/platform/blackberry/AuthenticationChallengeManager.h
@@ -19,13 +19,8 @@
#ifndef AuthenticationChallengeManager_h
#define AuthenticationChallengeManager_h
-#include <wtf/OwnPtr.h>
-
-class PageClientBlackBerry;
-
namespace WebCore {
-class AuthenticationChallengeManagerPrivate;
class Credential;
class KURL;
class ProtectionSpace;
@@ -40,36 +35,6 @@ public:
virtual void notifyChallengeResult(const KURL&, const ProtectionSpace&, AuthenticationChallengeResult, const Credential&) = 0;
};
-class AuthenticationChallengeManager {
-public:
- static void init();
- static AuthenticationChallengeManager* instance();
-
- void pageCreated(PageClientBlackBerry*);
- void pageDeleted(PageClientBlackBerry*);
- void pageVisibilityChanged(PageClientBlackBerry*, bool visible);
-
- void authenticationChallenge(const KURL&,
- const ProtectionSpace&,
- const Credential&,
- AuthenticationChallengeClient*,
- PageClientBlackBerry*);
-
- void cancelAuthenticationChallenge(AuthenticationChallengeClient*);
-
- void notifyChallengeResult(const KURL&,
- const ProtectionSpace&,
- AuthenticationChallengeResult,
- const Credential&);
-
-private:
- AuthenticationChallengeManager();
- ~AuthenticationChallengeManager();
-
- OwnPtr<AuthenticationChallengeManagerPrivate> d;
-};
-
-
} // namespace WebCore
#endif // AuthenticationChallengeManager_h
diff --git a/Source/WebCore/platform/blackberry/CookieManager.cpp b/Source/WebCore/platform/blackberry/CookieManager.cpp
index 091d7531e..db012bfb4 100644
--- a/Source/WebCore/platform/blackberry/CookieManager.cpp
+++ b/Source/WebCore/platform/blackberry/CookieManager.cpp
@@ -137,6 +137,17 @@ void CookieManager::setCookies(const KURL& url, const String& value, CookieFilte
}
}
+void CookieManager::setCookies(const KURL& url, const Vector<String>& cookies, CookieFilter filter)
+{
+ CookieLog("CookieManager - Setting cookies");
+ CookieParser parser(url);
+ for (size_t i = 0; i < cookies.size(); ++i) {
+ BackingStoreRemovalPolicy treatment = m_privateMode ? DoNotRemoveFromBackingStore : RemoveFromBackingStore;
+ if (ParsedCookie* parsedCookie = parser.parseOneCookie(cookies[i]))
+ checkAndTreatCookie(parsedCookie, treatment, filter);
+ }
+}
+
String CookieManager::getCookie(const KURL& url, CookieFilter filter) const
{
Vector<ParsedCookie*> rawCookies;
diff --git a/Source/WebCore/platform/blackberry/CookieManager.h b/Source/WebCore/platform/blackberry/CookieManager.h
index acb2fcd7a..d334e67fd 100644
--- a/Source/WebCore/platform/blackberry/CookieManager.h
+++ b/Source/WebCore/platform/blackberry/CookieManager.h
@@ -71,6 +71,7 @@ public:
void setCanLocalAccessAllCookies(bool enabled) { m_shouldDumpAllCookies = enabled; }
void setCookies(const KURL&, const String& value, CookieFilter = WithHttpOnlyCookies);
+ void setCookies(const KURL&, const Vector<String>& cookies, CookieFilter);
void removeAllCookies(BackingStoreRemovalPolicy);
void removeCookieWithName(const KURL&, const String& cookieName);
diff --git a/Source/WebCore/platform/blackberry/CookieParser.cpp b/Source/WebCore/platform/blackberry/CookieParser.cpp
index ff6b871b8..dc3580f2b 100644
--- a/Source/WebCore/platform/blackberry/CookieParser.cpp
+++ b/Source/WebCore/platform/blackberry/CookieParser.cpp
@@ -103,6 +103,11 @@ Vector<ParsedCookie*> CookieParser::parse(const String& cookies)
return parsedCookies;
}
+ParsedCookie* CookieParser::parseOneCookie(const String& cookie)
+{
+ return parseOneCookie(cookie, 0, cookie.length() - 1, currentTime());
+}
+
// The cookie String passed into this method will only contian the name value pairs as well as other related cookie
// attributes such as max-age and domain. Set-Cookie should never be part of this string.
ParsedCookie* CookieParser::parseOneCookie(const String& cookie, unsigned start, unsigned end, double curTime)
diff --git a/Source/WebCore/platform/blackberry/CookieParser.h b/Source/WebCore/platform/blackberry/CookieParser.h
index 00fafcfef..aed5e87eb 100644
--- a/Source/WebCore/platform/blackberry/CookieParser.h
+++ b/Source/WebCore/platform/blackberry/CookieParser.h
@@ -45,6 +45,8 @@ public:
// Parses a sequence of "Cookie:" header and return the parsed cookies.
Vector<ParsedCookie*> parse(const String& cookies);
+ ParsedCookie* parseOneCookie(const String& cookie);
+
private:
// FIXME: curTime, start, end parameters should be removed. And this method can be public.
ParsedCookie* parseOneCookie(const String& cookie, unsigned start, unsigned end, double curTime);
diff --git a/Source/WebCore/platform/blackberry/PageClientBlackBerry.h b/Source/WebCore/platform/blackberry/PageClientBlackBerry.h
index f2c7c0e65..bdb2f1607 100644
--- a/Source/WebCore/platform/blackberry/PageClientBlackBerry.h
+++ b/Source/WebCore/platform/blackberry/PageClientBlackBerry.h
@@ -72,7 +72,7 @@ public:
virtual int showAlertDialog(BlackBerry::WebKit::WebPageClient::AlertType) = 0;
virtual bool isActive() const = 0;
virtual bool isVisible() const = 0;
- virtual void authenticationChallenge(const WebCore::KURL&, const WebCore::ProtectionSpace&, const WebCore::Credential&) = 0;
+ virtual void authenticationChallenge(const WebCore::KURL&, const WebCore::ProtectionSpace&, const WebCore::Credential&, WebCore::AuthenticationChallengeClient*) = 0;
virtual SaveCredentialType notifyShouldSaveCredential(bool) = 0;
virtual void syncProxyCredential(const WebCore::Credential&) = 0;
};
diff --git a/Source/WebCore/platform/cairo/WidgetBackingStoreCairo.cpp b/Source/WebCore/platform/cairo/WidgetBackingStoreCairo.cpp
index 1dec7c2e7..69b79efca 100644
--- a/Source/WebCore/platform/cairo/WidgetBackingStoreCairo.cpp
+++ b/Source/WebCore/platform/cairo/WidgetBackingStoreCairo.cpp
@@ -22,7 +22,7 @@
#include "CairoUtilities.h"
#include "RefPtrCairo.h"
-#include <cairo/cairo.h>
+#include <cairo.h>
#if PLATFORM(GTK)
#include "GtkVersioning.h"
diff --git a/Source/WebCore/platform/chromium/PlatformSupport.h b/Source/WebCore/platform/chromium/PlatformSupport.h
index eb1970b8a..7af75b8ef 100644
--- a/Source/WebCore/platform/chromium/PlatformSupport.h
+++ b/Source/WebCore/platform/chromium/PlatformSupport.h
@@ -49,15 +49,6 @@ typedef struct NPObject NPObject;
typedef struct _NPP NPP_t;
typedef NPP_t* NPP;
-#if OS(DARWIN)
-typedef struct CGFont* CGFontRef;
-#ifdef __OBJC__
-@class NSFont;
-#else
-class NSFont;
-#endif
-#endif // OS(DARWIN)
-
#if OS(WINDOWS)
typedef struct HFONT__* HFONT;
#endif
@@ -99,9 +90,6 @@ public:
#if OS(WINDOWS)
static bool ensureFontLoaded(HFONT);
#endif
-#if OS(DARWIN)
- static bool loadFont(NSFont* srcFont, CGFontRef*, uint32_t* fontID);
-#endif
// IndexedDB ----------------------------------------------------------
static PassRefPtr<IDBFactoryBackendInterface> idbFactory();
diff --git a/Source/WebCore/platform/chromium/ScrollbarThemeChromiumAndroid.cpp b/Source/WebCore/platform/chromium/ScrollbarThemeChromiumAndroid.cpp
index 1b9e571b1..6f555fbd1 100644
--- a/Source/WebCore/platform/chromium/ScrollbarThemeChromiumAndroid.cpp
+++ b/Source/WebCore/platform/chromium/ScrollbarThemeChromiumAndroid.cpp
@@ -26,7 +26,6 @@
#include "config.h"
#include "ScrollbarThemeChromiumAndroid.h"
-#include "LayoutTestSupport.h"
#include "PlatformContextSkia.h"
#include "PlatformMouseEvent.h"
#include "PlatformSupport.h"
@@ -50,21 +49,12 @@ ScrollbarTheme* ScrollbarTheme::nativeTheme()
int ScrollbarThemeChromiumAndroid::scrollbarThickness(ScrollbarControlSize controlSize)
{
- if (isRunningLayoutTest()) {
- // Match Chromium-Linux for DumpRenderTree, so the layout test results
- // can be shared. The width of scrollbar down arrow should equal the
- // width of the vertical scrollbar.
- IntSize scrollbarSize = PlatformSupport::getThemePartSize(PlatformSupport::PartScrollbarDownArrow);
- return scrollbarSize.width();
- }
-
return scrollbarWidth + scrollbarMargin;
}
bool ScrollbarThemeChromiumAndroid::usesOverlayScrollbars() const
{
- // In layout test mode, match Chromium-Linux.
- return !isRunningLayoutTest();
+ return true;
}
int ScrollbarThemeChromiumAndroid::thumbPosition(ScrollbarThemeClient* scrollbar)
@@ -92,8 +82,7 @@ int ScrollbarThemeChromiumAndroid::thumbLength(ScrollbarThemeClient* scrollbar)
bool ScrollbarThemeChromiumAndroid::hasThumb(ScrollbarThemeClient* scrollbar)
{
- // In layout test mode, match Chromium-Linux.
- return !isRunningLayoutTest();
+ return true;
}
IntRect ScrollbarThemeChromiumAndroid::backButtonRect(ScrollbarThemeClient*, ScrollbarPart, bool)
@@ -157,12 +146,4 @@ void ScrollbarThemeChromiumAndroid::paintThumb(GraphicsContext* context, Scrollb
fillSmoothEdgedRect(context, thumbRect, Color(128, 128, 128, 128));
}
-void ScrollbarThemeChromiumAndroid::paintScrollbarBackground(GraphicsContext* context, ScrollbarThemeClient* scrollbar)
-{
- // Paint black background in DumpRenderTree, otherwise the pixels in the scrollbar area depend
- // on their previous state, which makes the dumped result undetermined.
- if (isRunningLayoutTest())
- context->fillRect(scrollbar->frameRect(), Color::black, ColorSpaceDeviceRGB);
-}
-
} // namespace WebCore
diff --git a/Source/WebCore/platform/chromium/ScrollbarThemeChromiumAndroid.h b/Source/WebCore/platform/chromium/ScrollbarThemeChromiumAndroid.h
index eab501029..84d647dde 100644
--- a/Source/WebCore/platform/chromium/ScrollbarThemeChromiumAndroid.h
+++ b/Source/WebCore/platform/chromium/ScrollbarThemeChromiumAndroid.h
@@ -46,7 +46,6 @@ public:
virtual IntRect trackRect(ScrollbarThemeClient*, bool painting = false);
virtual void paintThumb(GraphicsContext*, ScrollbarThemeClient*, const IntRect&);
- virtual void paintScrollbarBackground(GraphicsContext*, ScrollbarThemeClient*);
};
} // namespace WebCore
diff --git a/Source/WebCore/platform/clutter/GRefPtrClutter.cpp b/Source/WebCore/platform/clutter/GRefPtrClutter.cpp
deleted file mode 100644
index 2a34186c2..000000000
--- a/Source/WebCore/platform/clutter/GRefPtrClutter.cpp
+++ /dev/null
@@ -1,53 +0,0 @@
-/*
- * Copyright (C) 2011 Collabora Ltd.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
-
-#include "config.h"
-#include "GRefPtrClutter.h"
-
-#include <clutter/clutter.h>
-
-namespace WTF {
-
-template <> GRefPtr<ClutterActor> adoptGRef(ClutterActor* ptr)
-{
- if (g_object_is_floating(ptr))
- g_object_ref_sink(ptr);
-
- return GRefPtr<ClutterActor>(ptr, GRefPtrAdopt);
-}
-
-template <> ClutterActor* refGPtr<ClutterActor>(ClutterActor* ptr)
-{
- if (ptr) {
- if (g_object_is_floating(ptr))
- g_object_ref_sink(ptr);
-
- g_object_ref(ptr);
- }
-
- return ptr;
-}
-
-template <> void derefGPtr<ClutterActor>(ClutterActor* ptr)
-{
- if (ptr)
- g_object_unref(ptr);
-}
-
-}
diff --git a/Source/WebCore/platform/clutter/GRefPtrClutter.h b/Source/WebCore/platform/clutter/GRefPtrClutter.h
deleted file mode 100644
index bdec65481..000000000
--- a/Source/WebCore/platform/clutter/GRefPtrClutter.h
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- * Copyright (C) 2011 Collabora Ltd.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public License
- * along with this library; see the file COPYING.LIB. If not, write to
- * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
- * Boston, MA 02110-1301, USA.
- */
-
-#ifndef GRefPtrClutter_h
-#define GRefPtrClutter_h
-
-#include <wtf/gobject/GRefPtr.h>
-
-typedef struct _ClutterActor ClutterActor;
-
-namespace WTF {
-
-template<> ClutterActor* refGPtr<ClutterActor>(ClutterActor* ptr);
-template<> void derefGPtr<ClutterActor>(ClutterActor* ptr);
-
-}
-
-#endif
diff --git a/Source/WebCore/platform/graphics/BitmapImage.cpp b/Source/WebCore/platform/graphics/BitmapImage.cpp
index 0b1168078..d0a2aabd1 100644
--- a/Source/WebCore/platform/graphics/BitmapImage.cpp
+++ b/Source/WebCore/platform/graphics/BitmapImage.cpp
@@ -34,6 +34,7 @@
#include "PlatformMemoryInstrumentation.h"
#include "Timer.h"
#include <wtf/CurrentTime.h>
+#include <wtf/MemoryInstrumentationVector.h>
#include <wtf/Vector.h>
#include <wtf/text/WTFString.h>
@@ -578,7 +579,7 @@ void BitmapImage::reportMemoryUsage(MemoryObjectInfo* memoryObjectInfo) const
Image::reportMemoryUsage(memoryObjectInfo);
info.addMember(m_source);
info.addMember(m_frameTimer);
- info.addVector(m_frames);
+ info.addMember(m_frames);
for (unsigned i = 0; i < m_frameCount; ++i) {
#if OS(WINCE) && !PLATFORM(QT)
info.addRawBuffer(m_frames[i].m_frame.get(), m_frames[i].m_frameBytes);
diff --git a/Source/WebCore/platform/graphics/BitmapImage.h b/Source/WebCore/platform/graphics/BitmapImage.h
index 10b372948..3f23dcedf 100644
--- a/Source/WebCore/platform/graphics/BitmapImage.h
+++ b/Source/WebCore/platform/graphics/BitmapImage.h
@@ -87,7 +87,6 @@ public:
// Clear the cached image data on the frame, and (optionally) the metadata.
// Returns whether there was cached image data to clear.
bool clear(bool clearMetadata);
- void reportMemoryUsage(MemoryObjectInfo*) const;
NativeImagePtr m_frame;
ImageOrientation m_orientation;
diff --git a/Source/WebCore/platform/graphics/blackberry/MediaPlayerPrivateBlackBerry.cpp b/Source/WebCore/platform/graphics/blackberry/MediaPlayerPrivateBlackBerry.cpp
index d696ad199..867d8158c 100644
--- a/Source/WebCore/platform/graphics/blackberry/MediaPlayerPrivateBlackBerry.cpp
+++ b/Source/WebCore/platform/graphics/blackberry/MediaPlayerPrivateBlackBerry.cpp
@@ -21,7 +21,6 @@
#if ENABLE(VIDEO)
#include "MediaPlayerPrivateBlackBerry.h"
-#include "AuthenticationChallengeManager.h"
#include "CookieManager.h"
#include "Credential.h"
#include "CredentialStorage.h"
@@ -115,7 +114,6 @@ MediaPlayerPrivate::MediaPlayerPrivate(MediaPlayer* player)
, m_userDrivenSeekTimer(this, &MediaPlayerPrivate::userDrivenSeekTimerFired)
, m_lastSeekTime(0)
, m_lastSeekTimePending(false)
- , m_isAuthenticationChallenging(false)
, m_waitMetadataTimer(this, &MediaPlayerPrivate::waitMetadataTimerFired)
, m_waitMetadataPopDialogCounter(0)
{
@@ -123,9 +121,6 @@ MediaPlayerPrivate::MediaPlayerPrivate(MediaPlayer* player)
MediaPlayerPrivate::~MediaPlayerPrivate()
{
- if (m_isAuthenticationChallenging)
- AuthenticationChallengeManager::instance()->cancelAuthenticationChallenge(this);
-
if (isFullscreen()) {
m_webCorePlayer->mediaPlayerClient()->mediaPlayerExitFullscreen();
}
@@ -352,13 +347,16 @@ void MediaPlayerPrivate::paint(GraphicsContext* context, const IntRect& rect)
return;
#if USE(ACCELERATED_COMPOSITING)
- // Only process paint calls coming via the accelerated compositing code
- // path, where we get called with a null graphics context. See
- // LayerCompositingThread::drawTextures(). Ignore calls from the regular
- // rendering path.
- if (!context)
- m_platformPlayer->notifyOutputUpdate(BlackBerry::Platform::IntRect(rect.x(), rect.y(), rect.width(), rect.height()));
- return;
+ if (supportsAcceleratedRendering()) {
+ // Only process paint calls coming via the accelerated compositing code
+ // path, where we get called with a null graphics context. See
+ // LayerCompositingThread::drawTextures(). Ignore calls from the regular
+ // rendering path.
+ if (!context)
+ m_platformPlayer->notifyOutputUpdate(BlackBerry::Platform::IntRect(rect.x(), rect.y(), rect.width(), rect.height()));
+
+ return;
+ }
#endif
paintCurrentFrameInContext(context, rect);
@@ -545,7 +543,7 @@ void MediaPlayerPrivate::updateStates()
m_showBufferingImage = false;
m_mediaIsBuffering = false;
// Create platform layer for video (create hole punch rect).
- if (!m_platformLayer)
+ if (!m_platformLayer && supportsAcceleratedRendering())
m_platformLayer = VideoLayerWebKitThread::create(m_webCorePlayer);
#endif
break;
@@ -715,18 +713,12 @@ void MediaPlayerPrivate::onAuthenticationNeeded(MMRAuthChallenge& authChallenge)
return;
}
- m_isAuthenticationChallenging = true;
- AuthenticationChallengeManager::instance()->authenticationChallenge(url,
- protectionSpace,
- credential,
- this,
- m_webCorePlayer->mediaPlayerClient()->mediaPlayerHostWindow()->platformPageClient());
+ if (frameView() && frameView()->hostWindow())
+ frameView()->hostWindow()->platformPageClient()->authenticationChallenge(url, protectionSpace, credential, this);
}
void MediaPlayerPrivate::notifyChallengeResult(const KURL& url, const ProtectionSpace& protectionSpace, AuthenticationChallengeResult result, const Credential& credential)
{
- m_isAuthenticationChallenging = false;
-
if (result != AuthenticationChallengeSuccess || !url.isValid())
return;
@@ -831,6 +823,13 @@ bool MediaPlayerPrivate::isTabVisible() const
return m_webCorePlayer->mediaPlayerClient()->mediaPlayerHostWindow()->platformPageClient()->isVisible();
}
+bool MediaPlayerPrivate::supportsAcceleratedRendering() const
+{
+ if (m_platformPlayer)
+ return m_platformPlayer->supportsAcceleratedRendering();
+ return false;
+}
+
#if USE(ACCELERATED_COMPOSITING)
static const double BufferingAnimationDelay = 1.0 / 24;
static char* s_bufferingImageData = 0;
diff --git a/Source/WebCore/platform/graphics/blackberry/MediaPlayerPrivateBlackBerry.h b/Source/WebCore/platform/graphics/blackberry/MediaPlayerPrivateBlackBerry.h
index 5a083b59e..2629e04f6 100644
--- a/Source/WebCore/platform/graphics/blackberry/MediaPlayerPrivateBlackBerry.h
+++ b/Source/WebCore/platform/graphics/blackberry/MediaPlayerPrivateBlackBerry.h
@@ -96,7 +96,7 @@ public:
#if USE(ACCELERATED_COMPOSITING)
// Whether accelerated rendering is supported by the media engine for the current media.
- virtual bool supportsAcceleratedRendering() const { return true; }
+ virtual bool supportsAcceleratedRendering() const;
// Called when the rendering system flips the into or out of accelerated rendering mode.
virtual void acceleratedRenderingStateChanged() { }
#endif
@@ -174,7 +174,6 @@ private:
Timer<MediaPlayerPrivate> m_userDrivenSeekTimer;
float m_lastSeekTime;
bool m_lastSeekTimePending;
- bool m_isAuthenticationChallenging;
void waitMetadataTimerFired(Timer<MediaPlayerPrivate>*);
Timer<MediaPlayerPrivate> m_waitMetadataTimer;
int m_waitMetadataPopDialogCounter;
diff --git a/Source/WebCore/platform/graphics/chromium/CrossProcessFontLoading.mm b/Source/WebCore/platform/graphics/chromium/CrossProcessFontLoading.mm
index c0f10dc6b..a10956366 100644
--- a/Source/WebCore/platform/graphics/chromium/CrossProcessFontLoading.mm
+++ b/Source/WebCore/platform/graphics/chromium/CrossProcessFontLoading.mm
@@ -30,8 +30,10 @@
#import "CrossProcessFontLoading.h"
#import "../graphics/FontPlatformData.h"
-#import "PlatformSupport.h"
+#include "LinkHash.h"
#import <AppKit/NSFont.h>
+#import <public/Platform.h>
+#import <public/mac/WebSandboxSupport.h>
#import <wtf/HashMap.h>
namespace WebCore {
@@ -121,7 +123,15 @@ PassRefPtr<MemoryActivatedFont> loadFontFromBrowserProcess(NSFont* nsFont)
CGFontRef tmpCGFont;
uint32_t fontID;
// Send cross-process request to load font.
- if (!PlatformSupport::loadFont(nsFont, &tmpCGFont, &fontID))
+ WebKit::WebSandboxSupport* sandboxSupport = WebKit::Platform::current()->sandboxSupport();
+ if (!sandboxSupport) {
+ // This function should only be called in response to an error loading a
+ // font due to being blocked by the sandbox.
+ // This by definition shouldn't happen if there is no sandbox support.
+ ASSERT_NOT_REACHED();
+ return 0;
+ }
+ if (!sandboxSupport->loadFont(nsFont, &tmpCGFont, &fontID))
return 0;
RetainPtr<CGFontRef> cgFont(tmpCGFont);
@@ -129,7 +139,7 @@ PassRefPtr<MemoryActivatedFont> loadFontFromBrowserProcess(NSFont* nsFont)
// the ID cache.
font = fontCacheByFontID().get(fontID);
if (font)
- // FIXME: PlatformSupport::loadFont() should consult the id cache
+ // FIXME: WebSandboxSupport::loadFont() should consult the id cache
// before activating the font.
return font;
diff --git a/Source/WebCore/platform/graphics/clutter/GraphicsLayerClutter.h b/Source/WebCore/platform/graphics/clutter/GraphicsLayerClutter.h
index 42f6b76f9..3e142e487 100644
--- a/Source/WebCore/platform/graphics/clutter/GraphicsLayerClutter.h
+++ b/Source/WebCore/platform/graphics/clutter/GraphicsLayerClutter.h
@@ -29,10 +29,10 @@
#if USE(ACCELERATED_COMPOSITING)
-#include "GRefPtrClutter.h"
#include "GraphicsLayer.h"
#include <clutter/clutter.h>
+#include <wtf/gobject/GRefPtr.h>
namespace WebCore {
diff --git a/Source/WebCore/platform/graphics/clutter/PlatformClutterLayerClient.h b/Source/WebCore/platform/graphics/clutter/PlatformClutterLayerClient.h
new file mode 100644
index 000000000..90b56ab6a
--- /dev/null
+++ b/Source/WebCore/platform/graphics/clutter/PlatformClutterLayerClient.h
@@ -0,0 +1,51 @@
+/*
+ * Copyright (C) 2010 Apple Inc. All rights reserved.
+ * Copyright (C) 2011 Collabora Ltd.
+ *
+ * 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.
+ */
+
+#ifndef PlatformClutterLayerClient_h
+#define PlatformClutterLayerClient_h
+
+#if USE(ACCELERATED_COMPOSITING)
+
+#include "GraphicsContext.h"
+#include "GraphicsLayer.h"
+
+namespace WebCore {
+
+class PlatformClutterLayerClient {
+public:
+ virtual void platformClutterLayerPaintContents(GraphicsContext&, const IntRect& inClip) = 0;
+ virtual void platformClutterLayerAnimationStarted(double startTime) = 0;
+
+protected:
+ virtual ~PlatformClutterLayerClient() { }
+};
+
+}
+
+#endif // USE(ACCELERATED_COMPOSITING)
+
+#endif // PlatformClutterLayerClient_h
+
diff --git a/Source/WebCore/platform/graphics/clutter/TransformationMatrixClutter.cpp b/Source/WebCore/platform/graphics/clutter/TransformationMatrixClutter.cpp
new file mode 100644
index 000000000..d5c3f2ae4
--- /dev/null
+++ b/Source/WebCore/platform/graphics/clutter/TransformationMatrixClutter.cpp
@@ -0,0 +1,54 @@
+/*
+ * Copyright (C) 2011 Collabora Ltd.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA
+ */
+
+#include "config.h"
+#include "TransformationMatrix.h"
+
+#include <cogl/cogl.h>
+
+namespace WebCore {
+
+TransformationMatrix::operator CoglMatrix() const
+{
+ CoglMatrix matrix;
+
+ matrix.xx = m11();
+ matrix.xy = m21();
+ matrix.xz = m31();
+ matrix.xw = m41();
+
+ matrix.yx = m12();
+ matrix.yy = m22();
+ matrix.yz = m32();
+ matrix.yw = m42();
+
+ matrix.zx = m13();
+ matrix.zy = m23();
+ matrix.zz = m33();
+ matrix.zw = m43();
+
+ matrix.wx = m14();
+ matrix.wy = m24();
+ matrix.wz = m34();
+ matrix.ww = m44();
+
+ return matrix;
+}
+
+}
diff --git a/Source/WebCore/platform/graphics/mac/ComplexTextController.cpp b/Source/WebCore/platform/graphics/mac/ComplexTextController.cpp
index edc74fbb5..3553a9780 100644
--- a/Source/WebCore/platform/graphics/mac/ComplexTextController.cpp
+++ b/Source/WebCore/platform/graphics/mac/ComplexTextController.cpp
@@ -575,14 +575,8 @@ void ComplexTextController::adjustGlyphsAndAdvances()
nextCh = *(m_complexTextRuns[r + 1]->characters() + m_complexTextRuns[r + 1]->indexAt(0));
bool treatAsSpace = Font::treatAsSpace(ch);
- CGGlyph glyph = glyphs[i];
- CGSize advance = advances[i];
- // FIXME: We should find a way to substitute spaces for characters that are treated as spaces
- // before handing them off to Core Text, so that kerning can be applied as if they were spaces.
- if (treatAsSpace && ch != ' ') {
- glyph = fontData->spaceGlyph();
- advance.width = spaceWidth;
- }
+ CGGlyph glyph = treatAsSpace ? fontData->spaceGlyph() : glyphs[i];
+ CGSize advance = treatAsSpace ? CGSizeMake(spaceWidth, advances[i].height) : advances[i];
if (ch == '\t' && m_run.allowTabs())
advance.width = m_font.tabWidth(*fontData, m_run.tabSize(), m_run.xPos() + m_totalWidth + widthSinceLastCommit);
diff --git a/Source/WebCore/platform/graphics/opengl/Extensions3DOpenGLCommon.cpp b/Source/WebCore/platform/graphics/opengl/Extensions3DOpenGLCommon.cpp
index a3c056591..60f6bfaf3 100644
--- a/Source/WebCore/platform/graphics/opengl/Extensions3DOpenGLCommon.cpp
+++ b/Source/WebCore/platform/graphics/opengl/Extensions3DOpenGLCommon.cpp
@@ -125,7 +125,7 @@ String Extensions3DOpenGLCommon::getTranslatedShaderSourceANGLE(Platform3DObject
#if PLATFORM(MAC)
const char* vendor = reinterpret_cast<const char*>(::glGetString(GL_VENDOR));
- if (vendor && (std::strstr(vendor, "ATI") || std::strstr(vendor, "AMD")))
+ if (vendor && (std::strstr(vendor, "ATI") || std::strstr(vendor, "AMD") || std::strstr(vendor, "Intel")))
extraCompileOptions |= SH_EMULATE_BUILT_IN_FUNCTIONS;
#endif
diff --git a/Source/WebCore/platform/graphics/transforms/TransformationMatrix.h b/Source/WebCore/platform/graphics/transforms/TransformationMatrix.h
index cd1db5e03..9eda74608 100644
--- a/Source/WebCore/platform/graphics/transforms/TransformationMatrix.h
+++ b/Source/WebCore/platform/graphics/transforms/TransformationMatrix.h
@@ -34,6 +34,9 @@
#if USE(CA)
typedef struct CATransform3D CATransform3D;
#endif
+#if USE(CLUTTER)
+typedef struct _CoglMatrix CoglMatrix;
+#endif
#if USE(CG)
typedef struct CGAffineTransform CGAffineTransform;
#elif USE(CAIRO)
@@ -324,6 +327,9 @@ public:
TransformationMatrix(const CATransform3D&);
operator CATransform3D() const;
#endif
+#if USE(CLUTTER)
+ operator CoglMatrix() const;
+#endif
#if USE(CG)
TransformationMatrix(const CGAffineTransform&);
operator CGAffineTransform() const;
diff --git a/Source/WebCore/platform/gtk/GtkInputMethodFilter.cpp b/Source/WebCore/platform/gtk/GtkInputMethodFilter.cpp
index da0ec7fa0..8696ef37a 100644
--- a/Source/WebCore/platform/gtk/GtkInputMethodFilter.cpp
+++ b/Source/WebCore/platform/gtk/GtkInputMethodFilter.cpp
@@ -292,7 +292,7 @@ void GtkInputMethodFilter::handleCommit(const char* compositionString)
if (!m_enabled)
return;
- m_confirmedComposition += String::fromUTF8(compositionString);
+ m_confirmedComposition.append(String::fromUTF8(compositionString));
// If the commit was triggered outside of a key event, just send
// the IME event now. If we are handling a key event, we'll decide
diff --git a/Source/WebCore/platform/gtk/GtkWidgetBackingStoreX11.cpp b/Source/WebCore/platform/gtk/GtkWidgetBackingStoreX11.cpp
index afead805b..60376bc77 100644
--- a/Source/WebCore/platform/gtk/GtkWidgetBackingStoreX11.cpp
+++ b/Source/WebCore/platform/gtk/GtkWidgetBackingStoreX11.cpp
@@ -22,8 +22,8 @@
#include "GtkVersioning.h"
#include "RefPtrCairo.h"
#include <X11/Xlib.h>
-#include <cairo/cairo-xlib.h>
-#include <cairo/cairo.h>
+#include <cairo-xlib.h>
+#include <cairo.h>
#include <gdk/gdkx.h>
namespace WebCore {
diff --git a/Source/WebCore/platform/mac/KURLMac.mm b/Source/WebCore/platform/mac/KURLMac.mm
index 9efbee0d8..d5c25e147 100644
--- a/Source/WebCore/platform/mac/KURLMac.mm
+++ b/Source/WebCore/platform/mac/KURLMac.mm
@@ -53,7 +53,7 @@ KURL::KURL(NSURL *url)
#else
m_urlImpl = adoptRef(new KURLWTFURLImpl());
String urlString(bytes, bytesLength);
- m_urlImpl->m_parsedURL = ParsedURL(urlString);
+ m_urlImpl->m_parsedURL = ParsedURL(urlString, 0);
if (!m_urlImpl->m_parsedURL.isValid())
m_urlImpl->m_invalidUrlString = urlString;
#endif // USE(WTFURL)
diff --git a/Source/WebCore/platform/mock/GeolocationClientMock.cpp b/Source/WebCore/platform/mock/GeolocationClientMock.cpp
index 276b4a343..9901b66aa 100644
--- a/Source/WebCore/platform/mock/GeolocationClientMock.cpp
+++ b/Source/WebCore/platform/mock/GeolocationClientMock.cpp
@@ -1,5 +1,6 @@
/*
* Copyright (C) 2010 Google Inc. All rights reserved.
+ * Copyright (C) 2012 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
@@ -41,6 +42,7 @@ namespace WebCore {
GeolocationClientMock::GeolocationClientMock()
: m_controller(0)
+ , m_hasError(false)
, m_controllerTimer(this, &GeolocationClientMock::controllerTimerFired)
, m_permissionTimer(this, &GeolocationClientMock::permissionTimerFired)
, m_isActive(false)
@@ -62,14 +64,15 @@ void GeolocationClientMock::setController(GeolocationController *controller)
void GeolocationClientMock::setPosition(PassRefPtr<GeolocationPosition> position)
{
m_lastPosition = position;
- m_lastError = 0;
+ clearError();
asyncUpdateController();
}
-void GeolocationClientMock::setError(PassRefPtr<GeolocationError> error)
+void GeolocationClientMock::setPositionUnavailableError(const String& errorMessage)
{
- m_lastError = error;
- m_lastPosition = 0;
+ m_hasError = true;
+ m_errorMessage = errorMessage;
+ m_lastPosition = nullptr;
asyncUpdateController();
}
@@ -125,7 +128,7 @@ void GeolocationClientMock::permissionTimerFired(WebCore::Timer<GeolocationClien
void GeolocationClientMock::reset()
{
m_lastPosition = 0;
- m_lastError = 0;
+ clearError();
m_permissionState = PermissionStateUnset;
}
@@ -171,10 +174,19 @@ void GeolocationClientMock::controllerTimerFired(Timer<GeolocationClientMock>* t
ASSERT_UNUSED(timer, timer == &m_controllerTimer);
ASSERT(m_controller);
- if (m_lastPosition.get())
+ if (m_lastPosition.get()) {
+ ASSERT(!m_hasError);
m_controller->positionChanged(m_lastPosition.get());
- else if (m_lastError.get())
- m_controller->errorOccurred(m_lastError.get());
+ } else if (m_hasError) {
+ RefPtr<GeolocationError> geolocatioError = GeolocationError::create(GeolocationError::PositionUnavailable, m_errorMessage);
+ m_controller->errorOccurred(geolocatioError.get());
+ }
+}
+
+void GeolocationClientMock::clearError()
+{
+ m_hasError = false;
+ m_errorMessage = String();
}
} // WebCore
diff --git a/Source/WebCore/platform/mock/GeolocationClientMock.h b/Source/WebCore/platform/mock/GeolocationClientMock.h
index 8abd5e970..f380c1443 100644
--- a/Source/WebCore/platform/mock/GeolocationClientMock.h
+++ b/Source/WebCore/platform/mock/GeolocationClientMock.h
@@ -1,5 +1,6 @@
/*
* Copyright (C) 2010 Google Inc. All rights reserved.
+ * Copyright (C) 2012 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
@@ -42,9 +43,9 @@ namespace WebCore {
class GeolocationController;
class GeolocationPosition;
-class GeolocationError;
-// Provides a mock object for the geolocation client
+// FIXME: this should not be in WebCore. It should be moved to WebKit.
+// Provides a mock object for the geolocation client.
class GeolocationClientMock : public GeolocationClient {
public:
GeolocationClientMock();
@@ -53,8 +54,8 @@ public:
void reset();
void setController(GeolocationController*);
- void setError(PassRefPtr<GeolocationError>);
void setPosition(PassRefPtr<GeolocationPosition>);
+ void setPositionUnavailableError(const String& errorMessage);
void setPermission(bool allowed);
int numberOfPendingPermissionRequests() const;
@@ -74,9 +75,12 @@ private:
void asyncUpdatePermission();
void permissionTimerFired(Timer<GeolocationClientMock>*);
+ void clearError();
+
GeolocationController* m_controller;
RefPtr<GeolocationPosition> m_lastPosition;
- RefPtr<GeolocationError> m_lastError;
+ bool m_hasError;
+ String m_errorMessage;
Timer<GeolocationClientMock> m_controllerTimer;
Timer<GeolocationClientMock> m_permissionTimer;
bool m_isActive;
diff --git a/Source/WebCore/platform/network/FormData.cpp b/Source/WebCore/platform/network/FormData.cpp
index 45f730248..43a71af1a 100644
--- a/Source/WebCore/platform/network/FormData.cpp
+++ b/Source/WebCore/platform/network/FormData.cpp
@@ -37,6 +37,7 @@
#include "TextEncoding.h"
#include <wtf/Decoder.h>
#include <wtf/Encoder.h>
+#include <wtf/MemoryInstrumentationVector.h>
namespace WebCore {
@@ -360,7 +361,7 @@ void FormData::removeGeneratedFilesIfNeeded()
void FormData::reportMemoryUsage(MemoryObjectInfo* memoryObjectInfo) const
{
MemoryClassInfo info(memoryObjectInfo, this, PlatformMemoryTypes::Loader);
- info.addVector(m_boundary);
+ info.addMember(m_boundary);
}
static void encode(Encoder& encoder, const FormDataElement& element)
diff --git a/Source/WebCore/platform/network/ResourceRequestBase.cpp b/Source/WebCore/platform/network/ResourceRequestBase.cpp
index 00f583905..303deaa9c 100644
--- a/Source/WebCore/platform/network/ResourceRequestBase.cpp
+++ b/Source/WebCore/platform/network/ResourceRequestBase.cpp
@@ -28,6 +28,7 @@
#include "PlatformMemoryInstrumentation.h"
#include "ResourceRequest.h"
+#include <wtf/MemoryInstrumentationVector.h>
using namespace std;
@@ -452,7 +453,7 @@ void ResourceRequestBase::reportMemoryUsage(MemoryObjectInfo* memoryObjectInfo)
info.addMember(m_httpMethod);
info.addHashMap(m_httpHeaderFields);
info.addInstrumentedMapEntries(m_httpHeaderFields);
- info.addInstrumentedVector(m_responseContentDispositionEncodingFallbackArray);
+ info.addMember(m_responseContentDispositionEncodingFallbackArray);
info.addMember(m_httpBody);
}
diff --git a/Source/WebCore/platform/network/blackberry/CredentialBackingStore.cpp b/Source/WebCore/platform/network/blackberry/CredentialBackingStore.cpp
index f60c6c212..b08a84110 100644
--- a/Source/WebCore/platform/network/blackberry/CredentialBackingStore.cpp
+++ b/Source/WebCore/platform/network/blackberry/CredentialBackingStore.cpp
@@ -265,7 +265,7 @@ ProtectionSpace CredentialBackingStore::getProtectionSpace(const KURL& url)
int result = m_getLoginByURLStatement->step();
String username = m_getLoginByURLStatement->getColumnText(0);
- String password = m_usingCertManager ? "" : m_getLoginByURLStatement->getColumnBlobAsString(1);
+ String password = certMgrWrapper()->isReady() ? "" : m_getLoginByURLStatement->getColumnBlobAsString(1);
String host = m_getLoginByURLStatement->getColumnText(2);
int port = m_getLoginByURLStatement->getColumnInt(3);
int serviceType = m_getLoginByURLStatement->getColumnInt(4);
diff --git a/Source/WebCore/platform/network/blackberry/NetworkJob.cpp b/Source/WebCore/platform/network/blackberry/NetworkJob.cpp
index cca89b520..98ebe6059 100644
--- a/Source/WebCore/platform/network/blackberry/NetworkJob.cpp
+++ b/Source/WebCore/platform/network/blackberry/NetworkJob.cpp
@@ -19,7 +19,6 @@
#include "config.h"
#include "NetworkJob.h"
-#include "AuthenticationChallengeManager.h"
#include "Chrome.h"
#include "ChromeClient.h"
#include "CookieManager.h"
@@ -85,16 +84,9 @@ NetworkJob::NetworkJob()
, m_deferredData(*this)
, m_deferLoadingCount(0)
, m_frame(0)
- , m_isAuthenticationChallenging(false)
{
}
-NetworkJob::~NetworkJob()
-{
- if (m_isAuthenticationChallenging)
- AuthenticationChallengeManager::instance()->cancelAuthenticationChallenge(this);
-}
-
bool NetworkJob::initialize(int playerId,
const String& pageGroupName,
const KURL& url,
@@ -211,8 +203,10 @@ void NetworkJob::handleNotifyStatusReceived(int status, const String& message)
m_response.setHTTPStatusText(message);
- if (isUnauthorized(m_extendedStatusCode))
+ if (isUnauthorized(m_extendedStatusCode)) {
purgeCredentials();
+ BlackBerry::Platform::log(BlackBerry::Platform::LogLevelCritical, "Authentication failed, purge the stored credentials for this site.");
+ }
}
void NetworkJob::notifyHeadersReceived(BlackBerry::Platform::NetworkRequest::HeaderList& headers)
@@ -490,7 +484,6 @@ void NetworkJob::handleNotifyClose(int status)
#ifndef NDEBUG
m_isRunning = false;
#endif
-
if (!m_cancelled) {
if (!m_statusReceived) {
// Connection failed before sending notifyStatusReceived: use generic NetworkError.
@@ -502,7 +495,6 @@ void NetworkJob::handleNotifyClose(int status)
m_extendedStatusCode = BlackBerry::Platform::FilterStream::StatusTooManyRedirects;
sendResponseIfNeeded();
-
if (isClientAvailable()) {
if (isError(status))
m_extendedStatusCode = status;
@@ -775,15 +767,7 @@ bool NetworkJob::sendRequestWithCredentials(ProtectionSpaceServerType type, Prot
return false;
m_handle->getInternal()->m_currentWebChallenge = AuthenticationChallenge();
-
- m_isAuthenticationChallenging = true;
- updateDeferLoadingCount(1);
-
- AuthenticationChallengeManager::instance()->authenticationChallenge(newURL,
- protectionSpace,
- Credential(),
- this,
- m_frame->page()->chrome()->client()->platformPageClient());
+ m_frame->page()->chrome()->client()->platformPageClient()->authenticationChallenge(newURL, protectionSpace, Credential(), this);
return true;
}
@@ -844,17 +828,11 @@ void NetworkJob::fireDeleteJobTimer(Timer<NetworkJob>*)
void NetworkJob::notifyChallengeResult(const KURL& url, const ProtectionSpace& protectionSpace, AuthenticationChallengeResult result, const Credential& credential)
{
- m_isAuthenticationChallenging = false;
-
if (result != AuthenticationChallengeSuccess || protectionSpace.host().isEmpty() || !url.isValid()) {
m_newJobWithCredentialsStarted = false;
- updateDeferLoadingCount(-1);
return;
}
- cancelJob();
- updateDeferLoadingCount(-1);
-
if (m_handle->getInternal()->m_currentWebChallenge.isNull())
m_handle->getInternal()->m_currentWebChallenge = AuthenticationChallenge(protectionSpace, credential, 0, m_response, ResourceError());
diff --git a/Source/WebCore/platform/network/blackberry/NetworkJob.h b/Source/WebCore/platform/network/blackberry/NetworkJob.h
index 8bfb46708..3526374ab 100644
--- a/Source/WebCore/platform/network/blackberry/NetworkJob.h
+++ b/Source/WebCore/platform/network/blackberry/NetworkJob.h
@@ -29,7 +29,6 @@
#include <network/FilterStream.h>
#include <wtf/OwnPtr.h>
#include <wtf/RefPtr.h>
-#include <wtf/Vector.h>
#include <wtf/text/WTFString.h>
namespace BlackBerry {
@@ -50,8 +49,6 @@ class ResourceRequest;
class NetworkJob : public AuthenticationChallengeClient, public BlackBerry::Platform::FilterStream {
public:
NetworkJob();
- ~NetworkJob();
-
bool initialize(int playerId,
const String& pageGroupName,
const KURL&,
@@ -174,8 +171,6 @@ private:
DeferredData m_deferredData;
int m_deferLoadingCount;
const Frame* m_frame;
-
- bool m_isAuthenticationChallenging;
};
} // namespace WebCore
diff --git a/Source/WebCore/platform/text/mac/LocaleMac.h b/Source/WebCore/platform/text/mac/LocaleMac.h
index 26ca6a220..0e48c2e96 100644
--- a/Source/WebCore/platform/text/mac/LocaleMac.h
+++ b/Source/WebCore/platform/text/mac/LocaleMac.h
@@ -47,6 +47,7 @@ class DateComponents;
class LocaleMac : public Localizer {
public:
static PassOwnPtr<LocaleMac> create(const String&);
+ static PassOwnPtr<LocaleMac> create(NSLocale*);
static LocaleMac* currentLocale();
~LocaleMac();
double parseDate(const String&);
@@ -67,7 +68,6 @@ public:
private:
explicit LocaleMac(NSLocale*);
- explicit LocaleMac(const String&);
NSDateFormatter *createShortDateFormatter();
virtual void initializeLocalizerData() OVERRIDE;
diff --git a/Source/WebCore/platform/text/mac/LocaleMac.mm b/Source/WebCore/platform/text/mac/LocaleMac.mm
index 91ece4d06..e381c022d 100644
--- a/Source/WebCore/platform/text/mac/LocaleMac.mm
+++ b/Source/WebCore/platform/text/mac/LocaleMac.mm
@@ -45,9 +45,30 @@ using namespace std;
namespace WebCore {
+static inline String languageFromLocale(const String& locale)
+{
+ String normalizedLocale = locale;
+ normalizedLocale.replace('-', '_');
+ size_t separatorPosition = normalizedLocale.find('_');
+ if (separatorPosition == notFound)
+ return normalizedLocale;
+ return normalizedLocale.left(separatorPosition);
+}
+
+static NSLocale* determineLocale(const String& locale)
+{
+ NSLocale* currentLocale = [NSLocale currentLocale];
+ String currentLocaleLanguage = languageFromLocale(String([currentLocale localeIdentifier]));
+ String localeLanguage = languageFromLocale(locale);
+ if (equalIgnoringCase(currentLocaleLanguage, localeLanguage))
+ return currentLocale;
+ // It seems initWithLocaleIdentifier accepts dash-separated locale identifier.
+ return [[NSLocale alloc] initWithLocaleIdentifier:locale];
+}
+
PassOwnPtr<Localizer> Localizer::create(const AtomicString& locale)
{
- return LocaleMac::create(locale.string());
+ return LocaleMac::create(determineLocale(locale.string()));
}
static NSDateFormatter* createDateTimeFormatter(NSLocale* locale, NSDateFormatterStyle dateStyle, NSDateFormatterStyle timeStyle)
@@ -65,12 +86,6 @@ LocaleMac::LocaleMac(NSLocale* locale)
: m_locale(locale)
, m_didInitializeNumberData(false)
{
-}
-
-LocaleMac::LocaleMac(const String& localeIdentifier)
- : m_locale([[NSLocale alloc] initWithLocaleIdentifier:localeIdentifier])
- , m_didInitializeNumberData(false)
-{
NSArray* availableLanguages = [NSLocale ISOLanguageCodes];
// NSLocale returns a lower case NSLocaleLanguageCode so we don't have care about case.
NSString* language = [m_locale.get() objectForKey:NSLocaleLanguageCode];
@@ -84,33 +99,17 @@ LocaleMac::~LocaleMac()
PassOwnPtr<LocaleMac> LocaleMac::create(const String& localeIdentifier)
{
- return adoptPtr(new LocaleMac(localeIdentifier));
+ return adoptPtr(new LocaleMac([[NSLocale alloc] initWithLocaleIdentifier:localeIdentifier]));
}
-static inline String languageFromLocale(const String& locale)
+PassOwnPtr<LocaleMac> LocaleMac::create(NSLocale* locale)
{
- String normalizedLocale = locale;
- normalizedLocale.replace('-', '_');
- size_t separatorPosition = normalizedLocale.find('_');
- if (separatorPosition == notFound)
- return normalizedLocale;
- return normalizedLocale.left(separatorPosition);
-}
-
-static NSLocale* determineLocale()
-{
- NSLocale* currentLocale = [NSLocale currentLocale];
- String currentLocaleLanguage = languageFromLocale(String([currentLocale localeIdentifier]));
- String browserLanguage = languageFromLocale(defaultLanguage());
- if (equalIgnoringCase(currentLocaleLanguage, browserLanguage))
- return currentLocale;
- // It seems initWithLocaleIdentifier accepts dash-separated locale identifier.
- return [[NSLocale alloc] initWithLocaleIdentifier:defaultLanguage()];
+ return adoptPtr(new LocaleMac(locale));
}
LocaleMac* LocaleMac::currentLocale()
{
- static LocaleMac* currentLocale = new LocaleMac(determineLocale());
+ static LocaleMac* currentLocale = new LocaleMac(determineLocale(defaultLanguage()));
return currentLocale;
}
diff --git a/Source/WebCore/plugins/gtk/PluginViewGtk.cpp b/Source/WebCore/plugins/gtk/PluginViewGtk.cpp
index 62f9f8d84..4006040d8 100644
--- a/Source/WebCore/plugins/gtk/PluginViewGtk.cpp
+++ b/Source/WebCore/plugins/gtk/PluginViewGtk.cpp
@@ -76,7 +76,7 @@
#define Bool int // this got undefined somewhere
#define Status int // ditto
#include <X11/extensions/Xrender.h>
-#include <cairo/cairo-xlib.h>
+#include <cairo-xlib.h>
#include <gdk/gdkx.h>
using JSC::ExecState;
diff --git a/Source/WebCore/rendering/ExclusionRectangle.cpp b/Source/WebCore/rendering/ExclusionRectangle.cpp
index 78f83b055..3bdde0aee 100644
--- a/Source/WebCore/rendering/ExclusionRectangle.cpp
+++ b/Source/WebCore/rendering/ExclusionRectangle.cpp
@@ -40,10 +40,10 @@ static inline float ellipseXIntercept(float y, float rx, float ry)
return rx * sqrt(1 - (y*y) / (ry*ry));
}
-void ExclusionRectangle::getOutsideIntervals(float y1, float y2, Vector<ExclusionInterval>& rv) const
+void ExclusionRectangle::getExcludedIntervals(float logicalTop, float logicalBottom, SegmentList& result) const
{
- if (y1 > y2)
- std::swap(y1, y2);
+ float y1 = minYForLogicalLine(logicalTop, logicalBottom);
+ float y2 = maxYForLogicalLine(logicalTop, logicalBottom);
if (y2 < m_y || y1 >= m_y + m_height)
return;
@@ -65,15 +65,15 @@ void ExclusionRectangle::getOutsideIntervals(float y1, float y2, Vector<Exclusio
}
}
- rv.append(ExclusionInterval(x1, x2));
+ result.append(LineSegment(x1, x2));
}
-void ExclusionRectangle::getInsideIntervals(float y1, float y2, Vector<ExclusionInterval>& rv) const
+void ExclusionRectangle::getIncludedIntervals(float logicalTop, float logicalBottom, SegmentList& result) const
{
- if (y1 > y2)
- std::swap(y1, y2);
+ float y1 = minYForLogicalLine(logicalTop, logicalBottom);
+ float y2 = maxYForLogicalLine(logicalTop, logicalBottom);
- if (y1 < m_y || y2 >= m_y + m_height)
+ if (y1 < m_y || y2 > m_y + m_height)
return;
float x1 = m_x;
@@ -106,7 +106,7 @@ void ExclusionRectangle::getInsideIntervals(float y1, float y2, Vector<Exclusion
}
}
- rv.append(ExclusionInterval(x1, x2));
+ result.append(LineSegment(x1, x2));
}
} // namespace WebCore
diff --git a/Source/WebCore/rendering/ExclusionRectangle.h b/Source/WebCore/rendering/ExclusionRectangle.h
index 6af021772..5ca289d86 100644
--- a/Source/WebCore/rendering/ExclusionRectangle.h
+++ b/Source/WebCore/rendering/ExclusionRectangle.h
@@ -31,6 +31,7 @@
#define ExclusionRectangle_h
#include "ExclusionShape.h"
+#include "FloatSize.h"
#include <wtf/Assertions.h>
#include <wtf/Vector.h>
@@ -38,20 +39,20 @@ namespace WebCore {
class ExclusionRectangle : public ExclusionShape {
public:
- ExclusionRectangle(float x, float y, float width, float height, float rx = 0, float ry = 0)
+ ExclusionRectangle(const FloatRect& bounds, const FloatSize& radii)
: ExclusionShape()
- , m_x(x)
- , m_y(y)
- , m_width(width)
- , m_height(height)
- , m_rx(rx)
- , m_ry(ry)
+ , m_x(bounds.x())
+ , m_y(bounds.y())
+ , m_width(bounds.width())
+ , m_height(bounds.height())
+ , m_rx(radii.width())
+ , m_ry(radii.height())
{
}
- virtual FloatRect shapeLogicalBoundingBox() const OVERRIDE { return FloatRect(m_x, m_y, m_width, m_height); }
- virtual void getOutsideIntervals(float y1, float y2, Vector<ExclusionInterval>&) const OVERRIDE;
- virtual void getInsideIntervals(float y1, float y2, Vector<ExclusionInterval>&) const OVERRIDE;
+ virtual FloatRect shapeLogicalBoundingBox() const OVERRIDE { return internalToLogicalBoundingBox(FloatRect(m_x, m_y, m_width, m_height)); }
+ virtual void getExcludedIntervals(float logicalTop, float logicalBottom, SegmentList&) const OVERRIDE;
+ virtual void getIncludedIntervals(float logicalTop, float logicalBottom, SegmentList&) const OVERRIDE;
private:
float m_x;
diff --git a/Source/WebCore/rendering/ExclusionShape.cpp b/Source/WebCore/rendering/ExclusionShape.cpp
index 48c88b653..0f430ef04 100644
--- a/Source/WebCore/rendering/ExclusionShape.cpp
+++ b/Source/WebCore/rendering/ExclusionShape.cpp
@@ -32,6 +32,7 @@
#include "BasicShapeFunctions.h"
#include "ExclusionRectangle.h"
+#include "FloatSize.h"
#include "LengthFunctions.h"
#include "NotImplemented.h"
#include "WindRule.h"
@@ -41,66 +42,93 @@
namespace WebCore {
-static PassOwnPtr<ExclusionShape> createExclusionRectangle(float x, float y, float width, float height, float rx, float ry)
+static PassOwnPtr<ExclusionShape> createExclusionRectangle(const FloatRect& bounds, const FloatSize& radii)
{
- ASSERT(width >= 0 && height >= 0 && rx >= 0 && ry >= 0);
- return adoptPtr(new ExclusionRectangle(x, y, width, height, rx, ry));
+ ASSERT(bounds.width() >= 0 && bounds.height() >= 0 && radii.width() >= 0 && radii.height() >= 0);
+ return adoptPtr(new ExclusionRectangle(bounds, radii));
}
-static PassOwnPtr<ExclusionShape> createExclusionCircle(float cx, float cy, float radius)
+static PassOwnPtr<ExclusionShape> createExclusionCircle(const FloatPoint& center, float radius)
{
ASSERT(radius >= 0);
- return adoptPtr(new ExclusionRectangle(cx - radius, cy - radius, cx + radius, cy + radius, radius, radius));
+ return adoptPtr(new ExclusionRectangle(FloatRect(center.x() - radius, center.y() - radius, radius*2, radius*2), FloatSize(radius, radius)));
}
-static PassOwnPtr<ExclusionShape> createExclusionEllipse(float cx, float cy, float rx, float ry)
+static PassOwnPtr<ExclusionShape> createExclusionEllipse(const FloatPoint& center, const FloatSize& radii)
{
- ASSERT(rx >= 0 && ry >= 0);
- return adoptPtr(new ExclusionRectangle(cx - rx, cy - ry, cx + rx, cy + ry, rx, ry));
+ ASSERT(radii.width() >= 0 && radii.height() >= 0);
+ return adoptPtr(new ExclusionRectangle(FloatRect(center.x() - radii.width(), center.y() - radii.height(), radii.width()*2, radii.height()*2), radii));
}
-PassOwnPtr<ExclusionShape> ExclusionShape::createExclusionShape(const BasicShape* wrapShape, float borderBoxLogicalWidth, float borderBoxLogicalHeight)
+// If the writingMode is vertical, then the BasicShape's (physical) x and y coordinates are swapped, so that
+// line segments are parallel to the internal coordinate system's X axis.
+
+PassOwnPtr<ExclusionShape> ExclusionShape::createExclusionShape(const BasicShape* basicShape, float logicalBoxWidth, float logicalBoxHeight, WritingMode writingMode)
{
- if (!wrapShape)
+ if (!basicShape)
return nullptr;
- switch (wrapShape->type()) {
+ bool horizontalWritingMode = isHorizontalWritingMode(writingMode);
+ float boxWidth = horizontalWritingMode ? logicalBoxWidth : logicalBoxHeight;
+ float boxHeight = horizontalWritingMode ? logicalBoxHeight : logicalBoxWidth;
+ OwnPtr<ExclusionShape> exclusionShape;
+
+ switch (basicShape->type()) {
+
case BasicShape::BASIC_SHAPE_RECTANGLE: {
- const BasicShapeRectangle* rectangle = static_cast<const BasicShapeRectangle*>(wrapShape);
- Length rx = rectangle->cornerRadiusX();
- Length ry = rectangle->cornerRadiusY();
- return createExclusionRectangle(
- floatValueForLength(rectangle->x(), borderBoxLogicalWidth),
- floatValueForLength(rectangle->y(), borderBoxLogicalHeight),
- floatValueForLength(rectangle->width(), borderBoxLogicalWidth),
- floatValueForLength(rectangle->height(), borderBoxLogicalHeight),
- rx.isUndefined() ? 0 : floatValueForLength(rx, borderBoxLogicalWidth),
- ry.isUndefined() ? 0 : floatValueForLength(ry, borderBoxLogicalHeight) );
+ const BasicShapeRectangle* rectangle = static_cast<const BasicShapeRectangle*>(basicShape);
+ float x = floatValueForLength(rectangle->x(), boxWidth);
+ float y = floatValueForLength(rectangle->y(), boxHeight);
+ float width = floatValueForLength(rectangle->width(), boxWidth);
+ float height = floatValueForLength(rectangle->height(), boxHeight);
+ Length radiusXLength = rectangle->cornerRadiusX();
+ Length radiusYLength = rectangle->cornerRadiusY();
+ float radiusX = radiusXLength.isUndefined() ? 0 : floatValueForLength(radiusXLength, boxWidth);
+ float radiusY = radiusYLength.isUndefined() ? 0 : floatValueForLength(radiusYLength, boxHeight);
+
+ exclusionShape = horizontalWritingMode
+ ? createExclusionRectangle(FloatRect(x, y, width, height), FloatSize(radiusX, radiusY))
+ : createExclusionRectangle(FloatRect(y, x, height, width), FloatSize(radiusY, radiusX));
+ break;
}
case BasicShape::BASIC_SHAPE_CIRCLE: {
- const BasicShapeCircle* circle = static_cast<const BasicShapeCircle*>(wrapShape);
- return createExclusionCircle(
- floatValueForLength(circle->centerX(), borderBoxLogicalWidth),
- floatValueForLength(circle->centerY(), borderBoxLogicalHeight),
- floatValueForLength(circle->radius(), std::max(borderBoxLogicalHeight, borderBoxLogicalWidth)) );
+ const BasicShapeCircle* circle = static_cast<const BasicShapeCircle*>(basicShape);
+ float centerX = floatValueForLength(circle->centerX(), boxWidth);
+ float centerY = floatValueForLength(circle->centerY(), boxHeight);
+ float radius = floatValueForLength(circle->radius(), std::max(boxHeight, boxWidth));
+
+ exclusionShape = horizontalWritingMode
+ ? createExclusionCircle(FloatPoint(centerX, centerY), radius)
+ : createExclusionCircle(FloatPoint(centerY, centerX), radius);
+ break;
}
case BasicShape::BASIC_SHAPE_ELLIPSE: {
- const BasicShapeEllipse* ellipse = static_cast<const BasicShapeEllipse*>(wrapShape);
- return createExclusionEllipse(
- floatValueForLength(ellipse->centerX(), borderBoxLogicalWidth),
- floatValueForLength(ellipse->centerY(), borderBoxLogicalHeight),
- floatValueForLength(ellipse->radiusX(), borderBoxLogicalWidth),
- floatValueForLength(ellipse->radiusY(), borderBoxLogicalHeight) );
+ const BasicShapeEllipse* ellipse = static_cast<const BasicShapeEllipse*>(basicShape);
+ float centerX = floatValueForLength(ellipse->centerX(), boxWidth);
+ float centerY = floatValueForLength(ellipse->centerY(), boxHeight);
+ float radiusX = floatValueForLength(ellipse->radiusX(), boxWidth);
+ float radiusY = floatValueForLength(ellipse->radiusY(), boxHeight);
+
+ exclusionShape = horizontalWritingMode
+ ? createExclusionEllipse(FloatPoint(centerX, centerY), FloatSize(radiusX, radiusY))
+ : createExclusionEllipse(FloatPoint(centerY, centerX), FloatSize(radiusY, radiusX));
+ break;
}
case BasicShape::BASIC_SHAPE_POLYGON:
notImplemented();
+
+ default:
+ ASSERT_NOT_REACHED();
}
- ASSERT_NOT_REACHED();
- return nullptr;
+ exclusionShape->m_logicalBoxWidth = logicalBoxWidth;
+ exclusionShape->m_logicalBoxHeight = logicalBoxHeight;
+ exclusionShape->m_writingMode = writingMode;
+
+ return exclusionShape.release();
}
} // namespace WebCore
diff --git a/Source/WebCore/rendering/ExclusionShape.h b/Source/WebCore/rendering/ExclusionShape.h
index c5de4d705..bb1edc6d1 100644
--- a/Source/WebCore/rendering/ExclusionShape.h
+++ b/Source/WebCore/rendering/ExclusionShape.h
@@ -31,22 +31,51 @@
#define ExclusionShape_h
#include "BasicShapes.h"
-#include "ExclusionInterval.h"
#include "FloatRect.h"
+#include "WritingMode.h"
#include <wtf/PassOwnPtr.h>
#include <wtf/Vector.h>
namespace WebCore {
+struct LineSegment {
+ float logicalLeft;
+ float logicalRight;
+
+ LineSegment(float logicalLeft, float logicalRight)
+ : logicalLeft(logicalLeft)
+ , logicalRight(logicalRight)
+ {
+ }
+};
+
+typedef Vector<LineSegment> SegmentList;
+
+
+// A representation of a BasicShape that enables layout code to determine how to break a line up into segments
+// that will fit within or around a shape. The line is defined by a pair of logical Y coordinates and the
+// computed segments are returned as pairs of logical X coordinates. The BasicShape itself is defined in
+// physical coordinates.
+
class ExclusionShape {
public:
- static PassOwnPtr<ExclusionShape> createExclusionShape(const BasicShape*, float borderBoxLogicalWidth, float borderBoxLogicalHeight);
+ static PassOwnPtr<ExclusionShape> createExclusionShape(const BasicShape*, float logicalBoxWidth, float logicalBoxHeight, WritingMode);
virtual ~ExclusionShape() { }
virtual FloatRect shapeLogicalBoundingBox() const = 0;
- virtual void getInsideIntervals(float logicalTop, float logicalBottom, Vector<ExclusionInterval>&) const = 0;
- virtual void getOutsideIntervals(float logicalTop, float logicalBottom, Vector<ExclusionInterval>&) const = 0;
+ virtual void getIncludedIntervals(float logicalTop, float logicalBottom, SegmentList&) const = 0;
+ virtual void getExcludedIntervals(float logicalTop, float logicalBottom, SegmentList&) const = 0;
+
+protected:
+ float minYForLogicalLine(float logicalTop, float logicalBottom) const { return (m_writingMode == RightToLeftWritingMode) ? m_logicalBoxHeight - logicalBottom : logicalTop; }
+ float maxYForLogicalLine(float logicalTop, float logicalBottom) const { return (m_writingMode == RightToLeftWritingMode) ? m_logicalBoxHeight - logicalTop : logicalBottom; }
+ FloatRect internalToLogicalBoundingBox(FloatRect r) const { return (m_writingMode == RightToLeftWritingMode) ? FloatRect(r.x(), m_logicalBoxHeight - r.maxY(), r.width(), r.height()) : r; }
+
+private:
+ WritingMode m_writingMode;
+ float m_logicalBoxWidth;
+ float m_logicalBoxHeight;
};
} // namespace WebCore
diff --git a/Source/WebCore/rendering/RenderBR.cpp b/Source/WebCore/rendering/RenderBR.cpp
index d80393614..304a27945 100644
--- a/Source/WebCore/rendering/RenderBR.cpp
+++ b/Source/WebCore/rendering/RenderBR.cpp
@@ -40,7 +40,7 @@ RenderBR::~RenderBR()
int RenderBR::lineHeight(bool firstLine) const
{
- if (firstLine && document()->usesFirstLineRules()) {
+ if (firstLine && document()->styleSheetCollection()->usesFirstLineRules()) {
RenderStyle* s = style(firstLine);
if (s != style())
return s->computedLineHeight(view());
diff --git a/Source/WebCore/rendering/RenderBlock.cpp b/Source/WebCore/rendering/RenderBlock.cpp
index abed66220..4c1371e81 100755
--- a/Source/WebCore/rendering/RenderBlock.cpp
+++ b/Source/WebCore/rendering/RenderBlock.cpp
@@ -347,7 +347,7 @@ void RenderBlock::styleDidChange(StyleDifference diff, const RenderStyle* oldSty
m_lineHeight = -1;
// Update pseudos for :before and :after now.
- if (!isAnonymous() && document()->usesBeforeAfterRules() && canHaveGeneratedChildren()) {
+ if (!isAnonymous() && document()->styleSheetCollection()->usesBeforeAfterRules() && canHaveGeneratedChildren()) {
updateBeforeAfterContent(BEFORE);
updateBeforeAfterContent(AFTER);
}
@@ -602,7 +602,7 @@ void RenderBlock::splitBlocks(RenderBlock* fromBlock, RenderBlock* toBlock,
RenderBoxModelObject* curr = toRenderBoxModelObject(parent());
RenderBoxModelObject* currChild = this;
RenderObject* currChildNextSibling = currChild->nextSibling();
- bool documentUsesBeforeAfterRules = document()->usesBeforeAfterRules();
+ bool documentUsesBeforeAfterRules = document()->styleSheetCollection()->usesBeforeAfterRules();
// Note: |this| can be destroyed inside this loop if it is an empty anonymous
// block and we try to call updateBeforeAfterContent inside which removes the
@@ -877,7 +877,7 @@ void RenderBlock::addChildIgnoringAnonymousColumnBlocks(RenderObject* newChild,
// content gets properly destroyed.
bool isFirstChild = (beforeChild == firstChild());
bool isLastChild = (beforeChild == lastChild());
- if (document()->usesBeforeAfterRules())
+ if (document()->styleSheetCollection()->usesBeforeAfterRules())
children()->updateBeforeAfterContent(this, AFTER);
if (isLastChild && beforeChild != lastChild()) {
// We destroyed the last child, so now we need to update our insertion
@@ -6153,7 +6153,7 @@ LayoutUnit RenderBlock::lineHeight(bool firstLine, LineDirectionMode direction,
if (isReplaced() && linePositionMode == PositionOnContainingLine)
return RenderBox::lineHeight(firstLine, direction, linePositionMode);
- if (firstLine && document()->usesFirstLineRules()) {
+ if (firstLine && document()->styleSheetCollection()->usesFirstLineRules()) {
RenderStyle* s = style(firstLine);
if (s != style())
return s->computedLineHeight(view());
@@ -6461,7 +6461,7 @@ void RenderBlock::createFirstLetterRenderer(RenderObject* firstLetterBlock, Rend
void RenderBlock::updateFirstLetter()
{
- if (!document()->usesFirstLetterRules())
+ if (!document()->styleSheetCollection()->usesFirstLetterRules())
return;
// Don't recur
if (style()->styleType() == FIRST_LETTER)
diff --git a/Source/WebCore/rendering/RenderFlowThread.cpp b/Source/WebCore/rendering/RenderFlowThread.cpp
index 0741ea8c8..d5a99b7bb 100644
--- a/Source/WebCore/rendering/RenderFlowThread.cpp
+++ b/Source/WebCore/rendering/RenderFlowThread.cpp
@@ -222,19 +222,18 @@ void RenderFlowThread::updateLogicalWidth()
}
}
-void RenderFlowThread::updateLogicalHeight()
+void RenderFlowThread::computeLogicalHeight(LayoutUnit, LayoutUnit logicalTop, LogicalExtentComputedValues& computedValues) const
{
- LayoutUnit logicalHeight = 0;
+ computedValues.m_position = logicalTop;
+ computedValues.m_extent = 0;
- for (RenderRegionList::iterator iter = m_regionList.begin(); iter != m_regionList.end(); ++iter) {
+ for (RenderRegionList::const_iterator iter = m_regionList.begin(); iter != m_regionList.end(); ++iter) {
RenderRegion* region = *iter;
if (!region->isValid())
continue;
ASSERT(!region->needsLayout());
- logicalHeight += region->logicalHeightOfAllFlowThreadContent();
+ computedValues.m_extent += region->logicalHeightOfAllFlowThreadContent();
}
-
- setLogicalHeight(logicalHeight);
}
void RenderFlowThread::paintFlowThreadPortionInRegion(PaintInfo& paintInfo, RenderRegion* region, LayoutRect flowThreadPortionRect, LayoutRect flowThreadPortionOverflowRect, const LayoutPoint& paintOffset) const
diff --git a/Source/WebCore/rendering/RenderFlowThread.h b/Source/WebCore/rendering/RenderFlowThread.h
index d09183d95..b942eee57 100644
--- a/Source/WebCore/rendering/RenderFlowThread.h
+++ b/Source/WebCore/rendering/RenderFlowThread.h
@@ -74,7 +74,7 @@ public:
const RenderRegionList& renderRegionList() const { return m_regionList; }
virtual void updateLogicalWidth() OVERRIDE;
- virtual void updateLogicalHeight() OVERRIDE;
+ virtual void computeLogicalHeight(LayoutUnit logicalHeight, LayoutUnit logicalTop, LogicalExtentComputedValues&) const OVERRIDE;
void paintFlowThreadPortionInRegion(PaintInfo&, RenderRegion*, LayoutRect flowThreadPortionRect, LayoutRect flowThreadPortionOverflowRect, const LayoutPoint&) const;
bool hitTestFlowThreadPortionInRegion(RenderRegion*, LayoutRect flowThreadPortionRect, LayoutRect flowThreadPortionOverflowRect, const HitTestRequest&, HitTestResult&, const HitTestLocation& locationInContainer, const LayoutPoint& accumulatedOffset) const;
diff --git a/Source/WebCore/rendering/RenderInline.cpp b/Source/WebCore/rendering/RenderInline.cpp
index 234cea28b..239aba370 100644
--- a/Source/WebCore/rendering/RenderInline.cpp
+++ b/Source/WebCore/rendering/RenderInline.cpp
@@ -194,7 +194,7 @@ void RenderInline::styleDidChange(StyleDifference diff, const RenderStyle* oldSt
}
// Update pseudos for :before and :after now.
- if (!isAnonymous() && document()->usesBeforeAfterRules()) {
+ if (!isAnonymous() && document()->styleSheetCollection()->usesBeforeAfterRules()) {
children()->updateBeforeAfterContent(this, BEFORE);
children()->updateBeforeAfterContent(this, AFTER);
}
@@ -218,7 +218,7 @@ void RenderInline::updateAlwaysCreateLineBoxes(bool fullLayout)
|| parentStyle->lineHeight() != style()->lineHeight()))
|| (inRenderFlowThread() && enclosingRenderFlowThread()->hasRegionsWithStyling());
- if (!alwaysCreateLineBoxes && checkFonts && document()->usesFirstLineRules()) {
+ if (!alwaysCreateLineBoxes && checkFonts && document()->styleSheetCollection()->usesFirstLineRules()) {
// Have to check the first line style as well.
parentStyle = parent()->style(true);
RenderStyle* childStyle = style(true);
@@ -324,7 +324,7 @@ void RenderInline::addChildIgnoringContinuation(RenderObject* newChild, RenderOb
// has to move into the inline continuation. Call updateBeforeAfterContent to ensure that our :after
// content gets properly destroyed.
bool isLastChild = (beforeChild == lastChild());
- if (document()->usesBeforeAfterRules())
+ if (document()->styleSheetCollection()->usesBeforeAfterRules())
children()->updateBeforeAfterContent(this, AFTER);
if (isLastChild && beforeChild != lastChild())
beforeChild = 0; // We destroyed the last child, so now we need to update our insertion
@@ -399,7 +399,7 @@ void RenderInline::splitInlines(RenderBlock* fromBlock, RenderBlock* toBlock,
// Someone may have indirectly caused a <q> to split. When this happens, the :after content
// has to move into the inline continuation. Call updateBeforeAfterContent to ensure that the inline's :after
// content gets properly destroyed.
- if (document()->usesBeforeAfterRules())
+ if (document()->styleSheetCollection()->usesBeforeAfterRules())
inlineCurr->children()->updateBeforeAfterContent(inlineCurr, AFTER);
// Now we need to take all of the children starting from the first child
@@ -1283,7 +1283,7 @@ InlineFlowBox* RenderInline::createAndAppendInlineFlowBox()
LayoutUnit RenderInline::lineHeight(bool firstLine, LineDirectionMode /*direction*/, LinePositionMode /*linePositionMode*/) const
{
- if (firstLine && document()->usesFirstLineRules()) {
+ if (firstLine && document()->styleSheetCollection()->usesFirstLineRules()) {
RenderStyle* s = style(firstLine);
if (s != style())
return s->computedLineHeight(view());
diff --git a/Source/WebCore/rendering/RenderMeter.cpp b/Source/WebCore/rendering/RenderMeter.cpp
index b539c0a3a..a4b3eca35 100644
--- a/Source/WebCore/rendering/RenderMeter.cpp
+++ b/Source/WebCore/rendering/RenderMeter.cpp
@@ -55,13 +55,22 @@ HTMLMeterElement* RenderMeter::meterElement() const
void RenderMeter::updateLogicalWidth()
{
RenderBox::updateLogicalWidth();
- setWidth(theme()->meterSizeForBounds(this, pixelSnappedIntRect(frameRect())).width());
+
+ IntSize frameSize = theme()->meterSizeForBounds(this, pixelSnappedIntRect(frameRect()));
+ setLogicalWidth(isHorizontalWritingMode() ? frameSize.width() : frameSize.height());
}
-void RenderMeter::updateLogicalHeight()
+void RenderMeter::computeLogicalHeight(LayoutUnit logicalHeight, LayoutUnit logicalTop, LogicalExtentComputedValues& computedValues) const
{
- RenderBox::updateLogicalHeight();
- setHeight(theme()->meterSizeForBounds(this, pixelSnappedIntRect(frameRect())).height());
+ RenderBox::computeLogicalHeight(logicalHeight, logicalTop, computedValues);
+
+ LayoutRect frame = frameRect();
+ if (isHorizontalWritingMode())
+ frame.setHeight(computedValues.m_extent);
+ else
+ frame.setWidth(computedValues.m_extent);
+ IntSize frameSize = theme()->meterSizeForBounds(this, pixelSnappedIntRect(frame));
+ computedValues.m_extent = isHorizontalWritingMode() ? frameSize.height() : frameSize.width();
}
double RenderMeter::valueRatio() const
diff --git a/Source/WebCore/rendering/RenderMeter.h b/Source/WebCore/rendering/RenderMeter.h
index 9051951d1..b7c3ecee7 100644
--- a/Source/WebCore/rendering/RenderMeter.h
+++ b/Source/WebCore/rendering/RenderMeter.h
@@ -40,7 +40,7 @@ public:
private:
virtual void updateLogicalWidth() OVERRIDE;
- virtual void updateLogicalHeight() OVERRIDE;
+ virtual void computeLogicalHeight(LayoutUnit logicalHeight, LayoutUnit logicalTop, LogicalExtentComputedValues&) const OVERRIDE;
virtual const char* renderName() const { return "RenderMeter"; }
virtual bool isMeter() const { return true; }
diff --git a/Source/WebCore/rendering/RenderMultiColumnFlowThread.cpp b/Source/WebCore/rendering/RenderMultiColumnFlowThread.cpp
index e553c5401..562506842 100644
--- a/Source/WebCore/rendering/RenderMultiColumnFlowThread.cpp
+++ b/Source/WebCore/rendering/RenderMultiColumnFlowThread.cpp
@@ -42,4 +42,11 @@ const char* RenderMultiColumnFlowThread::renderName() const
return "RenderMultiColumnFlowThread";
}
+void RenderMultiColumnFlowThread::computeLogicalHeight(LayoutUnit logicalHeight, LayoutUnit logicalTop, LogicalExtentComputedValues& computedValues) const
+{
+ // We simply remain at our intrinsic height.
+ computedValues.m_extent = logicalHeight;
+ computedValues.m_position = logicalTop;
+}
+
}
diff --git a/Source/WebCore/rendering/RenderMultiColumnFlowThread.h b/Source/WebCore/rendering/RenderMultiColumnFlowThread.h
index 363cd0771..595222784 100644
--- a/Source/WebCore/rendering/RenderMultiColumnFlowThread.h
+++ b/Source/WebCore/rendering/RenderMultiColumnFlowThread.h
@@ -39,7 +39,7 @@ public:
private:
virtual const char* renderName() const OVERRIDE;
- virtual void updateLogicalHeight() OVERRIDE { } // We simply remain at our intrinsic height.
+ virtual void computeLogicalHeight(LayoutUnit logicalHeight, LayoutUnit logicalTop, LogicalExtentComputedValues&) const OVERRIDE;
};
} // namespace WebCore
diff --git a/Source/WebCore/rendering/RenderObject.cpp b/Source/WebCore/rendering/RenderObject.cpp
index 214970a35..c523d26b6 100755
--- a/Source/WebCore/rendering/RenderObject.cpp
+++ b/Source/WebCore/rendering/RenderObject.cpp
@@ -2597,7 +2597,7 @@ void RenderObject::layout()
PassRefPtr<RenderStyle> RenderObject::uncachedFirstLineStyle(RenderStyle* style) const
{
- if (!document()->usesFirstLineRules())
+ if (!document()->styleSheetCollection()->usesFirstLineRules())
return 0;
ASSERT(!isText());
@@ -2618,7 +2618,7 @@ PassRefPtr<RenderStyle> RenderObject::uncachedFirstLineStyle(RenderStyle* style)
RenderStyle* RenderObject::firstLineStyleSlowCase() const
{
- ASSERT(document()->usesFirstLineRules());
+ ASSERT(document()->styleSheetCollection()->usesFirstLineRules());
RenderStyle* style = m_style.get();
const RenderObject* renderer = isText() ? parent() : this;
diff --git a/Source/WebCore/rendering/RenderObject.h b/Source/WebCore/rendering/RenderObject.h
index 0b10b69dc..28cda3ad7 100644
--- a/Source/WebCore/rendering/RenderObject.h
+++ b/Source/WebCore/rendering/RenderObject.h
@@ -27,6 +27,7 @@
#define RenderObject_h
#include "CachedImageClient.h"
+#include "DocumentStyleSheetCollection.h"
#include "Element.h"
#include "FractionalLayoutUnit.h"
#include "FloatQuad.h"
@@ -735,7 +736,7 @@ public:
virtual LayoutUnit maxPreferredLogicalWidth() const { return 0; }
RenderStyle* style() const { return m_style.get(); }
- RenderStyle* firstLineStyle() const { return document()->usesFirstLineRules() ? firstLineStyleSlowCase() : style(); }
+ RenderStyle* firstLineStyle() const { return document()->styleSheetCollection()->usesFirstLineRules() ? firstLineStyleSlowCase() : style(); }
RenderStyle* style(bool firstLine) const { return firstLine ? firstLineStyle() : style(); }
// Used only by Element::pseudoStyleCacheIsInvalid to get a first line style based off of a
diff --git a/Source/WebCore/rendering/RenderObjectChildList.cpp b/Source/WebCore/rendering/RenderObjectChildList.cpp
index 247f7dda4..c3b4d4831 100644
--- a/Source/WebCore/rendering/RenderObjectChildList.cpp
+++ b/Source/WebCore/rendering/RenderObjectChildList.cpp
@@ -369,7 +369,7 @@ static RenderObject* ensureBeforeAfterContainer(RenderObject* owner, PseudoId ty
void RenderObjectChildList::updateBeforeAfterContent(RenderObject* owner, PseudoId type, const RenderObject* styledObject)
{
// Double check that the document did in fact use generated content rules. Otherwise we should not have been called.
- ASSERT(owner->document()->usesBeforeAfterRules());
+ ASSERT(owner->document()->styleSheetCollection()->usesBeforeAfterRules());
// In CSS2, before/after pseudo-content cannot nest. Check this first.
if (owner->style()->styleType() == BEFORE || owner->style()->styleType() == AFTER)
diff --git a/Source/WebCore/rendering/RenderTableRow.cpp b/Source/WebCore/rendering/RenderTableRow.cpp
index 1f2bd0689..b102f0842 100644
--- a/Source/WebCore/rendering/RenderTableRow.cpp
+++ b/Source/WebCore/rendering/RenderTableRow.cpp
@@ -55,7 +55,7 @@ void RenderTableRow::willBeRemovedFromTree()
void RenderTableRow::updateBeforeAndAfterContent()
{
- if (!isAnonymous() && document()->usesBeforeAfterRules()) {
+ if (!isAnonymous() && document()->styleSheetCollection()->usesBeforeAfterRules()) {
children()->updateBeforeAfterContent(this, BEFORE);
children()->updateBeforeAfterContent(this, AFTER);
}
diff --git a/Source/WebCore/rendering/RenderWidget.cpp b/Source/WebCore/rendering/RenderWidget.cpp
index 9537edf5d..21d0c3ad6 100644
--- a/Source/WebCore/rendering/RenderWidget.cpp
+++ b/Source/WebCore/rendering/RenderWidget.cpp
@@ -47,53 +47,42 @@ static HashMap<const Widget*, RenderWidget*>& widgetRendererMap()
return *staticWidgetRendererMap;
}
-static unsigned widgetHierarchyUpdateSuspendCount;
+unsigned WidgetHierarchyUpdatesSuspensionScope::s_widgetHierarchyUpdateSuspendCount = 0;
-typedef HashMap<RefPtr<Widget>, FrameView*> WidgetToParentMap;
-
-static WidgetToParentMap& widgetNewParentMap()
+WidgetHierarchyUpdatesSuspensionScope::WidgetToParentMap& WidgetHierarchyUpdatesSuspensionScope::widgetNewParentMap()
{
DEFINE_STATIC_LOCAL(WidgetToParentMap, map, ());
return map;
}
-void RenderWidget::suspendWidgetHierarchyUpdates()
+void WidgetHierarchyUpdatesSuspensionScope::moveWidgets()
{
- widgetHierarchyUpdateSuspendCount++;
-}
-
-void RenderWidget::resumeWidgetHierarchyUpdates()
-{
- ASSERT(widgetHierarchyUpdateSuspendCount);
- if (widgetHierarchyUpdateSuspendCount == 1) {
- WidgetToParentMap map = widgetNewParentMap();
- widgetNewParentMap().clear();
- WidgetToParentMap::iterator end = map.end();
- for (WidgetToParentMap::iterator it = map.begin(); it != end; ++it) {
- Widget* child = it->first.get();
- ScrollView* currentParent = child->parent();
- FrameView* newParent = it->second;
- if (newParent != currentParent) {
- if (currentParent)
- currentParent->removeChild(child);
- if (newParent)
- newParent->addChild(child);
- }
+ WidgetToParentMap map = widgetNewParentMap();
+ widgetNewParentMap().clear();
+ WidgetToParentMap::iterator end = map.end();
+ for (WidgetToParentMap::iterator it = map.begin(); it != end; ++it) {
+ Widget* child = it->first.get();
+ ScrollView* currentParent = child->parent();
+ FrameView* newParent = it->second;
+ if (newParent != currentParent) {
+ if (currentParent)
+ currentParent->removeChild(child);
+ if (newParent)
+ newParent->addChild(child);
}
}
- widgetHierarchyUpdateSuspendCount--;
}
static void moveWidgetToParentSoon(Widget* child, FrameView* parent)
{
- if (!widgetHierarchyUpdateSuspendCount) {
+ if (!WidgetHierarchyUpdatesSuspensionScope::isSuspended()) {
if (parent)
parent->addChild(child);
else
child->removeFromParent();
return;
}
- widgetNewParentMap().set(child, parent);
+ WidgetHierarchyUpdatesSuspensionScope::scheduleWidgetToMove(child, parent);
}
RenderWidget::RenderWidget(Node* node)
diff --git a/Source/WebCore/rendering/RenderWidget.h b/Source/WebCore/rendering/RenderWidget.h
index b7db3b809..d20123a68 100644
--- a/Source/WebCore/rendering/RenderWidget.h
+++ b/Source/WebCore/rendering/RenderWidget.h
@@ -28,6 +28,32 @@
namespace WebCore {
+class WidgetHierarchyUpdatesSuspensionScope {
+public:
+ WidgetHierarchyUpdatesSuspensionScope()
+ {
+ s_widgetHierarchyUpdateSuspendCount++;
+ }
+ ~WidgetHierarchyUpdatesSuspensionScope()
+ {
+ ASSERT(s_widgetHierarchyUpdateSuspendCount);
+ if (s_widgetHierarchyUpdateSuspendCount == 1)
+ moveWidgets();
+ s_widgetHierarchyUpdateSuspendCount--;
+ }
+
+ static bool isSuspended() { return s_widgetHierarchyUpdateSuspendCount; }
+ static void scheduleWidgetToMove(Widget* widget, FrameView* frame) { widgetNewParentMap().set(widget, frame); }
+
+private:
+ typedef HashMap<RefPtr<Widget>, FrameView*> WidgetToParentMap;
+ static WidgetToParentMap& widgetNewParentMap();
+
+ void moveWidgets();
+
+ static unsigned s_widgetHierarchyUpdateSuspendCount;
+};
+
class RenderWidget : public RenderReplaced, private OverlapTestRequestClient {
public:
virtual ~RenderWidget();
@@ -42,9 +68,6 @@ public:
IntRect windowClipRect() const;
void notifyWidget(WidgetNotification);
-
- static void suspendWidgetHierarchyUpdates();
- static void resumeWidgetHierarchyUpdates();
RenderArena* ref() { ++m_refCount; return renderArena(); }
void deref(RenderArena*);
diff --git a/Source/WebCore/rendering/RootInlineBox.cpp b/Source/WebCore/rendering/RootInlineBox.cpp
index 928fe667e..1f4206700 100644
--- a/Source/WebCore/rendering/RootInlineBox.cpp
+++ b/Source/WebCore/rendering/RootInlineBox.cpp
@@ -846,7 +846,7 @@ LayoutUnit RootInlineBox::verticalPositionForBox(InlineBox* box, VerticalPositio
// This method determines the vertical position for inline elements.
bool firstLine = isFirstLineStyle();
- if (firstLine && !renderer->document()->usesFirstLineRules())
+ if (firstLine && !renderer->document()->styleSheetCollection()->usesFirstLineRules())
firstLine = false;
// Check the cache.
diff --git a/Source/WebCore/rendering/WrapShapeInfo.cpp b/Source/WebCore/rendering/WrapShapeInfo.cpp
index 0a16cc51f..0ce46e665 100644
--- a/Source/WebCore/rendering/WrapShapeInfo.cpp
+++ b/Source/WebCore/rendering/WrapShapeInfo.cpp
@@ -71,10 +71,6 @@ WrapShapeInfo* WrapShapeInfo::wrapShapeInfoForRenderBlock(const RenderBlock* blo
bool WrapShapeInfo::isWrapShapeInfoEnabledForRenderBlock(const RenderBlock* block)
{
- // FIXME: Bug 89705: Enable shape inside for vertical writing modes
- if (!block->isHorizontalWritingMode())
- return false;
-
// FIXME: Bug 89707: Enable shape inside for non-rectangular shapes
BasicShape* shape = block->style()->wrapShapeInside();
return (shape && shape->type() == BasicShape::BASIC_SHAPE_RECTANGLE);
@@ -107,7 +103,7 @@ void WrapShapeInfo::computeShapeSize(LayoutUnit logicalWidth, LayoutUnit logical
BasicShape* shape = m_block->style()->wrapShapeInside();
ASSERT(shape);
- m_shape = ExclusionShape::createExclusionShape(shape, logicalWidth, logicalHeight);
+ m_shape = ExclusionShape::createExclusionShape(shape, logicalWidth, logicalHeight, m_block->style()->writingMode());
ASSERT(m_shape);
}
@@ -118,15 +114,7 @@ bool WrapShapeInfo::computeSegmentsForLine(LayoutUnit lineTop)
if (lineState() == LINE_INSIDE_SHAPE) {
ASSERT(m_shape);
-
- Vector<ExclusionInterval> intervals;
- m_shape->getInsideIntervals(lineTop, lineTop, intervals); // FIXME: Bug 95479, workaround for now
- for (size_t i = 0; i < intervals.size(); i++) {
- LineSegment segment;
- segment.logicalLeft = intervals[i].x1;
- segment.logicalRight = intervals[i].x2;
- m_segments.append(segment);
- }
+ m_shape->getIncludedIntervals(lineTop, lineTop, m_segments); // FIXME: Bug 95479, workaround for now
}
return m_segments.size();
}
diff --git a/Source/WebCore/rendering/WrapShapeInfo.h b/Source/WebCore/rendering/WrapShapeInfo.h
index 080b842a8..3a2673b4f 100644
--- a/Source/WebCore/rendering/WrapShapeInfo.h
+++ b/Source/WebCore/rendering/WrapShapeInfo.h
@@ -42,14 +42,6 @@
namespace WebCore {
class RenderBlock;
-class WrapShapeInfo;
-
-struct LineSegment {
- LayoutUnit logicalLeft;
- LayoutUnit logicalRight;
-};
-
-typedef Vector<LineSegment> SegmentList;
class WrapShapeInfo {
WTF_MAKE_FAST_ALLOCATED;
diff --git a/Source/WebCore/rendering/style/RenderStyle.cpp b/Source/WebCore/rendering/style/RenderStyle.cpp
index 0602cfa9b..63d5e0550 100644
--- a/Source/WebCore/rendering/style/RenderStyle.cpp
+++ b/Source/WebCore/rendering/style/RenderStyle.cpp
@@ -40,6 +40,7 @@
#include "RenderTheme.h"
#endif
#include "WebCoreMemoryInstrumentation.h"
+#include <wtf/MemoryInstrumentationVector.h>
#include <wtf/StdLibExtras.h>
#include <algorithm>
@@ -1615,8 +1616,7 @@ void RenderStyle::reportMemoryUsage(MemoryObjectInfo* memoryObjectInfo) const
info.addMember(rareInheritedData);
// FIXME: inherited contains StyleImage and Font fields that might need to be instrumented.
info.addMember(inherited);
- if (m_cachedPseudoStyles)
- info.addVectorPtr(m_cachedPseudoStyles.get());
+ info.addMember(m_cachedPseudoStyles);
#if ENABLE(SVG)
info.addMember(m_svgStyle);
#endif
diff --git a/Source/WebCore/rendering/style/StyleRareNonInheritedData.cpp b/Source/WebCore/rendering/style/StyleRareNonInheritedData.cpp
index bbe07bfde..ff5c28d9c 100644
--- a/Source/WebCore/rendering/style/StyleRareNonInheritedData.cpp
+++ b/Source/WebCore/rendering/style/StyleRareNonInheritedData.cpp
@@ -31,6 +31,7 @@
#include "StyleImage.h"
#include "StyleResolver.h"
#include "WebCoreMemoryInstrumentation.h"
+#include <wtf/MemoryInstrumentationVector.h>
namespace WebCore {
@@ -306,7 +307,7 @@ void StyleRareNonInheritedData::reportMemoryUsage(MemoryObjectInfo* memoryObject
{
MemoryClassInfo info(memoryObjectInfo, this, WebCoreMemoryTypes::CSS);
#if ENABLE(DASHBOARD_SUPPORT)
- info.addVector(m_dashboardRegions);
+ info.addMember(m_dashboardRegions);
#endif
info.addMember(m_deprecatedFlexibleBox);
info.addMember(m_flexibleBox);
diff --git a/Source/WebCore/testing/InternalSettings.cpp b/Source/WebCore/testing/InternalSettings.cpp
index bd2376607..bb9eed6b1 100755
--- a/Source/WebCore/testing/InternalSettings.cpp
+++ b/Source/WebCore/testing/InternalSettings.cpp
@@ -100,6 +100,7 @@ InternalSettings::Backup::Backup(Page* page, Settings* settings)
, m_canStartMedia(page->canStartMedia())
, m_originalMockScrollbarsEnabled(settings->mockScrollbarsEnabled())
, m_langAttributeAwareFormControlUIEnabled(RuntimeEnabledFeatures::langAttributeAwareFormControlUIEnabled())
+ , m_imagesEnabled(settings->areImagesEnabled())
{
}
@@ -135,6 +136,7 @@ void InternalSettings::Backup::restoreTo(Page* page, Settings* settings)
page->setCanStartMedia(m_canStartMedia);
settings->setMockScrollbarsEnabled(m_originalMockScrollbarsEnabled);
RuntimeEnabledFeatures::setLangAttributeAwareFormControlUIEnabled(m_langAttributeAwareFormControlUIEnabled);
+ settings->setImagesEnabled(m_imagesEnabled);
}
InternalSettings* InternalSettings::from(Page* page)
@@ -659,4 +661,10 @@ void InternalSettings::setLangAttributeAwareFormControlUIEnabled(bool enabled)
RuntimeEnabledFeatures::setLangAttributeAwareFormControlUIEnabled(enabled);
}
+void InternalSettings::setImagesEnabled(bool enabled, ExceptionCode& ec)
+{
+ InternalSettingsGuardForSettings();
+ settings()->setImagesEnabled(enabled);
+}
+
}
diff --git a/Source/WebCore/testing/InternalSettings.h b/Source/WebCore/testing/InternalSettings.h
index 2c073df6e..be8810de6 100755
--- a/Source/WebCore/testing/InternalSettings.h
+++ b/Source/WebCore/testing/InternalSettings.h
@@ -82,6 +82,7 @@ public:
bool m_canStartMedia;
bool m_originalMockScrollbarsEnabled;
bool m_langAttributeAwareFormControlUIEnabled;
+ bool m_imagesEnabled;
};
typedef RefCountedSupplement<Page, InternalSettings> SuperType;
@@ -147,6 +148,8 @@ public:
void setMemoryInfoEnabled(bool, ExceptionCode&);
void setStorageBlockingPolicy(const String&, ExceptionCode&);
void setLangAttributeAwareFormControlUIEnabled(bool);
+ void setImagesEnabled(bool enabled, ExceptionCode&);
+
private:
explicit InternalSettings(Page*);
virtual void hostDestroyed() OVERRIDE { m_page = 0; }
diff --git a/Source/WebCore/testing/InternalSettings.idl b/Source/WebCore/testing/InternalSettings.idl
index 9673d2f1c..d8a8aaf8b 100755
--- a/Source/WebCore/testing/InternalSettings.idl
+++ b/Source/WebCore/testing/InternalSettings.idl
@@ -82,6 +82,7 @@ module window {
#endif
void setMemoryInfoEnabled(in boolean enabled) raises(DOMException);
void setStorageBlockingPolicy(in DOMString policy) raises(DOMException);
+ void setImagesEnabled(in boolean enabled) raises(DOMException);
};
}
diff --git a/Source/WebCore/testing/Internals.cpp b/Source/WebCore/testing/Internals.cpp
index 3afb3347a..a213f2faf 100644
--- a/Source/WebCore/testing/Internals.cpp
+++ b/Source/WebCore/testing/Internals.cpp
@@ -32,6 +32,7 @@
#include "ClientRectList.h"
#include "ComposedShadowTreeWalker.h"
#include "DOMStringList.h"
+#include "DOMWindow.h"
#include "Document.h"
#include "DocumentMarker.h"
#include "DocumentMarkerController.h"
@@ -46,9 +47,12 @@
#include "HTMLNames.h"
#include "HTMLTextAreaElement.h"
#include "HistoryItem.h"
+#include "InspectorClient.h"
#include "InspectorConsoleAgent.h"
#include "InspectorController.h"
#include "InspectorCounters.h"
+#include "InspectorFrontendChannel.h"
+#include "InspectorFrontendClientLocal.h"
#include "InspectorInstrumentation.h"
#include "InspectorOverlay.h"
#include "InstrumentingAgents.h"
@@ -105,6 +109,52 @@ namespace WebCore {
using namespace HTMLNames;
+#if ENABLE(INSPECTOR)
+class InspectorFrontendClientDummy : public InspectorFrontendClientLocal {
+public:
+ InspectorFrontendClientDummy(InspectorController*, Page*);
+ virtual ~InspectorFrontendClientDummy() { }
+ virtual void attachWindow() OVERRIDE { }
+ virtual void detachWindow() OVERRIDE { }
+
+ virtual String localizedStringsURL() OVERRIDE { return String(); }
+ virtual String hiddenPanels() OVERRIDE { return String(); }
+
+ virtual void bringToFront() OVERRIDE { }
+ virtual void closeWindow() OVERRIDE { }
+
+ virtual void inspectedURLChanged(const String&) OVERRIDE { }
+
+protected:
+ virtual void setAttachedWindowHeight(unsigned) OVERRIDE { }
+};
+
+InspectorFrontendClientDummy::InspectorFrontendClientDummy(InspectorController* controller, Page* page)
+ : InspectorFrontendClientLocal(controller, page, adoptPtr(new InspectorFrontendClientLocal::Settings()))
+{
+}
+
+class InspectorFrontendChannelDummy : public InspectorFrontendChannel {
+public:
+ explicit InspectorFrontendChannelDummy(Page*);
+ virtual ~InspectorFrontendChannelDummy() { }
+ virtual bool sendMessageToFrontend(const String& message) OVERRIDE;
+
+private:
+ Page* m_frontendPage;
+};
+
+InspectorFrontendChannelDummy::InspectorFrontendChannelDummy(Page* page)
+ : m_frontendPage(page)
+{
+}
+
+bool InspectorFrontendChannelDummy::sendMessageToFrontend(const String& message)
+{
+ return InspectorClient::doDispatchMessageOnFrontendPage(m_frontendPage, message);
+}
+#endif // ENABLE(INSPECTOR)
+
static bool markerTypesFrom(const String& markerType, DocumentMarker::MarkerTypes& result)
{
if (markerType.isEmpty() || equalIgnoringCase(markerType, "all"))
@@ -1061,6 +1111,45 @@ Vector<String> Internals::consoleMessageArgumentCounts(Document* document) const
result[i] = String::number(counts[i]);
return result;
}
+
+PassRefPtr<DOMWindow> Internals::openDummyInspectorFrontend(const String& url)
+{
+ Page* page = contextDocument()->frame()->page();
+ ASSERT(page);
+
+ DOMWindow* window = page->mainFrame()->document()->domWindow();
+ ASSERT(window);
+
+ m_frontendWindow = window->open(url, "", "", window, window);
+ ASSERT(m_frontendWindow);
+
+ Page* frontendPage = m_frontendWindow->document()->page();
+ ASSERT(frontendPage);
+
+ OwnPtr<InspectorFrontendClientDummy> frontendClient = adoptPtr(new InspectorFrontendClientDummy(page->inspectorController(), frontendPage));
+
+ frontendPage->inspectorController()->setInspectorFrontendClient(frontendClient.release());
+
+ m_frontendChannel = adoptPtr(new InspectorFrontendChannelDummy(frontendPage));
+
+ page->inspectorController()->connectFrontend(m_frontendChannel.get());
+
+ return m_frontendWindow;
+}
+
+void Internals::closeDummyInspectorFrontend()
+{
+ Page* page = contextDocument()->frame()->page();
+ ASSERT(page);
+ ASSERT(m_frontendWindow);
+
+ page->inspectorController()->disconnectFrontend();
+
+ m_frontendChannel.release();
+
+ m_frontendWindow->close(m_frontendWindow->scriptExecutionContext());
+ m_frontendWindow.release();
+}
#endif // ENABLE(INSPECTOR)
bool Internals::hasGrammarMarker(Document* document, int from, int length, ExceptionCode&)
diff --git a/Source/WebCore/testing/Internals.h b/Source/WebCore/testing/Internals.h
index d2d452ea9..c3c4cb44b 100644
--- a/Source/WebCore/testing/Internals.h
+++ b/Source/WebCore/testing/Internals.h
@@ -38,10 +38,12 @@ namespace WebCore {
class ClientRect;
class ClientRectList;
class DOMStringList;
+class DOMWindow;
class Document;
class DocumentMarker;
class Element;
class Frame;
+class InspectorFrontendChannelDummy;
class InternalSettings;
class Node;
class PagePopupController;
@@ -192,6 +194,8 @@ public:
unsigned numberOfLiveNodes() const;
unsigned numberOfLiveDocuments() const;
Vector<String> consoleMessageArgumentCounts(Document*) const;
+ PassRefPtr<DOMWindow> openDummyInspectorFrontend(const String& url);
+ void closeDummyInspectorFrontend();
#endif
String counterValue(Element*);
@@ -223,6 +227,10 @@ private:
Frame* frame() const;
DocumentMarker* markerAt(Node*, const String& markerType, unsigned index, ExceptionCode&);
+#if ENABLE(INSPECTOR)
+ RefPtr<DOMWindow> m_frontendWindow;
+ OwnPtr<InspectorFrontendChannelDummy> m_frontendChannel;
+#endif
};
} // namespace WebCore
diff --git a/Source/WebCore/testing/Internals.idl b/Source/WebCore/testing/Internals.idl
index 3bd91299f..f7d0bce70 100644
--- a/Source/WebCore/testing/Internals.idl
+++ b/Source/WebCore/testing/Internals.idl
@@ -171,6 +171,8 @@ module window {
[Conditional=INSPECTOR] unsigned long numberOfLiveNodes();
[Conditional=INSPECTOR] unsigned long numberOfLiveDocuments();
[Conditional=INSPECTOR] sequence<String> consoleMessageArgumentCounts(in Document document);
+ [Conditional=INSPECTOR] DOMWindow openDummyInspectorFrontend(in DOMString url);
+ [Conditional=INSPECTOR] void closeDummyInspectorFrontend();
DOMString counterValue(in Element element);
long pageNumber(in Element element, in [Optional] float pageWidth, in [Optional] float pageHeight);
diff --git a/Source/WebKit/ChangeLog b/Source/WebKit/ChangeLog
index 2ed3fd10e..a09e8df0d 100644
--- a/Source/WebKit/ChangeLog
+++ b/Source/WebKit/ChangeLog
@@ -1,3 +1,16 @@
+2012-09-24 Arvid Nilsson <anilsson@rim.com>
+
+ [BlackBerry] Add cookie database API
+ https://bugs.webkit.org/show_bug.cgi?id=97102
+
+ Reviewed by Antonio Gomes.
+
+ Add cookie database file to build system.
+
+ Reviewed internally by Otto D. Cheung.
+
+ * PlatformBlackBerry.cmake:
+
2012-09-21 Arvid Nilsson <anilsson@rim.com>
[BlackBerry] Remove obsolete compositing surface code
diff --git a/Source/WebKit/PlatformBlackBerry.cmake b/Source/WebKit/PlatformBlackBerry.cmake
index d75ff91d6..7fdb7eca7 100644
--- a/Source/WebKit/PlatformBlackBerry.cmake
+++ b/Source/WebKit/PlatformBlackBerry.cmake
@@ -59,6 +59,7 @@ LIST(APPEND WebKit_SOURCES
blackberry/Api/BlackBerryGlobal.cpp
blackberry/Api/InRegionScroller.cpp
blackberry/Api/WebAnimation.cpp
+ blackberry/Api/WebCookieJar.cpp
blackberry/Api/WebKitMIMETypeConverter.cpp
blackberry/Api/WebKitTextCodec.cpp
blackberry/Api/WebOverlay.cpp
diff --git a/Source/WebKit/blackberry/Api/BlackBerryGlobal.cpp b/Source/WebKit/blackberry/Api/BlackBerryGlobal.cpp
index d8b5c5124..fc9cd5aae 100644
--- a/Source/WebKit/blackberry/Api/BlackBerryGlobal.cpp
+++ b/Source/WebKit/blackberry/Api/BlackBerryGlobal.cpp
@@ -20,7 +20,6 @@
#include "BlackBerryGlobal.h"
#include "ApplicationCacheStorage.h"
-#include "AuthenticationChallengeManager.h"
#include "CacheClientBlackBerry.h"
#include "CookieManager.h"
#include "CrossOriginPreflightResultCache.h"
@@ -81,8 +80,6 @@ void globalInitialize()
BlackBerry::Platform::Settings* settings = BlackBerry::Platform::Settings::instance();
ImageSource::setMaxPixelsPerDecodedImage(settings->maxPixelsPerDecodedImage());
-
- AuthenticationChallengeManager::init();
}
void collectJavascriptGarbageNow()
diff --git a/Source/WebKit/blackberry/Api/WebCookieJar.cpp b/Source/WebKit/blackberry/Api/WebCookieJar.cpp
new file mode 100644
index 000000000..da8964fa8
--- /dev/null
+++ b/Source/WebKit/blackberry/Api/WebCookieJar.cpp
@@ -0,0 +1,60 @@
+/*
+ * Copyright (C) 2012 Research In Motion Limited. All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include "config.h"
+
+#include "WebCookieJar.h"
+
+#include "CookieManager.h"
+#include "KURL.h"
+#include "WebString.h"
+
+using namespace WebCore;
+
+namespace BlackBerry {
+namespace WebKit {
+
+WebCookieJar::WebCookieJar()
+{
+}
+
+std::vector<WebString> WebCookieJar::cookies(const char* url)
+{
+ KURL kurl = KURL(KURL(), String(url));
+
+ Vector<ParsedCookie*> rawCookies;
+ cookieManager().getRawCookies(rawCookies, kurl, WithHttpOnlyCookies);
+
+ std::vector<WebString> result;
+ for (size_t i = 0; i < rawCookies.size(); ++i)
+ result.push_back(WebString(rawCookies[i]->toNameValuePair().impl()));
+
+ return result;
+}
+
+void WebCookieJar::setCookies(const char* url, const std::vector<WebString>& cookies)
+{
+ KURL kurl = KURL(KURL(), String(url));
+ Vector<String> coreCookies;
+ for (size_t i = 0; i < cookies.size(); ++i)
+ coreCookies.append(String(cookies[i].impl()));
+ cookieManager().setCookies(kurl, coreCookies, WithHttpOnlyCookies);
+}
+
+}
+}
diff --git a/Source/WebKit/blackberry/Api/WebCookieJar.h b/Source/WebKit/blackberry/Api/WebCookieJar.h
new file mode 100644
index 000000000..0c174e404
--- /dev/null
+++ b/Source/WebKit/blackberry/Api/WebCookieJar.h
@@ -0,0 +1,70 @@
+/*
+ * Copyright (C) 2012 Research In Motion Limited. All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef WebCookieJar_h
+#define WebCookieJar_h
+
+#include "BlackBerryGlobal.h"
+
+#include <vector>
+
+namespace BlackBerry {
+namespace WebKit {
+
+class WebPage;
+class WebString;
+
+/**
+ * Represents the cookie database.
+ *
+ * You can obtain an instance of WebCookieJar by calling WebPage::cookieJar().
+ */
+class BLACKBERRY_EXPORT WebCookieJar {
+public:
+ /**
+ * Returns a list of cookies for the URL specified.
+ *
+ * All cookies whose domain and path match the provided URL will be returned.
+ */
+ std::vector<WebString> cookies(const char* url);
+
+ /**
+ * This will add the cookies provided in the list to the cookie database.
+ * If a cookie with the same name and domain+path as one of the cookies
+ * provided already exists, it will be replaced. Other cookies that already
+ * existed will remain.
+ *
+ * If no domain and/or path is provided in a cookie, the domain and/or path
+ * will be inferred from the provided URL.
+ */
+ void setCookies(const char* url, const std::vector<WebString>& cookies);
+
+private:
+ friend class WebPage;
+
+ WebCookieJar();
+
+ // Disable copy constructor and operator=.
+ WebCookieJar(const WebCookieJar&);
+ WebCookieJar& operator=(const WebCookieJar&);
+};
+
+}
+}
+
+#endif // WebCookieJar_h
diff --git a/Source/WebKit/blackberry/Api/WebPage.cpp b/Source/WebKit/blackberry/Api/WebPage.cpp
index 128075704..78a2858c2 100644
--- a/Source/WebKit/blackberry/Api/WebPage.cpp
+++ b/Source/WebKit/blackberry/Api/WebPage.cpp
@@ -124,6 +124,7 @@
#include "VibrationClientBlackBerry.h"
#endif
#include "VisiblePosition.h"
+#include "WebCookieJar.h"
#if ENABLE(WEBDOM)
#include "WebDOMDocument.h"
#endif
@@ -349,6 +350,7 @@ WebPagePrivate::WebPagePrivate(WebPage* webPage, WebPageClient* client, const In
, m_mainFrame(0) // Initialized by init.
, m_currentContextNode(0)
, m_webSettings(0) // Initialized by init.
+ , m_cookieJar(0)
, m_visible(false)
, m_activationState(ActivationActive)
, m_shouldResetTilesWhenShown(false)
@@ -427,8 +429,6 @@ WebPagePrivate::WebPagePrivate(WebPage* webPage, WebPageClient* client, const In
BlackBerry::Platform::DeviceInfo::instance();
defaultUserAgent();
}
-
- AuthenticationChallengeManager::instance()->pageCreated(this);
}
WebPage::WebPage(WebPageClient* client, const WebString& pageGroupName, const Platform::IntRect& rect)
@@ -440,7 +440,6 @@ WebPage::WebPage(WebPageClient* client, const WebString& pageGroupName, const Pl
WebPagePrivate::~WebPagePrivate()
{
- AuthenticationChallengeManager::instance()->pageDeleted(this);
// Hand the backingstore back to another owner if necessary.
m_webPage->setVisible(false);
if (BackingStorePrivate::currentBackingStoreOwner() == m_webPage)
@@ -449,6 +448,9 @@ WebPagePrivate::~WebPagePrivate()
delete m_webSettings;
m_webSettings = 0;
+ delete m_cookieJar;
+ m_cookieJar = 0;
+
delete m_backingStoreClient;
m_backingStoreClient = 0;
m_backingStore = 0;
@@ -2213,19 +2215,18 @@ bool WebPagePrivate::isActive() const
return m_client->isActive();
}
-void WebPagePrivate::authenticationChallenge(const KURL& url, const ProtectionSpace& protectionSpace, const Credential& inputCredential)
+void WebPagePrivate::authenticationChallenge(const KURL& url, const ProtectionSpace& protectionSpace, const Credential& inputCredential, AuthenticationChallengeClient* client)
{
WebString username;
WebString password;
- AuthenticationChallengeManager* authmgr = AuthenticationChallengeManager::instance();
#if !defined(PUBLIC_BUILD) || !PUBLIC_BUILD
if (m_dumpRenderTree) {
Credential credential(inputCredential, inputCredential.persistence());
if (m_dumpRenderTree->didReceiveAuthenticationChallenge(credential))
- authmgr->notifyChallengeResult(url, protectionSpace, AuthenticationChallengeSuccess, credential);
+ client->notifyChallengeResult(url, protectionSpace, AuthenticationChallengeSuccess, credential);
else
- authmgr->notifyChallengeResult(url, protectionSpace, AuthenticationChallengeCancelled, inputCredential);
+ client->notifyChallengeResult(url, protectionSpace, AuthenticationChallengeCancelled, inputCredential);
return;
}
#endif
@@ -2246,9 +2247,9 @@ void WebPagePrivate::authenticationChallenge(const KURL& url, const ProtectionSp
#endif
if (isConfirmed)
- authmgr->notifyChallengeResult(url, protectionSpace, AuthenticationChallengeSuccess, credential);
+ client->notifyChallengeResult(url, protectionSpace, AuthenticationChallengeSuccess, credential);
else
- authmgr->notifyChallengeResult(url, protectionSpace, AuthenticationChallengeCancelled, inputCredential);
+ client->notifyChallengeResult(url, protectionSpace, AuthenticationChallengeCancelled, inputCredential);
}
PageClientBlackBerry::SaveCredentialType WebPagePrivate::notifyShouldSaveCredential(bool isNew)
@@ -3191,6 +3192,14 @@ WebSettings* WebPage::settings() const
return d->m_webSettings;
}
+WebCookieJar* WebPage::cookieJar() const
+{
+ if (!d->m_cookieJar)
+ d->m_cookieJar = new WebCookieJar();
+
+ return d->m_cookieJar;
+}
+
bool WebPage::isVisible() const
{
return d->m_visible;
@@ -3240,7 +3249,6 @@ void WebPage::setVisible(bool visible)
return;
d->setVisible(visible);
- AuthenticationChallengeManager::instance()->pageVisibilityChanged(d, visible);
if (!visible) {
d->suspendBackingStore();
diff --git a/Source/WebKit/blackberry/Api/WebPage.h b/Source/WebKit/blackberry/Api/WebPage.h
index 20c48f00e..31b990808 100644
--- a/Source/WebKit/blackberry/Api/WebPage.h
+++ b/Source/WebKit/blackberry/Api/WebPage.h
@@ -66,6 +66,7 @@ class BackingStoreClient;
class BackingStorePrivate;
class InRegionScroller;
class RenderQueue;
+class WebCookieJar;
class WebOverlay;
class WebPageClient;
class WebPageCompositor;
@@ -127,6 +128,8 @@ public:
WebSettings* settings() const;
+ WebCookieJar* cookieJar() const;
+
void setVisible(bool);
bool isVisible() const;
diff --git a/Source/WebKit/blackberry/Api/WebPage_p.h b/Source/WebKit/blackberry/Api/WebPage_p.h
index bcb7d5009..ca0c180c0 100644
--- a/Source/WebKit/blackberry/Api/WebPage_p.h
+++ b/Source/WebKit/blackberry/Api/WebPage_p.h
@@ -77,6 +77,7 @@ class InPageSearchManager;
class InputHandler;
class SelectionHandler;
class TouchEventHandler;
+class WebCookieJar;
class WebPageClient;
#if USE(ACCELERATED_COMPOSITING)
@@ -201,7 +202,7 @@ public:
virtual int showAlertDialog(WebPageClient::AlertType atype);
virtual bool isActive() const;
virtual bool isVisible() const { return m_visible; }
- virtual void authenticationChallenge(const WebCore::KURL&, const WebCore::ProtectionSpace&, const WebCore::Credential&);
+ virtual void authenticationChallenge(const WebCore::KURL&, const WebCore::ProtectionSpace&, const WebCore::Credential&, WebCore::AuthenticationChallengeClient*);
virtual SaveCredentialType notifyShouldSaveCredential(bool);
virtual void syncProxyCredential(const WebCore::Credential&);
@@ -469,6 +470,7 @@ public:
WebCore::Frame* m_mainFrame;
RefPtr<WebCore::Node> m_currentContextNode;
WebSettings* m_webSettings;
+ WebCookieJar* m_cookieJar;
OwnPtr<WebTapHighlight> m_tapHighlight;
WebSelectionOverlay* m_selectionOverlay;
diff --git a/Source/WebKit/blackberry/Api/WebString.cpp b/Source/WebKit/blackberry/Api/WebString.cpp
index 640b673c9..0e75fc1a6 100644
--- a/Source/WebKit/blackberry/Api/WebString.cpp
+++ b/Source/WebKit/blackberry/Api/WebString.cpp
@@ -65,6 +65,11 @@ WebString WebString::fromUtf8(const char* utf8)
return String::fromUTF8(utf8);
}
+WebString WebString::fromUtf8(const char* utf8, size_t length)
+{
+ return String::fromUTF8(utf8, length);
+}
+
WebString& WebString::operator=(const WebString& str)
{
if (&str == this)
diff --git a/Source/WebKit/blackberry/Api/WebString.h b/Source/WebKit/blackberry/Api/WebString.h
index fe43c247f..c2af16b79 100644
--- a/Source/WebKit/blackberry/Api/WebString.h
+++ b/Source/WebKit/blackberry/Api/WebString.h
@@ -41,6 +41,7 @@ public:
WebString& operator=(const WebString&);
std::string utf8() const;
static WebString fromUtf8(const char* utf8);
+ static WebString fromUtf8(const char* utf8, size_t length);
const unsigned short* characters() const;
unsigned length() const;
bool isEmpty() const;
diff --git a/Source/WebKit/blackberry/ChangeLog b/Source/WebKit/blackberry/ChangeLog
index ed5687843..c32d3c4f3 100644
--- a/Source/WebKit/blackberry/ChangeLog
+++ b/Source/WebKit/blackberry/ChangeLog
@@ -1,3 +1,88 @@
+2012-09-24 Mark Lam <mark.lam@apple.com>
+
+ Deleting the classic interpreter and cleaning up some build options.
+ https://bugs.webkit.org/show_bug.cgi?id=96969.
+
+ Reviewed by Geoffrey Garen.
+
+ * WebCoreSupport/AboutDataEnableFeatures.in:
+
+2012-09-24 Benjamin Poulain <bpoulain@apple.com>
+
+ Fix Geolocation error reporting in the test support
+ https://bugs.webkit.org/show_bug.cgi?id=97386
+
+ Reviewed by Sam Weinig.
+
+ * WebKitSupport/DumpRenderTreeSupport.cpp:
+ (DumpRenderTreeSupport::setMockGeolocationPositionUnavailableError):
+ * WebKitSupport/DumpRenderTreeSupport.h:
+ (DumpRenderTreeSupport):
+
+2012-09-24 Otto Derek Cheung <otcheung@rim.com>
+
+ [BlackBerry] Reverting implementation for 407 error pages
+ https://bugs.webkit.org/show_bug.cgi?id=97455
+
+ Reviewed by Rob Buis.
+
+ Revert "[BlackBerry] Really fix bug 95488 that user can get the
+ authentication challenge dialog while the other tab has focus."
+ https://bugs.webkit.org/show_bug.cgi?id=97348
+
+ This reverts commit 0cffe01961fb80204138505bcec29a83818efb73.
+
+ * Api/BlackBerryGlobal.cpp:
+ (BlackBerry::WebKit::globalInitialize):
+ * Api/WebPage.cpp:
+ (BlackBerry::WebKit::WebPagePrivate::WebPagePrivate):
+ (BlackBerry::WebKit::WebPagePrivate::~WebPagePrivate):
+ (BlackBerry::WebKit::WebPagePrivate::authenticationChallenge):
+ (BlackBerry::WebKit::WebPage::setVisible):
+ * Api/WebPage_p.h:
+ (WebPagePrivate):
+
+2012-09-24 Arvid Nilsson <anilsson@rim.com>
+
+ [BlackBerry] Add cookie database API
+ https://bugs.webkit.org/show_bug.cgi?id=97102
+
+ Reviewed by Antonio Gomes.
+
+ The cookie database is exposed through WebCookieJar, which has only two
+ methods: cookies() and setCookies().
+
+ Also add a new WebString::fromUTF8 overload that takes a const char*
+ and a length, in order to avoid a strlen call when converting from
+ other string classes to WebString. This is useful for callers of the
+ new cookie API when converting cookies to WebString.
+
+ Reviewed internally by Otto D. Cheung.
+
+ PR 209282
+
+ * Api/WebCookieJar.cpp: Added.
+ (WebKit):
+ (BlackBerry::WebKit::WebCookieJar::WebCookieJar):
+ (BlackBerry::WebKit::WebCookieJar::cookies):
+ (BlackBerry::WebKit::WebCookieJar::setCookies):
+ * Api/WebCookieJar.h: Added.
+ (WebKit):
+ * Api/WebPage.cpp:
+ (BlackBerry::WebKit::WebPagePrivate::WebPagePrivate):
+ (BlackBerry::WebKit::WebPagePrivate::~WebPagePrivate):
+ (BlackBerry::WebKit::WebPage::cookieJar):
+ (WebKit):
+ * Api/WebPage.h:
+ (WebKit):
+ * Api/WebPage_p.h:
+ (WebKit):
+ (WebPagePrivate):
+ * Api/WebString.cpp:
+ (BlackBerry::WebKit::WebString::fromUtf8):
+ (WebKit):
+ * Api/WebString.h:
+
2012-09-21 Lianghui Chen <liachen@rim.com>
[BlackBerry] Really fix bug 95488 that user can get the authentication challenge dialog while the other tab has focus.
diff --git a/Source/WebKit/blackberry/WebCoreSupport/AboutDataEnableFeatures.in b/Source/WebKit/blackberry/WebCoreSupport/AboutDataEnableFeatures.in
index 45986026b..6b0ba389d 100644
--- a/Source/WebKit/blackberry/WebCoreSupport/AboutDataEnableFeatures.in
+++ b/Source/WebKit/blackberry/WebCoreSupport/AboutDataEnableFeatures.in
@@ -12,11 +12,9 @@ BLOB
BRANCH_COMPACTION
CALENDAR_PICKER
CHANNEL_MESSAGING
-CLASSIC_INTERPRETER
CODEBLOCK_SAMPLING
COMPARE_AND_SWAP
COMPUTED_GOTO
-COMPUTED_GOTO_CLASSIC_INTERPRETER
COMPUTED_GOTO_INTERPRETER
CONSISTENCY_CHECK
CONTEXT_MENUS
diff --git a/Source/WebKit/blackberry/WebKitSupport/DumpRenderTreeSupport.cpp b/Source/WebKit/blackberry/WebKitSupport/DumpRenderTreeSupport.cpp
index e4e4ef0c0..ea4ac5601 100644
--- a/Source/WebKit/blackberry/WebKitSupport/DumpRenderTreeSupport.cpp
+++ b/Source/WebKit/blackberry/WebKitSupport/DumpRenderTreeSupport.cpp
@@ -1,5 +1,6 @@
/*
* Copyright (C) 2012 Research In Motion Limited. All rights reserved.
+ * Copyright (C) 2012 Apple Inc. All Rights Reserved.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -95,20 +96,10 @@ void DumpRenderTreeSupport::resetGeolocationMock(WebPage* webPage)
mockClient->reset();
}
-void DumpRenderTreeSupport::setMockGeolocationError(WebPage* webPage, int errorCode, const String message)
+void DumpRenderTreeSupport::setMockGeolocationPositionUnavailableError(WebPage* webPage, const String message)
{
- GeolocationError::ErrorCode code = GeolocationError::PositionUnavailable;
- switch (errorCode) {
- case PositionError::PERMISSION_DENIED:
- code = GeolocationError::PermissionDenied;
- break;
- case PositionError::POSITION_UNAVAILABLE:
- code = GeolocationError::PositionUnavailable;
- break;
- }
-
GeolocationClientMock* mockClient = static_cast<GeolocationClientMock*>(GeolocationController::from(corePage(webPage))->client());
- mockClient->setError(GeolocationError::create(code, message));
+ mockClient->setPositionUnavailableError(message);
}
void DumpRenderTreeSupport::setMockGeolocationPermission(WebPage* webPage, bool allowed)
diff --git a/Source/WebKit/blackberry/WebKitSupport/DumpRenderTreeSupport.h b/Source/WebKit/blackberry/WebKitSupport/DumpRenderTreeSupport.h
index 58fc1b53e..01fe4f83a 100644
--- a/Source/WebKit/blackberry/WebKitSupport/DumpRenderTreeSupport.h
+++ b/Source/WebKit/blackberry/WebKitSupport/DumpRenderTreeSupport.h
@@ -1,5 +1,6 @@
/*
* Copyright (C) 2012 Research In Motion Limited. All rights reserved.
+ * Copyright (C) 2012 Apple Inc. All Rights Reserved.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -52,7 +53,7 @@ public:
static int numberOfPendingGeolocationPermissionRequests(BlackBerry::WebKit::WebPage*);
static void resetGeolocationMock(BlackBerry::WebKit::WebPage*);
- static void setMockGeolocationError(BlackBerry::WebKit::WebPage*, int errorCode, const WTF::String message);
+ static void setMockGeolocationPositionUnavailableError(BlackBerry::WebKit::WebPage*, const WTF::String message);
static void setMockGeolocationPermission(BlackBerry::WebKit::WebPage*, bool allowed);
static void setMockGeolocationPosition(BlackBerry::WebKit::WebPage*, double latitude, double longitude, double accuracy);
static void scalePageBy(BlackBerry::WebKit::WebPage*, float, float, float);
diff --git a/Source/WebKit/chromium/ChangeLog b/Source/WebKit/chromium/ChangeLog
index 340eed6af..b216df91a 100644
--- a/Source/WebKit/chromium/ChangeLog
+++ b/Source/WebKit/chromium/ChangeLog
@@ -1,3 +1,121 @@
+2012-09-21 Ilya Tikhonovsky <loislo@chromium.org>
+
+ Web Inspector: extract Vector instrumentation from core NMI code into MemoryInstrumentationVector.h header.
+ https://bugs.webkit.org/show_bug.cgi?id=96650
+
+ Reviewed by Vsevolod Vlasov.
+
+ Test for instrumented vector.
+
+ * tests/MemoryInstrumentationTest.cpp:
+ (WebCore::InstrumentedOwner::InstrumentedOwner):
+ (WebCore::TEST):
+ (WebCore):
+
+2012-09-24 Benjamin Poulain <bpoulain@apple.com>
+
+ Fix Geolocation error reporting in the test support
+ https://bugs.webkit.org/show_bug.cgi?id=97386
+
+ Reviewed by Sam Weinig.
+
+ * public/WebGeolocationClientMock.h:
+ (WebGeolocationClientMock):
+ * src/WebGeolocationClientMock.cpp:
+ (WebKit::WebGeolocationClientMock::setMockGeolocationPositionUnavailableError):
+
+2012-09-24 Kent Tamura <tkent@chromium.org>
+
+ [Chromium] Implement ValidationMessageClient for Chromium
+ https://bugs.webkit.org/show_bug.cgi?id=97167
+
+ Reviewed by Hajime Morita.
+
+ Introduce ValidationMessageClientImpl. However actual popup
+ implementation should be done in WebViewClient.
+
+ * WebKit.gyp: Add ValidationMessageClientImpl.{cpp,h}.
+ * public/WebViewClient.h:
+ (WebKit::WebViewClient::showValidationMessage): Added.
+ (WebKit::WebViewClient::hideValidationMessage): Added.
+ * src/ValidationMessageClientImpl.cpp: Added.
+ (WebKit::ValidationMessageClientImpl::ValidationMessageClientImpl):
+ (WebKit::ValidationMessageClientImpl::create):
+ (WebKit::ValidationMessageClientImpl::~ValidationMessageClientImpl):
+ Make sure that a popup is closed.
+ (WebKit::ValidationMessageClientImpl::showValidationMessage):
+ Implementataion of ValidationMessageClient::showValidationMessage.
+ minimumSecondToShowValidationMessage and secondPerCharacter are same as
+ the corresponding values in the current Shadow DOM implementation.
+ (WebKit::ValidationMessageClientImpl::hideValidationMessage):
+ Implementataion of ValidationMessageClient::hideValidationMessage.
+ (WebKit::ValidationMessageClientImpl::isValidationMessageVisible):
+ Implementataion of ValidationMessageClient::isValidationMessageVisible.
+ (WebKit::ValidationMessageClientImpl::hideCurrentValidationMessage):
+ This is a callback function for the timer.
+ * src/ValidationMessageClientImpl.h: Added.
+
+ * src/WebViewImpl.cpp:
+ (WebKit::WebViewImpl::WebViewImpl):
+ - Initialize m_validationMessage.
+ - Add a comment for PageClients.
+ * src/WebViewImpl.h:
+ Add m_validationMessage.
+
+2012-09-24 Mihai Parparita <mihaip@chromium.org>
+
+ [Chromium] Remove WebRuntimeFeatures::{enablePushState,isPushStateEnabled}
+ https://bugs.webkit.org/show_bug.cgi?id=97506
+
+ Reviewed by Adam Barth.
+
+ These methods have been no-ops since r127674. All Chromium code that
+ called them was removed with http://crrev.com/155205.
+
+ * public/WebRuntimeFeatures.h:
+ (WebRuntimeFeatures):
+ * src/WebRuntimeFeatures.cpp:
+
+2012-09-24 Mark Pilgrim <pilgrim@chromium.org>
+
+ [Chromium][Mac] Remove loadFont from PlatformSupport
+ https://bugs.webkit.org/show_bug.cgi?id=97360
+
+ Reviewed by Adam Barth.
+
+ Part of a refactoring series. See tracking bug 82948.
+
+ * src/PlatformSupport.cpp:
+ (WebCore):
+
+2012-09-24 Tony Chang <tony@chromium.org>
+
+ Unreviewed. Rolled DEPS.
+
+ * DEPS:
+
+2012-09-24 Dana Jansens <danakj@chromium.org>
+
+ [chromium] Add setters to WebFilterOperation for IPC pickling
+ https://bugs.webkit.org/show_bug.cgi?id=97147
+
+ Reviewed by James Robinson.
+
+ * tests/FilterOperationsTest.cpp:
+ (WebKit):
+ (WebKit::TEST):
+
+2012-09-24 Patrick Gansterer <paroga@webkit.org>
+
+ Remove remaining WTF_DEPRECATED_STRING_OPERATORS from cpp files
+ https://bugs.webkit.org/show_bug.cgi?id=97412
+
+ Reviewed by Adam Barth.
+
+ * src/WebPageSerializerImpl.cpp:
+ (WebKit::WebPageSerializerImpl::openTagToString): Replaced operator+= with StringBuilder::append().
+ (WebKit::WebPageSerializerImpl::endTagToString): Ditto.
+
2012-09-24 Yury Semikhatsky <yurys@chromium.org>
Unreviewed, rolling out r122243.
diff --git a/Source/WebKit/chromium/DEPS b/Source/WebKit/chromium/DEPS
index 5f3d4b55e..f5ee44aef 100644
--- a/Source/WebKit/chromium/DEPS
+++ b/Source/WebKit/chromium/DEPS
@@ -32,7 +32,7 @@
vars = {
'chromium_svn': 'http://src.chromium.org/svn/trunk/src',
- 'chromium_rev': '158095'
+ 'chromium_rev': '158289'
}
deps = {
diff --git a/Source/WebKit/chromium/WebKit.gyp b/Source/WebKit/chromium/WebKit.gyp
index ad86d1a9e..f4f4c9ece 100644
--- a/Source/WebKit/chromium/WebKit.gyp
+++ b/Source/WebKit/chromium/WebKit.gyp
@@ -467,6 +467,8 @@
'src/TextFieldDecoratorImpl.cpp',
'src/UserMediaClientImpl.h',
'src/UserMediaClientImpl.cpp',
+ 'src/ValidationMessageClientImpl.cpp',
+ 'src/ValidationMessageClientImpl.h',
'src/WebTextCheckingCompletionImpl.h',
'src/WebTextCheckingCompletionImpl.cpp',
'src/WebTextCheckingResult.cpp',
diff --git a/Source/WebKit/chromium/public/WebGeolocationClientMock.h b/Source/WebKit/chromium/public/WebGeolocationClientMock.h
index 052a546ad..a04d1ddde 100644
--- a/Source/WebKit/chromium/public/WebGeolocationClientMock.h
+++ b/Source/WebKit/chromium/public/WebGeolocationClientMock.h
@@ -49,7 +49,7 @@ public:
~WebGeolocationClientMock() { reset(); }
WEBKIT_EXPORT void setPosition(double latitude, double longitude, double accuracy);
- WEBKIT_EXPORT void setError(int errorCode, const WebString& message);
+ WEBKIT_EXPORT void setPositionUnavailableError(const WebString& message);
WEBKIT_EXPORT void setPermission(bool);
WEBKIT_EXPORT int numberOfPendingPermissionRequests() const;
WEBKIT_EXPORT void resetMock();
diff --git a/Source/WebKit/chromium/public/WebRuntimeFeatures.h b/Source/WebKit/chromium/public/WebRuntimeFeatures.h
index 6d0629fea..64cf829b5 100644
--- a/Source/WebKit/chromium/public/WebRuntimeFeatures.h
+++ b/Source/WebKit/chromium/public/WebRuntimeFeatures.h
@@ -76,10 +76,6 @@ public:
WEBKIT_EXPORT static void enableWebAudio(bool);
WEBKIT_EXPORT static bool isWebAudioEnabled();
- // TODO: Remove these (since they're no-ops) once Chromium code stops calling them.
- WEBKIT_EXPORT static void enablePushState(bool);
- WEBKIT_EXPORT static bool isPushStateEnabled(bool);
-
WEBKIT_EXPORT static void enableTouch(bool);
WEBKIT_EXPORT static bool isTouchEnabled();
diff --git a/Source/WebKit/chromium/public/WebViewClient.h b/Source/WebKit/chromium/public/WebViewClient.h
index 88da1416b..da6498d30 100644
--- a/Source/WebKit/chromium/public/WebViewClient.h
+++ b/Source/WebKit/chromium/public/WebViewClient.h
@@ -293,6 +293,13 @@ public:
// Return true to swallow the input event if the embedder will start a disambiguation popup
virtual bool didTapMultipleTargets(const WebGestureEvent&, const WebVector<WebRect>& targetRects) { return false; }
+ // Show a notification popup for the specified form vaidation messages
+ // besides the anchor rectangle. An implementation of this function should
+ // not hide the popup until hideValidationMessage call.
+ virtual void showValidationMessage(const WebRect& anchorInScreen, const WebString& mainText, const WebString& supplementalText, WebTextDirection hint) { }
+ // Hide notifation popup for form validation messages.
+ virtual void hideValidationMessage() { }
+
// Session history -----------------------------------------------------
// Tells the embedder to navigate back or forward in session history by
diff --git a/Source/WebKit/chromium/src/PlatformSupport.cpp b/Source/WebKit/chromium/src/PlatformSupport.cpp
index 8d0df4d44..7cd6453f6 100644
--- a/Source/WebKit/chromium/src/PlatformSupport.cpp
+++ b/Source/WebKit/chromium/src/PlatformSupport.cpp
@@ -217,24 +217,6 @@ bool PlatformSupport::ensureFontLoaded(HFONT font)
}
#endif
-#if OS(DARWIN)
-bool PlatformSupport::loadFont(NSFont* srcFont, CGFontRef* out, uint32_t* fontID)
-{
- WebSandboxSupport* ss = WebKit::Platform::current()->sandboxSupport();
- if (ss)
- return ss->loadFont(srcFont, out, fontID);
-
- // This function should only be called in response to an error loading a
- // font due to being blocked by the sandbox.
- // This by definition shouldn't happen if there is no sandbox support.
- ASSERT_NOT_REACHED();
- *out = 0;
- *fontID = 0;
- return false;
-}
-#elif OS(UNIX)
-#endif
-
// Indexed Database -----------------------------------------------------------
PassRefPtr<IDBFactoryBackendInterface> PlatformSupport::idbFactory()
diff --git a/Source/WebKit/chromium/src/ValidationMessageClientImpl.cpp b/Source/WebKit/chromium/src/ValidationMessageClientImpl.cpp
new file mode 100644
index 000000000..5ea79297f
--- /dev/null
+++ b/Source/WebKit/chromium/src/ValidationMessageClientImpl.cpp
@@ -0,0 +1,97 @@
+/*
+ * Copyright (C) 2012 Google 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"
+#include "ValidationMessageClientImpl.h"
+
+#include "Element.h"
+#include "FrameView.h"
+#include "RenderObject.h"
+#include "WebTextDirection.h"
+#include "WebViewClient.h"
+
+using namespace WebCore;
+
+namespace WebKit {
+
+ValidationMessageClientImpl::ValidationMessageClientImpl(WebViewClient& client)
+ : m_client(client)
+ , m_currentAnchor(0)
+ , m_timer(this, &ValidationMessageClientImpl::hideCurrentValidationMessage)
+{
+}
+
+PassOwnPtr<ValidationMessageClientImpl> ValidationMessageClientImpl::create(WebViewClient& client)
+{
+ return adoptPtr(new ValidationMessageClientImpl(client));
+}
+
+ValidationMessageClientImpl::~ValidationMessageClientImpl()
+{
+ if (m_currentAnchor)
+ hideValidationMessage(*m_currentAnchor);
+}
+
+void ValidationMessageClientImpl::showValidationMessage(const Element& anchor, const String& message)
+{
+ if (message.isEmpty()) {
+ hideValidationMessage(anchor);
+ return;
+ }
+ if (!anchor.renderBox())
+ return;
+ if (m_currentAnchor)
+ hideValidationMessage(*m_currentAnchor);
+ m_currentAnchor = &anchor;
+ IntRect anchorInScreen = anchor.document()->view()->contentsToScreen(anchor.pixelSnappedBoundingBox());
+ WebTextDirection dir = anchor.renderer()->style()->direction() == RTL ? WebTextDirectionRightToLeft : WebTextDirectionLeftToRight;
+ m_client.showValidationMessage(anchorInScreen, message, anchor.fastGetAttribute(HTMLNames::titleAttr), dir);
+
+ const double minimumSecondToShowValidationMessage = 5.0;
+ const double secondPerCharacter = 0.05;
+ m_timer.startOneShot(std::max(minimumSecondToShowValidationMessage, message.length() * secondPerCharacter));
+}
+
+void ValidationMessageClientImpl::hideValidationMessage(const Element& anchor)
+{
+ if (!m_currentAnchor || !isValidationMessageVisible(anchor))
+ return;
+ m_timer.stop();
+ m_client.hideValidationMessage();
+ m_currentAnchor = 0;
+}
+
+bool ValidationMessageClientImpl::isValidationMessageVisible(const Element& anchor)
+{
+ return m_currentAnchor == &anchor;
+}
+
+void ValidationMessageClientImpl::hideCurrentValidationMessage(Timer<ValidationMessageClientImpl>*)
+{
+ ASSERT(m_currentAnchor);
+ hideValidationMessage(*m_currentAnchor);
+}
+
+}
diff --git a/Source/WebKit/chromium/src/ValidationMessageClientImpl.h b/Source/WebKit/chromium/src/ValidationMessageClientImpl.h
new file mode 100644
index 000000000..0206bba47
--- /dev/null
+++ b/Source/WebKit/chromium/src/ValidationMessageClientImpl.h
@@ -0,0 +1,56 @@
+/*
+ * Copyright (C) 2012 Google 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.
+ */
+
+#ifndef ValidationMessageClientImpl_h
+#define ValidationMessageClientImpl_h
+
+#include "Timer.h"
+#include "ValidationMessageClient.h"
+
+namespace WebKit {
+
+class WebViewClient;
+
+class ValidationMessageClientImpl : public WebCore::ValidationMessageClient {
+public:
+ static PassOwnPtr<ValidationMessageClientImpl> create(WebViewClient&);
+ virtual ~ValidationMessageClientImpl();
+
+private:
+ explicit ValidationMessageClientImpl(WebViewClient&);
+ void hideCurrentValidationMessage(WebCore::Timer<ValidationMessageClientImpl>*);
+
+ virtual void showValidationMessage(const WebCore::Element& anchor, const String& message) OVERRIDE;
+ virtual void hideValidationMessage(const WebCore::Element& anchor) OVERRIDE;
+ virtual bool isValidationMessageVisible(const WebCore::Element& anchor) OVERRIDE;
+
+ WebViewClient& m_client;
+ const WebCore::Element* m_currentAnchor;
+ WebCore::Timer<ValidationMessageClientImpl> m_timer;
+};
+
+}
+
+#endif
diff --git a/Source/WebKit/chromium/src/WebDocument.cpp b/Source/WebKit/chromium/src/WebDocument.cpp
index 691701715..3486613be 100644
--- a/Source/WebKit/chromium/src/WebDocument.cpp
+++ b/Source/WebKit/chromium/src/WebDocument.cpp
@@ -35,6 +35,7 @@
#include "CSSParserMode.h"
#include "Document.h"
#include "DocumentLoader.h"
+#include "DocumentStyleSheetCollection.h"
#include "DocumentType.h"
#include "Element.h"
#include "HTMLAllCollection.h"
@@ -196,7 +197,7 @@ void WebDocument::insertUserStyleSheet(const WebString& sourceCode, UserStyleLev
RefPtr<StyleSheetContents> parsedSheet = StyleSheetContents::create(document.get());
parsedSheet->setIsUserStyleSheet(level == UserStyleUserLevel);
parsedSheet->parseString(sourceCode);
- document->addUserSheet(parsedSheet.release());
+ document->styleSheetCollection()->addUserSheet(parsedSheet.release());
}
void WebDocument::cancelFullScreen()
diff --git a/Source/WebKit/chromium/src/WebGeolocationClientMock.cpp b/Source/WebKit/chromium/src/WebGeolocationClientMock.cpp
index 3d9630707..a7948a78e 100644
--- a/Source/WebKit/chromium/src/WebGeolocationClientMock.cpp
+++ b/Source/WebKit/chromium/src/WebGeolocationClientMock.cpp
@@ -41,6 +41,7 @@
#include "WebGeolocationError.h"
#include "WebGeolocationPermissionRequest.h"
#include "WebGeolocationPosition.h"
+#include "platform/WebString.h"
using namespace WebCore;
@@ -58,23 +59,9 @@ void WebGeolocationClientMock::setPosition(double latitude, double longitude, do
m_clientMock->setPosition(webPosition);
}
-void WebGeolocationClientMock::setError(int errorCode, const WebString& message)
+void WebGeolocationClientMock::setPositionUnavailableError(const WebString& message)
{
- WebGeolocationError::Error code;
- switch (errorCode) {
- case PositionError::PERMISSION_DENIED:
- code = WebGeolocationError::ErrorPermissionDenied;
- break;
- case PositionError::POSITION_UNAVAILABLE:
- code = WebGeolocationError::ErrorPositionUnavailable;
- break;
- default:
- ASSERT_NOT_REACHED();
- return;
- }
-
- WebGeolocationError webError(code, message);
- m_clientMock->setError(webError);
+ m_clientMock->setPositionUnavailableError(message);
}
void WebGeolocationClientMock::setPermission(bool allowed)
diff --git a/Source/WebKit/chromium/src/WebPageSerializerImpl.cpp b/Source/WebKit/chromium/src/WebPageSerializerImpl.cpp
index 793ca8b83..02a665a11 100644
--- a/Source/WebKit/chromium/src/WebPageSerializerImpl.cpp
+++ b/Source/WebKit/chromium/src/WebPageSerializerImpl.cpp
@@ -75,8 +75,6 @@
// override the incorrect base URL and make sure we alway load correct local
// saved resource files.
-#define WTF_DEPRECATED_STRING_OPERATORS
-
#include "config.h"
#include "WebPageSerializerImpl.h"
@@ -300,23 +298,24 @@ void WebPageSerializerImpl::encodeAndFlushBuffer(
void WebPageSerializerImpl::openTagToString(Element* element,
SerializeDomParam* param)
{
- // FIXME: use StringBuilder instead of String.
bool needSkip;
+ StringBuilder result;
// Do pre action for open tag.
- String result = preActionBeforeSerializeOpenTag(element, param, &needSkip);
+ result.append(preActionBeforeSerializeOpenTag(element, param, &needSkip));
if (needSkip)
return;
// Add open tag
- result += "<" + element->nodeName().lower();
+ result.append('<');
+ result.append(element->nodeName().lower());
// Go through all attributes and serialize them.
if (element->hasAttributes()) {
unsigned numAttrs = element->attributeCount();
for (unsigned i = 0; i < numAttrs; i++) {
- result += " ";
+ result.append(' ');
// Add attribute pair
const Attribute *attribute = element->attributeItem(i);
- result += attribute->name().toString();
- result += "=\"";
+ result.append(attribute->name().toString());
+ result.appendLiteral("=\"");
if (!attribute->value().isEmpty()) {
const String& attrValue = attribute->value();
@@ -326,7 +325,7 @@ void WebPageSerializerImpl::openTagToString(Element* element,
if (elementHasLegalLinkAttribute(element, attrName)) {
// For links start with "javascript:", we do not change it.
if (attrValue.startsWith("javascript:", false))
- result += attrValue;
+ result.append(attrValue);
else {
// Get the absolute link
WebFrameImpl* subFrame = WebFrameImpl::fromFrameOwnerElement(element);
@@ -334,20 +333,23 @@ void WebPageSerializerImpl::openTagToString(Element* element,
param->document->completeURL(attrValue);
// Check whether we have local files for those link.
if (m_localLinks.contains(completeURL)) {
- if (!param->directoryName.isEmpty())
- result += "./" + param->directoryName + "/";
- result += m_localLinks.get(completeURL);
+ if (!param->directoryName.isEmpty()) {
+ result.appendLiteral("./");
+ result.append(param->directoryName);
+ result.append('/');
+ }
+ result.append(m_localLinks.get(completeURL));
} else
- result += completeURL;
+ result.append(completeURL);
}
} else {
if (param->isHTMLDocument)
- result += m_htmlEntities.convertEntitiesInString(attrValue);
+ result.append(m_htmlEntities.convertEntitiesInString(attrValue));
else
- result += m_xmlEntities.convertEntitiesInString(attrValue);
+ result.append(m_xmlEntities.convertEntitiesInString(attrValue));
}
}
- result += "\"";
+ result.append('\"');
}
}
@@ -355,11 +357,11 @@ void WebPageSerializerImpl::openTagToString(Element* element,
String addedContents = postActionAfterSerializeOpenTag(element, param);
// Complete the open tag for element when it has child/children.
if (element->hasChildNodes() || param->haveAddedContentsBeforeEnd)
- result += ">";
+ result.append('>');
// Append the added contents generate in post action of open tag.
- result += addedContents;
+ result.append(addedContents);
// Save the result to data buffer.
- saveHTMLContentToBuffer(result, param);
+ saveHTMLContentToBuffer(result.toString(), param);
}
// Serialize end tag of an specified element.
@@ -367,37 +369,36 @@ void WebPageSerializerImpl::endTagToString(Element* element,
SerializeDomParam* param)
{
bool needSkip;
+ StringBuilder result;
// Do pre action for end tag.
- String result = preActionBeforeSerializeEndTag(element,
- param,
- &needSkip);
+ result.append(preActionBeforeSerializeEndTag(element, param, &needSkip));
if (needSkip)
return;
// Write end tag when element has child/children.
if (element->hasChildNodes() || param->haveAddedContentsBeforeEnd) {
- result += "</";
- result += element->nodeName().lower();
- result += ">";
+ result.appendLiteral("</");
+ result.append(element->nodeName().lower());
+ result.append('>');
} else {
// Check whether we have to write end tag for empty element.
if (param->isHTMLDocument) {
- result += ">";
+ result.append('>');
// FIXME: This code is horribly wrong. WebPageSerializerImpl must die.
if (!static_cast<const HTMLElement*>(element)->ieForbidsInsertHTML()) {
// We need to write end tag when it is required.
- result += "</";
- result += element->nodeName().lower();
- result += ">";
+ result.appendLiteral("</");
+ result.append(element->nodeName().lower());
+ result.append('>');
}
} else {
// For xml base document.
- result += " />";
+ result.appendLiteral(" />");
}
}
// Do post action for end tag.
- result += postActionAfterSerializeEndTag(element, param);
+ result.append(postActionAfterSerializeEndTag(element, param));
// Save the result to data buffer.
- saveHTMLContentToBuffer(result, param);
+ saveHTMLContentToBuffer(result.toString(), param);
}
void WebPageSerializerImpl::buildContentForNode(Node* node,
diff --git a/Source/WebKit/chromium/src/WebRuntimeFeatures.cpp b/Source/WebKit/chromium/src/WebRuntimeFeatures.cpp
index bcdba86c1..4e64c664b 100644
--- a/Source/WebKit/chromium/src/WebRuntimeFeatures.cpp
+++ b/Source/WebKit/chromium/src/WebRuntimeFeatures.cpp
@@ -204,15 +204,6 @@ bool WebRuntimeFeatures::isWebAudioEnabled()
#endif
}
-void WebRuntimeFeatures::enablePushState(bool)
-{
-}
-
-bool WebRuntimeFeatures::isPushStateEnabled(bool enable)
-{
- return true;
-}
-
void WebRuntimeFeatures::enableTouch(bool enable)
{
#if ENABLE(TOUCH_EVENTS)
diff --git a/Source/WebKit/chromium/src/WebViewImpl.cpp b/Source/WebKit/chromium/src/WebViewImpl.cpp
index 764ae6dca..6666571b3 100644
--- a/Source/WebKit/chromium/src/WebViewImpl.cpp
+++ b/Source/WebKit/chromium/src/WebViewImpl.cpp
@@ -120,6 +120,7 @@
#include "TextIterator.h"
#include "Timer.h"
#include "TraceEvent.h"
+#include "ValidationMessageClientImpl.h"
#include "WebAccessibilityObject.h"
#include "WebActiveWheelFlingParameters.h"
#include "WebAutofillClient.h"
@@ -436,6 +437,7 @@ WebViewImpl::WebViewImpl(WebViewClient* client)
, m_navigatorContentUtilsClient(NavigatorContentUtilsClientImpl::create(this))
#endif
, m_flingModifier(0)
+ , m_validationMessage(ValidationMessageClientImpl::create(*client))
{
// WebKit/win/WebView.cpp does the same thing, except they call the
// KJS specific wrapper around this method. We need to have threading
@@ -450,6 +452,7 @@ WebViewImpl::WebViewImpl(WebViewClient* client)
pageClients.dragClient = &m_dragClientImpl;
pageClients.inspectorClient = &m_inspectorClientImpl;
pageClients.backForwardClient = BackForwardListChromium::create(this);
+ // FIXME: Set pageClients.validationMessageClient when Chromium-side implementation is done.
m_page = adoptPtr(new Page(pageClients));
#if ENABLE(MEDIA_STREAM)
diff --git a/Source/WebKit/chromium/src/WebViewImpl.h b/Source/WebKit/chromium/src/WebViewImpl.h
index 865898608..4c1a974a0 100644
--- a/Source/WebKit/chromium/src/WebViewImpl.h
+++ b/Source/WebKit/chromium/src/WebViewImpl.h
@@ -99,6 +99,7 @@ class PrerendererClientImpl;
class SpeechInputClientImpl;
class SpeechRecognitionClientProxy;
class UserMediaClientImpl;
+class ValidationMessageClientImpl;
class WebAccessibilityObject;
class WebCompositorImpl;
class WebDevToolsAgentClient;
@@ -862,6 +863,7 @@ private:
#if ENABLE(GESTURE_EVENTS)
OwnPtr<LinkHighlight> m_linkHighlight;
#endif
+ OwnPtr<ValidationMessageClientImpl> m_validationMessage;
};
} // namespace WebKit
diff --git a/Source/WebKit/chromium/tests/FilterOperationsTest.cpp b/Source/WebKit/chromium/tests/FilterOperationsTest.cpp
index 8a3c5d8a1..873d216cd 100644
--- a/Source/WebKit/chromium/tests/FilterOperationsTest.cpp
+++ b/Source/WebKit/chromium/tests/FilterOperationsTest.cpp
@@ -89,5 +89,108 @@ TEST(WebFilterOperationsTest, getOutsetsDropShadow)
EXPECT_EQ(54, left);
}
+#define SAVE_RESTORE_AMOUNT(Type, a) \
+ { \
+ WebFilterOperation op = WebFilterOperation::create##Type##Filter(a); \
+ EXPECT_EQ(WebFilterOperation::FilterType##Type, op.type()); \
+ EXPECT_EQ(a, op.amount()); \
+ \
+ WebFilterOperation op2 = WebFilterOperation::createEmptyFilter(); \
+ op2.setType(WebFilterOperation::FilterType##Type); \
+ \
+ EXPECT_NE(a, op2.amount()); \
+ \
+ op2.setAmount(a); \
+ \
+ EXPECT_EQ(WebFilterOperation::FilterType##Type, op2.type()); \
+ EXPECT_EQ(a, op2.amount()); \
+ }
+
+#define SAVE_RESTORE_OFFSET_AMOUNT_COLOR(Type, a, b, c) \
+ { \
+ WebFilterOperation op = WebFilterOperation::create##Type##Filter(a, b, c); \
+ EXPECT_EQ(WebFilterOperation::FilterType##Type, op.type()); \
+ EXPECT_EQ(a, op.dropShadowOffset()); \
+ EXPECT_EQ(b, op.amount()); \
+ EXPECT_EQ(c, op.dropShadowColor()); \
+ \
+ WebFilterOperation op2 = WebFilterOperation::createEmptyFilter(); \
+ op2.setType(WebFilterOperation::FilterType##Type); \
+ \
+ EXPECT_NE(a, op2.dropShadowOffset()); \
+ EXPECT_NE(b, op2.amount()); \
+ EXPECT_NE(c, op2.dropShadowColor()); \
+ \
+ op2.setDropShadowOffset(a); \
+ op2.setAmount(b); \
+ op2.setDropShadowColor(c); \
+ \
+ EXPECT_EQ(WebFilterOperation::FilterType##Type, op2.type()); \
+ EXPECT_EQ(a, op2.dropShadowOffset()); \
+ EXPECT_EQ(b, op2.amount()); \
+ EXPECT_EQ(c, op2.dropShadowColor()); \
+ }
+
+#define SAVE_RESTORE_MATRIX(Type, a) \
+ { \
+ WebFilterOperation op = WebFilterOperation::create##Type##Filter(a); \
+ EXPECT_EQ(WebFilterOperation::FilterType##Type, op.type()); \
+ for (unsigned i = 0; i < 20; ++i) \
+ EXPECT_EQ(a[i], op.matrix()[i]); \
+ \
+ WebFilterOperation op2 = WebFilterOperation::createEmptyFilter(); \
+ op2.setType(WebFilterOperation::FilterType##Type); \
+ \
+ for (unsigned i = 0; i < 20; ++i) \
+ EXPECT_NE(a[i], op2.matrix()[i]); \
+ \
+ op2.setMatrix(a); \
+ \
+ EXPECT_EQ(WebFilterOperation::FilterType##Type, op2.type()); \
+ for (unsigned i = 0; i < 20; ++i) \
+ EXPECT_EQ(a[i], op.matrix()[i]); \
+ }
+
+#define SAVE_RESTORE_ZOOMRECT_AMOUNT(Type, a, b) \
+ { \
+ WebFilterOperation op = WebFilterOperation::create##Type##Filter(a, b); \
+ EXPECT_EQ(WebFilterOperation::FilterType##Type, op.type()); \
+ EXPECT_EQ(a, op.zoomRect()); \
+ EXPECT_EQ(b, op.amount()); \
+ \
+ WebFilterOperation op2 = WebFilterOperation::createEmptyFilter(); \
+ op2.setType(WebFilterOperation::FilterType##Type); \
+ \
+ EXPECT_NE(a, op2.zoomRect()); \
+ EXPECT_NE(b, op2.amount()); \
+ \
+ op2.setZoomRect(a); \
+ op2.setAmount(b); \
+ \
+ EXPECT_EQ(WebFilterOperation::FilterType##Type, op2.type()); \
+ EXPECT_EQ(a, op2.zoomRect()); \
+ EXPECT_EQ(b, op2.amount()); \
+ }
+
+
+TEST(WebFilterOperationsTest, saveAndRestore)
+{
+ SAVE_RESTORE_AMOUNT(Grayscale, 0.6f);
+ SAVE_RESTORE_AMOUNT(Sepia, 0.6f);
+ SAVE_RESTORE_AMOUNT(Saturate, 0.6f);
+ SAVE_RESTORE_AMOUNT(HueRotate, 0.6f);
+ SAVE_RESTORE_AMOUNT(Invert, 0.6f);
+ SAVE_RESTORE_AMOUNT(Brightness, 0.6f);
+ SAVE_RESTORE_AMOUNT(Contrast, 0.6f);
+ SAVE_RESTORE_AMOUNT(Opacity, 0.6f);
+ SAVE_RESTORE_AMOUNT(Blur, 0.6f);
+ SAVE_RESTORE_OFFSET_AMOUNT_COLOR(DropShadow, WebPoint(3, 4), 0.4f, 0xffffff00);
+
+ SkScalar matrix[20] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20 };
+ SAVE_RESTORE_MATRIX(ColorMatrix, matrix);
+
+ SAVE_RESTORE_ZOOMRECT_AMOUNT(Zoom, WebRect(20, 19, 18, 17), 32);
+}
+
}
diff --git a/Source/WebKit/chromium/tests/MemoryInstrumentationTest.cpp b/Source/WebKit/chromium/tests/MemoryInstrumentationTest.cpp
index 4acf496ad..21ce96316 100644
--- a/Source/WebKit/chromium/tests/MemoryInstrumentationTest.cpp
+++ b/Source/WebKit/chromium/tests/MemoryInstrumentationTest.cpp
@@ -37,6 +37,7 @@
#include <gtest/gtest.h>
#include <wtf/HashSet.h>
+#include <wtf/MemoryInstrumentationVector.h>
#include <wtf/RefCounted.h>
#include <wtf/Vector.h>
#include <wtf/text/AtomicString.h>
@@ -235,6 +236,7 @@ class InstrumentedOwner {
public:
template<typename V>
InstrumentedOwner(const V& value) : m_value(value) { }
+ InstrumentedOwner() { }
void reportMemoryUsage(MemoryObjectInfo* memoryObjectInfo) const
{
MemoryClassInfo info(memoryObjectInfo, this, WebCoreMemoryTypes::DOM);
@@ -367,5 +369,75 @@ TEST(MemoryInstrumentationTest, detectReportMemoryUsageMethod)
}
}
+TEST(MemoryInstrumentationTest, vectorZeroInlineCapacity)
+{
+ VisitedObjects visitedObjects;
+ MemoryInstrumentationImpl impl(visitedObjects);
+ InstrumentedOwner<Vector<int> > vectorOwner(16);
+ impl.addRootObject(vectorOwner);
+ EXPECT_EQ(16 * sizeof(int), impl.reportedSizeForAllTypes());
+ EXPECT_EQ(1, visitedObjects.size());
+}
+
+TEST(MemoryInstrumentationTest, vectorFieldWithInlineCapacity)
+{
+ VisitedObjects visitedObjects;
+ MemoryInstrumentationImpl impl(visitedObjects);
+ InstrumentedOwner<Vector<int, 4> > vectorOwner;
+ impl.addRootObject(vectorOwner);
+ EXPECT_EQ(static_cast<size_t>(0), impl.reportedSizeForAllTypes());
+ EXPECT_EQ(0, visitedObjects.size());
+}
+
+TEST(MemoryInstrumentationTest, vectorFieldWithInlineCapacityResized)
+{
+ VisitedObjects visitedObjects;
+ MemoryInstrumentationImpl impl(visitedObjects);
+ InstrumentedOwner<Vector<int, 4> > vectorOwner;
+ vectorOwner.m_value.reserveCapacity(8);
+ impl.addRootObject(vectorOwner);
+ EXPECT_EQ(8 * sizeof(int), impl.reportedSizeForAllTypes());
+ EXPECT_EQ(1, visitedObjects.size());
+}
+
+TEST(MemoryInstrumentationTest, heapAllocatedVectorWithInlineCapacity)
+{
+ VisitedObjects visitedObjects;
+ MemoryInstrumentationImpl impl(visitedObjects);
+ InstrumentedOwner<OwnPtr<Vector<int, 4> > > vectorOwner;
+ vectorOwner.m_value = adoptPtr(new Vector<int, 4>());
+ impl.addRootObject(vectorOwner);
+ EXPECT_EQ(sizeof(Vector<int, 4>), impl.reportedSizeForAllTypes());
+ EXPECT_EQ(1, visitedObjects.size());
+}
+
+TEST(MemoryInstrumentationTest, heapAllocatedVectorWithInlineCapacityResized)
+{
+ VisitedObjects visitedObjects;
+ MemoryInstrumentationImpl impl(visitedObjects);
+ InstrumentedOwner<OwnPtr<Vector<int, 4> > > vectorOwner;
+ vectorOwner.m_value = adoptPtr(new Vector<int, 4>());
+ vectorOwner.m_value->reserveCapacity(8);
+ impl.addRootObject(vectorOwner);
+ EXPECT_EQ(8 * sizeof(int) + sizeof(Vector<int, 4>), impl.reportedSizeForAllTypes());
+ EXPECT_EQ(2, visitedObjects.size());
+}
+
+TEST(MemoryInstrumentationTest, vectorWithInstrumentedType)
+{
+ VisitedObjects visitedObjects;
+ MemoryInstrumentationImpl impl(visitedObjects);
+
+ typedef Vector<String> StringVector;
+ OwnPtr<StringVector> value = adoptPtr(new StringVector());
+ size_t count = 10;
+ for (size_t i = 0; i < count; ++i)
+ value->append("string");
+ InstrumentedOwner<StringVector* > root(value.get());
+ impl.addRootObject(root);
+ EXPECT_EQ(sizeof(StringVector) + sizeof(String) * value->capacity() + sizeof(StringImpl) * value->size(), impl.reportedSizeForAllTypes());
+ EXPECT_EQ(count + 2, (size_t)visitedObjects.size());
+}
+
} // namespace
diff --git a/Source/WebKit/efl/ChangeLog b/Source/WebKit/efl/ChangeLog
index c0d31cae1..137c5c115 100644
--- a/Source/WebKit/efl/ChangeLog
+++ b/Source/WebKit/efl/ChangeLog
@@ -1,3 +1,15 @@
+2012-09-24 Dominik Röttsches <dominik.rottsches@intel.com>
+
+ [EFL][DRT] Enable Regions support
+ https://bugs.webkit.org/show_bug.cgi?id=83897
+
+ Reviewed by Kenneth Rohde Christiansen.
+
+ Activating CSS regions by default for EWK views.
+
+ * ewk/ewk_view.cpp: Switch CSS regions on by default.
+ (_ewk_view_priv_new):
+
2012-09-23 Byungwoo Lee <bw80.lee@gmail.com>
Fix build warnings : -Wunused-parameter, -Wparentheses, -Wuninitialized.
diff --git a/Source/WebKit/efl/ewk/ewk_view.cpp b/Source/WebKit/efl/ewk/ewk_view.cpp
index f0b69673d..b2d6367a5 100644
--- a/Source/WebKit/efl/ewk/ewk_view.cpp
+++ b/Source/WebKit/efl/ewk/ewk_view.cpp
@@ -793,6 +793,7 @@ static Ewk_View_Private_Data* _ewk_view_priv_new(Ewk_View_Smart_Data* smartData)
priv->pageSettings->setSansSerifFontFamily("sans");
priv->pageSettings->setStandardFontFamily("sans");
priv->pageSettings->setHyperlinkAuditingEnabled(false);
+ priv->pageSettings->setCSSRegionsEnabled(true);
priv->pageSettings->setScriptEnabled(true);
priv->pageSettings->setPluginsEnabled(true);
priv->pageSettings->setLocalStorageEnabled(true);
diff --git a/Source/WebKit/gtk/ChangeLog b/Source/WebKit/gtk/ChangeLog
index c1afa53ed..e69726d5b 100644
--- a/Source/WebKit/gtk/ChangeLog
+++ b/Source/WebKit/gtk/ChangeLog
@@ -1,3 +1,44 @@
+2012-09-24 Benjamin Poulain <bpoulain@apple.com>
+
+ Fix Geolocation error reporting in the test support
+ https://bugs.webkit.org/show_bug.cgi?id=97386
+
+ Reviewed by Sam Weinig.
+
+ * WebCoreSupport/DumpRenderTreeSupportGtk.cpp:
+ (DumpRenderTreeSupportGtk::setMockGeolocationPositionUnavailableError):
+ * WebCoreSupport/DumpRenderTreeSupportGtk.h:
+ (DumpRenderTreeSupportGtk):
+
+2012-09-24 Zan Dobersek <zandobersek@gmail.com>
+
+ [Gtk] Unskip the Shadow DOM layout tests
+ https://bugs.webkit.org/show_bug.cgi?id=90776
+
+ Reviewed by Ryosuke Niwa.
+
+ Add a method for enabling the Shadow DOM through RuntimeEnabledFeatures.
+ The method is called from DumpRenderTree when resetting state.
+
+ * WebCoreSupport/DumpRenderTreeSupportGtk.cpp:
+ (DumpRenderTreeSupportGtk::setShadowDOMEnabled):
+ * WebCoreSupport/DumpRenderTreeSupportGtk.h:
+ (DumpRenderTreeSupportGtk):
+
+2012-09-24 Joone Hur <joone.hur@intel.com>
+
+ [GTK] Implement GraphicsLayer using Clutter
+ https://bugs.webkit.org/show_bug.cgi?id=73767
+
+ Reviewed by Martin Robinson.
+
+ This patch is needed for enabling Accelerated Compositing(Clutter backend)
+ with the patches submitted in bug 92045 and 91940.
+
+ * WebCoreSupport/AcceleratedCompositingContextClutter.cpp:
+ (WebKit::AcceleratedCompositingContext::scrollNonCompositedContents): Added to fix bulid break.
+ (WebKit):
+
2012-09-19 Danilo Cesar Lemes de Paula <danilo.cesar@collabora.co.uk>
[gtk] add enable-media-stream to websettings
diff --git a/Source/WebKit/gtk/WebCoreSupport/AcceleratedCompositingContextClutter.cpp b/Source/WebKit/gtk/WebCoreSupport/AcceleratedCompositingContextClutter.cpp
index 451117a82..c523bb545 100644
--- a/Source/WebKit/gtk/WebCoreSupport/AcceleratedCompositingContextClutter.cpp
+++ b/Source/WebKit/gtk/WebCoreSupport/AcceleratedCompositingContextClutter.cpp
@@ -112,6 +112,11 @@ void AcceleratedCompositingContext::resizeRootLayer(const IntSize& size)
gtk_widget_size_allocate(GTK_WIDGET(m_rootLayerEmbedder), &allocation);
}
+void AcceleratedCompositingContext::scrollNonCompositedContents(const IntRect& scrollRect, const IntSize& scrollOffset)
+{
+ notImplemented();
+}
+
static gboolean flushAndRenderLayersCallback(AcceleratedCompositingContext* context)
{
context->flushAndRenderLayers();
diff --git a/Source/WebKit/gtk/WebCoreSupport/DumpRenderTreeSupportGtk.cpp b/Source/WebKit/gtk/WebCoreSupport/DumpRenderTreeSupportGtk.cpp
index e5d6989d1..b39d5ae75 100644
--- a/Source/WebKit/gtk/WebCoreSupport/DumpRenderTreeSupportGtk.cpp
+++ b/Source/WebKit/gtk/WebCoreSupport/DumpRenderTreeSupportGtk.cpp
@@ -3,6 +3,7 @@
* Copyright (C) 2010 Joone Hur <joone@kldp.org>
* Copyright (C) 2009 Google Inc. All rights reserved.
* Copyright (C) 2011 Igalia S.L.
+ * Copyright (C) 2012 Apple Inc. All Rights Reserved.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -60,6 +61,7 @@
#include "RenderTreeAsText.h"
#include "RenderView.h"
#include "ResourceLoadScheduler.h"
+#include "RuntimeEnabledFeatures.h"
#include "SchemeRegistry.h"
#include "SecurityOrigin.h"
#include "SecurityPolicy.h"
@@ -658,23 +660,11 @@ void DumpRenderTreeSupportGtk::setMockGeolocationPosition(WebKitWebView* webView
#endif
}
-void DumpRenderTreeSupportGtk::setMockGeolocationError(WebKitWebView* webView, int errorCode, const gchar* errorMessage)
+void DumpRenderTreeSupportGtk::setMockGeolocationPositionUnavailableError(WebKitWebView* webView, const gchar* errorMessage)
{
#if ENABLE(GEOLOCATION)
GeolocationClientMock* mock = static_cast<GeolocationClientMock*>(GeolocationController::from(core(webView))->client());
-
- GeolocationError::ErrorCode code;
- switch (errorCode) {
- case PositionError::PERMISSION_DENIED:
- code = GeolocationError::PermissionDenied;
- break;
- case PositionError::POSITION_UNAVAILABLE:
- default:
- code = GeolocationError::PositionUnavailable;
- break;
- }
-
- mock->setError(GeolocationError::create(code, errorMessage));
+ mock->setPositionUnavailableError(errorMessage);
#endif
}
@@ -701,6 +691,11 @@ void DumpRenderTreeSupportGtk::setCSSRegionsEnabled(WebKitWebView* webView, bool
core(webView)->settings()->setCSSRegionsEnabled(enabled);
}
+void DumpRenderTreeSupportGtk::setShadowDOMEnabled(bool enabled)
+{
+ RuntimeEnabledFeatures::setShadowDOMEnabled(enabled);
+}
+
bool DumpRenderTreeSupportGtk::elementDoesAutoCompleteForElementWithId(WebKitWebFrame* frame, JSStringRef id)
{
Frame* coreFrame = core(frame);
diff --git a/Source/WebKit/gtk/WebCoreSupport/DumpRenderTreeSupportGtk.h b/Source/WebKit/gtk/WebCoreSupport/DumpRenderTreeSupportGtk.h
index 375020d7b..44ac78329 100644
--- a/Source/WebKit/gtk/WebCoreSupport/DumpRenderTreeSupportGtk.h
+++ b/Source/WebKit/gtk/WebCoreSupport/DumpRenderTreeSupportGtk.h
@@ -1,5 +1,6 @@
/*
* Copyright (C) Research In Motion Limited 2010. All rights reserved.
+ * Copyright (C) 2012 Apple Inc. All Rights Reserved.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -111,12 +112,13 @@ public:
static void resetGeolocationClientMock(WebKitWebView*);
static void setMockGeolocationPermission(WebKitWebView*, bool allowed);
static void setMockGeolocationPosition(WebKitWebView*, double latitude, double longitude, double accuracy);
- static void setMockGeolocationError(WebKitWebView*, int errorCode, const gchar* errorMessage);
+ static void setMockGeolocationPositionUnavailableError(WebKitWebView*, const gchar* errorMessage);
static int numberOfPendingGeolocationPermissionRequests(WebKitWebView*);
static void setPageCacheSupportsPlugins(WebKitWebView*, bool enabled);
static void setCSSGridLayoutEnabled(WebKitWebView*, bool enabled);
static void setCSSRegionsEnabled(WebKitWebView*, bool enabled);
+ static void setShadowDOMEnabled(bool enabled);
static void deliverAllMutationsIfNecessary();
static void setDomainRelaxationForbiddenForURLScheme(bool forbidden, const char* urlScheme);
diff --git a/Source/WebKit/mac/ChangeLog b/Source/WebKit/mac/ChangeLog
index 1a1fc1591..7579b6513 100644
--- a/Source/WebKit/mac/ChangeLog
+++ b/Source/WebKit/mac/ChangeLog
@@ -1,3 +1,24 @@
+2012-09-24 Benjamin Poulain <bpoulain@apple.com>
+
+ Fix Geolocation error reporting in the test support
+ https://bugs.webkit.org/show_bug.cgi?id=97386
+
+ Reviewed by Sam Weinig.
+
+ * WebView/WebView.mm:
+ (-[WebView _geolocationDidFailWithMessage:]):
+ * WebView/WebViewPrivate.h:
+
+2012-09-24 Ryosuke Niwa <rniwa@webkit.org>
+
+ suspend/resumeWidgetHierarchyUpdates should be a RAII object
+ https://bugs.webkit.org/show_bug.cgi?id=96706
+
+ Reviewed by Simon Fraser.
+
+ * WebView/WebHTMLView.mm:
+ (-[WebHTMLView _invalidateGStatesForTree]):
+
2012-09-21 Chris Rogers <crogers@google.com>
Add Web Audio support for deprecated/legacy APIs
diff --git a/Source/WebKit/mac/WebView/WebHTMLView.mm b/Source/WebKit/mac/WebView/WebHTMLView.mm
index bfede8db6..82716a6c9 100644
--- a/Source/WebKit/mac/WebView/WebHTMLView.mm
+++ b/Source/WebKit/mac/WebView/WebHTMLView.mm
@@ -3376,9 +3376,8 @@ static void setMenuTargets(NSMenu* menu)
// descendants, including plug-in views. This can result in calls out to plug-in code and back into
// WebCore via JavaScript, which could normally mutate the NSView tree while it is being traversed.
// Defer those mutations while descendants are being traveresed.
- RenderWidget::suspendWidgetHierarchyUpdates();
+ WidgetHierarchyUpdatesSuspensionScope suspendWidgetHierarchyUpdates;
[super _invalidateGStatesForTree];
- RenderWidget::resumeWidgetHierarchyUpdates();
}
- (BOOL)isFlipped
diff --git a/Source/WebKit/mac/WebView/WebView.mm b/Source/WebKit/mac/WebView/WebView.mm
index c1f0a2d89..80d54174c 100644
--- a/Source/WebKit/mac/WebView/WebView.mm
+++ b/Source/WebKit/mac/WebView/WebView.mm
@@ -6511,11 +6511,11 @@ static void glibContextIterationCallback(CFRunLoopObserverRef, CFRunLoopActivity
#endif // ENABLE(GEOLOCATION)
}
-- (void)_geolocationDidFailWithError:(NSError *)error
+- (void)_geolocationDidFailWithMessage:(NSString *)errorMessage
{
#if ENABLE(GEOLOCATION)
if (_private && _private->page) {
- RefPtr<GeolocationError> geolocatioError = GeolocationError::create(GeolocationError::PositionUnavailable, [error localizedDescription]);
+ RefPtr<GeolocationError> geolocatioError = GeolocationError::create(GeolocationError::PositionUnavailable, errorMessage);
WebCore::GeolocationController::from(_private->page)->errorOccurred(geolocatioError.get());
}
#endif // ENABLE(GEOLOCATION)
diff --git a/Source/WebKit/mac/WebView/WebViewPrivate.h b/Source/WebKit/mac/WebView/WebViewPrivate.h
index 826474e41..c46d35e12 100644
--- a/Source/WebKit/mac/WebView/WebViewPrivate.h
+++ b/Source/WebKit/mac/WebView/WebViewPrivate.h
@@ -728,7 +728,7 @@ Could be worth adding to the API.
- (id<WebGeolocationProvider>)_geolocationProvider;
- (void)_geolocationDidChangePosition:(WebGeolocationPosition *)position;
-- (void)_geolocationDidFailWithError:(NSError *)error;
+- (void)_geolocationDidFailWithMessage:(NSString *)errorMessage;
@end
@interface WebView (WebViewNotification)
diff --git a/Source/WebKit/qt/ChangeLog b/Source/WebKit/qt/ChangeLog
index 5aa62f179..3d7cedaa7 100644
--- a/Source/WebKit/qt/ChangeLog
+++ b/Source/WebKit/qt/ChangeLog
@@ -1,3 +1,14 @@
+2012-09-24 Benjamin Poulain <bpoulain@apple.com>
+
+ Fix Geolocation error reporting in the test support
+ https://bugs.webkit.org/show_bug.cgi?id=97386
+
+ Reviewed by Sam Weinig.
+
+ * WebCoreSupport/DumpRenderTreeSupportQt.cpp:
+ (DumpRenderTreeSupportQt::setMockGeolocationPositionUnavailableError):
+ * WebCoreSupport/DumpRenderTreeSupportQt.h:
+
2012-09-20 Csaba Osztrogonác <ossy@webkit.org>
[Qt] Enable CSS regions by default
diff --git a/Source/WebKit/qt/WebCoreSupport/DumpRenderTreeSupportQt.cpp b/Source/WebKit/qt/WebCoreSupport/DumpRenderTreeSupportQt.cpp
index dc823165c..1ec3644e0 100644
--- a/Source/WebKit/qt/WebCoreSupport/DumpRenderTreeSupportQt.cpp
+++ b/Source/WebKit/qt/WebCoreSupport/DumpRenderTreeSupportQt.cpp
@@ -2,7 +2,7 @@
Copyright (C) 2010 Robert Hogan <robert@roberthogan.net>
Copyright (C) 2008,2009,2010 Nokia Corporation and/or its subsidiary(-ies)
Copyright (C) 2007 Staikos Computing Services Inc.
- Copyright (C) 2007 Apple Inc.
+ Copyright (C) 2007, 2012 Apple Inc.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
@@ -753,23 +753,12 @@ void DumpRenderTreeSupportQt::setMockGeolocationPosition(QWebPage* page, double
#endif
}
-void DumpRenderTreeSupportQt::setMockGeolocationError(QWebPage* page, int errorCode, const QString& message)
+void DumpRenderTreeSupportQt::setMockGeolocationPositionUnavailableError(QWebPage* page, const QString& message)
{
#if ENABLE(GEOLOCATION)
Page* corePage = QWebPagePrivate::core(page);
-
- GeolocationError::ErrorCode code = GeolocationError::PositionUnavailable;
- switch (errorCode) {
- case PositionError::PERMISSION_DENIED:
- code = GeolocationError::PermissionDenied;
- break;
- case PositionError::POSITION_UNAVAILABLE:
- code = GeolocationError::PositionUnavailable;
- break;
- }
-
GeolocationClientMock* mockClient = static_cast<GeolocationClientMock*>(GeolocationController::from(corePage)->client());
- mockClient->setError(GeolocationError::create(code, message));
+ mockClient->setPositionUnavailableError(message);
#endif
}
diff --git a/Source/WebKit/qt/WebCoreSupport/DumpRenderTreeSupportQt.h b/Source/WebKit/qt/WebCoreSupport/DumpRenderTreeSupportQt.h
index 862213657..cefb9d1c8 100644
--- a/Source/WebKit/qt/WebCoreSupport/DumpRenderTreeSupportQt.h
+++ b/Source/WebKit/qt/WebCoreSupport/DumpRenderTreeSupportQt.h
@@ -2,7 +2,7 @@
Copyright (C) 2010 Robert Hogan <robert@roberthogan.net>
Copyright (C) 2008,2009,2010 Nokia Corporation and/or its subsidiary(-ies)
Copyright (C) 2007 Staikos Computing Services Inc.
- Copyright (C) 2007 Apple Inc.
+ Copyright (C) 2007, 2012 Apple Inc.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
@@ -141,7 +141,7 @@ public:
static void resetGeolocationMock(QWebPage*);
static void setMockGeolocationPermission(QWebPage*, bool allowed);
static void setMockGeolocationPosition(QWebPage*, double latitude, double longitude, double accuracy);
- static void setMockGeolocationError(QWebPage*, int errorCode, const QString& message);
+ static void setMockGeolocationPositionUnavailableError(QWebPage*, const QString& message);
static int numberOfPendingGeolocationPermissionRequests(QWebPage*);
static int workerThreadCount();
diff --git a/Source/WebKit2/ChangeLog b/Source/WebKit2/ChangeLog
index 18bdebe61..66240b840 100644
--- a/Source/WebKit2/ChangeLog
+++ b/Source/WebKit2/ChangeLog
@@ -1,3 +1,320 @@
+2012-09-25 Mikhail Pozdnyakov <mikhail.pozdnyakov@intel.com>
+
+ [WK2][WTR] WTR bundle client loads binary data as text
+ https://bugs.webkit.org/show_bug.cgi?id=97532
+
+ Reviewed by Kenneth Rohde Christiansen.
+
+ Added WKBundlePageCanShowMIMEType() function to WKBundlePage private API.
+ This function is put to WKBundlePage to keep consistency with WebKit::WebPageProxy::canShowMIMEType().
+ Actually it does not need anything from page.
+
+ * WebProcess/InjectedBundle/API/c/WKBundlePage.cpp:
+ (WKBundlePageCanShowMIMEType):
+ * WebProcess/InjectedBundle/API/c/WKBundlePagePrivate.h:
+
+2012-09-25 Carlos Garcia Campos <cgarcia@igalia.com>
+
+ [GTK] Don't use the C API internally in WebKitWebView
+ https://bugs.webkit.org/show_bug.cgi?id=96767
+
+ Reviewed by Gustavo Noronha Silva.
+
+ Using the C++ classes directly instead of the C API wrappers we
+ avoid a lot of toImpl/toAPI casts, string conversions and
+ allocations. The code is also a lot simpler and easier to read.
+
+ * UIProcess/API/gtk/WebKitContextMenuClient.cpp:
+ (getContextMenuFromProposedMenu):
+ * UIProcess/API/gtk/WebKitResourceLoadClient.cpp:
+ (didInitiateLoadForResource):
+ * UIProcess/API/gtk/WebKitUIClient.cpp:
+ (createNewPage):
+ (runJavaScriptPrompt):
+ (mouseDidMoveOverElement):
+ (printFrame):
+ * UIProcess/API/gtk/WebKitURIRequest.cpp:
+ (webkitURIRequestCreateForResourceRequest):
+ (webkitURIRequestGetResourceRequest):
+ * UIProcess/API/gtk/WebKitURIRequestPrivate.h:
+ * UIProcess/API/gtk/WebKitWebView.cpp:
+ (allowModalDialogsChanged):
+ (zoomTextOnlyChanged):
+ (webkitWebViewSetSettings):
+ (webkitWebViewConstructed):
+ (webkitWebViewUpdateURI):
+ (webkitWebViewCreateNewPage):
+ (webkitWebViewRunJavaScriptPrompt):
+ (webkitWebViewMouseTargetChanged):
+ (webkitWebViewPrintFrame):
+ (webkitWebViewResourceLoadStarted):
+ (webkitWebViewPopulateContextMenu):
+ (webkit_web_view_load_uri):
+ (webkit_web_view_load_html):
+ (webkit_web_view_load_alternate_html):
+ (webkit_web_view_load_plain_text):
+ (webkit_web_view_load_request):
+ (webkit_web_view_reload):
+ (webkit_web_view_reload_bypass_cache):
+ (webkit_web_view_stop_loading):
+ (webkit_web_view_go_back):
+ (webkit_web_view_can_go_back):
+ (webkit_web_view_go_forward):
+ (webkit_web_view_can_go_forward):
+ (webkit_web_view_get_custom_charset):
+ (webkit_web_view_set_custom_charset):
+ (webkit_web_view_go_to_back_forward_list_item):
+ (webkit_web_view_set_settings):
+ (webkit_web_view_set_zoom_level):
+ (webkit_web_view_get_zoom_level):
+ (webkit_web_view_can_execute_editing_command):
+ (webkit_web_view_execute_editing_command):
+ (webkit_web_view_run_javascript):
+ (webkit_web_view_get_inspector):
+ (webkit_web_view_can_show_mime_type):
+ (ViewSaveAsyncData):
+ (getContentsAsMHTMLDataCallback):
+ (webkit_web_view_save):
+ (webkit_web_view_save_finish):
+ (webkit_web_view_save_to_file):
+ * UIProcess/API/gtk/WebKitWebViewBase.cpp:
+ (webkitWebViewBaseCreate):
+ (webkitWebViewBaseCreateWebPage):
+ * UIProcess/API/gtk/WebKitWebViewBasePrivate.h:
+ * UIProcess/API/gtk/WebKitWebViewPrivate.h:
+
+2012-09-24 Bo Liu <boliu@chromium.org>
+
+ Reland "Add in-place reload behavior to ImagesEnabled setting" with optimizations
+ https://bugs.webkit.org/show_bug.cgi?id=97055
+
+ Reviewed by Adam Barth.
+
+ Relanding 128780, 128676, 128645. Was reverted in 128914 due to
+ performance regression in Chromium.
+
+ New changes in addition to previously reverted patches:
+
+ Refactored CachedResource::requestResource, loadResource, and
+ revalidateResource. Moved CachedResource::load method to end of
+ requestResource so there is one place where load is called for all
+ resources.
+
+ Added a enum parameter for requestResource and
+ determineRevalidationPolicy so that FrameLoaderClient::allowImage call
+ do not need to be called multiple times.
+
+ Removed CachedImage::load call in requestImage so it is not called
+ twice.
+
+ Removed unnecessary Frame.h includes in CachedResource and
+ CachedImage.
+
+ Removed dead load() method declaration in CachedImage.
+
+ Updated text expectation for two image-permissions tests to reflect
+ the removed calls to allowImage.
+
+ * win/WebKit2.def:
+
+2012-09-24 Sam Weinig <sam@webkit.org>
+
+ WKProcessGroup can't load injected bundle with file URL
+ <rdar://problem/12322774>
+ https://bugs.webkit.org/show_bug.cgi?id=97520
+
+ Reviewed by Anders Carlsson.
+
+ * UIProcess/API/mac/WKProcessGroup.mm:
+ (-[WKProcessGroup initWithInjectedBundleURL:]):
+ Fix typo. We need to pass the string as path, not as a URL.
+
+2012-09-24 Sam Weinig <sam@webkit.org>
+
+ Use NSUserDefaults rather than an environment variable to control whether to use an XPC Service for the WebProcess
+ https://bugs.webkit.org/show_bug.cgi?id=97514
+
+ Reviewed by Anders Carlsson.
+
+ * GNUmakefile.list.am:
+ * PlatformEfl.cmake:
+ * Target.pri:
+ Add new files.
+
+ * UIProcess/Launcher/ProcessLauncher.h:
+ * UIProcess/WebProcessProxy.cpp:
+ (WebKit::WebProcessProxy::connect):
+ Move platform specific launch options to a new function, platformConnect.
+
+ * UIProcess/WebProcessProxy.h:
+ * UIProcess/efl/WebProcessProxyEfl.cpp: Added.
+ Move Efl specific launch options here.
+
+ (WebKit::WebProcessProxy::platformConnect):
+ * UIProcess/gtk/WebProcessProxyGtk.cpp: Added.
+ Add stub.
+
+ (WebKit::WebProcessProxy::platformConnect):
+ * UIProcess/mac/WebProcessProxyMac.mm:
+ (WebKit::WebProcessProxy::platformConnect):
+ Move Mac specific launch option setting here, and switch from
+ using an environment variable to NSUserDefaults.
+
+ * UIProcess/qt/WebProcessProxyQt.cpp: Added.
+ (WebKit::WebProcessProxy::platformConnect):
+ Add stub.
+
+ * UIProcess/win/WebProcessProxyWin.cpp:
+ (WebKit::WebProcessProxy::platformConnect):
+ Add stub.
+
+2012-09-24 Laszlo Gombos <l.gombos@samsung.com>
+
+ [GTK][EFL] Remove cairo prefix from include statements
+ https://bugs.webkit.org/show_bug.cgi?id=97509
+
+ Reviewed by Gyuyoung Kim.
+
+ Make the build system consistent by always assuming that directory
+ that includes the cairo headers is included in the include path.
+
+ * UIProcess/cairo/BackingStoreCairo.cpp:
+ * WebProcess/Plugins/Netscape/x11/NetscapePluginX11.cpp:
+
+2012-09-24 Sheriff Bot <webkit.review.bot@gmail.com>
+
+ Unreviewed, rolling out r129388.
+ http://trac.webkit.org/changeset/129388
+ https://bugs.webkit.org/show_bug.cgi?id=97477
+
+ Caused an assertion in a WebKit2 unit test (Requested by
+ abarth on #webkit).
+
+ * win/WebKit2.def:
+
+2012-09-24 Simon Pena <spena@igalia.com>
+
+ [GTK] Add Select All method to WebKit2 GTK+ API
+ https://bugs.webkit.org/show_bug.cgi?id=97460
+
+ Reviewed by Martin Robinson.
+
+ Following the same approach used when added Cut, Copy and Paste,
+ the Select All method is added to the WebKit2 GTK+ API.
+
+ This introduces a new macro in the WebKitEditingCommands,
+ updates the documentation, and includes a new unit test.
+
+ * UIProcess/API/gtk/WebKitEditingCommands.h: Add a new macro for
+ the Select All command.
+ * UIProcess/API/gtk/docs/webkit2gtk-sections.txt: Include the Select All
+ command in the documentation.
+ * UIProcess/API/gtk/tests/TestWebViewEditor.cpp: Cover the new command
+ with a unit test.
+ (testWebViewEditorSelectAll):
+ (beforeAll):
+
+2012-09-24 Bo Liu <boliu@chromium.org>
+
+ Reland "Add in-place reload behavior to ImagesEnabled setting" with optimizations
+ https://bugs.webkit.org/show_bug.cgi?id=97055
+
+ Reviewed by Adam Barth.
+
+ Relanding 128780, 128676, 128645. Was reverted in 128914 due to
+ performance regression in Chromium.
+
+ New changes in addition to previously reverted patches:
+
+ Refactored CachedResource::requestResource, loadResource, and
+ revalidateResource. Moved CachedResource::load method to end of
+ requestResource so there is one place where load is called for all
+ resources.
+
+ Added a enum parameter for requestResource and
+ determineRevalidationPolicy so that FrameLoaderClient::allowImage call
+ do not need to be called multiple times.
+
+ Removed CachedImage::load call in requestImage so it is not called
+ twice.
+
+ Removed unnecessary Frame.h includes in CachedResource and
+ CachedImage.
+
+ Removed dead load() method declaration in CachedImage.
+
+ Updated text expectation for two image-permissions tests to reflect
+ the removed calls to allowImage.
+
+ * win/WebKit2.def:
+
+2012-09-24 Joone Hur <joone.hur@intel.com>, Gustavo Noronha Silva <gustavo.noronha@collabora.com>
+
+ [GTK] Implement GraphicsLayer using Clutter
+ https://bugs.webkit.org/show_bug.cgi?id=73767
+
+ Reviewed by Martin Robinson.
+
+ Fixed link errors by adding Clutter library and header to WebKit2 build.
+
+ * GNUmakefile.am:
+
+2012-09-24 Carlos Garcia Campos <cgarcia@igalia.com>
+
+ [GTK] WebKitWebView:is-loading is not updated when the is loaded is started by link clicked navigation action
+ https://bugs.webkit.org/show_bug.cgi?id=97458
+
+ Reviewed by Xan Lopez.
+
+ WebKitWebView:is-loading is set to TRUE when the load is started
+ by using the API. We want to make sure that both URI and
+ is-loading are updated before load-started is emitted, so we can
+ update both right before emitting load-started.
+
+ * UIProcess/API/gtk/WebKitWebView.cpp:
+ (webkitWebViewEmitLoadChanged): Update both uri and is-loading
+ properties before emitting load-changed signal with
+ WEBKIT_LOAD_STARTED.
+ (webkit_web_view_load_uri): Don't call
+ webkitWebViewSetIsLoading().
+ (webkit_web_view_load_html): Ditto.
+ (webkit_web_view_load_alternate_html): Ditto.
+ (webkit_web_view_load_plain_text): Ditto.
+ (webkit_web_view_load_request): Ditto.
+ (webkit_web_view_reload): Ditto.
+ (webkit_web_view_reload_bypass_cache): Ditto.
+ (webkit_web_view_go_back): Ditto.
+ (webkit_web_view_go_forward): Ditto.
+ (webkit_web_view_go_to_back_forward_list_item): Ditto.
+
+2012-09-24 Byungwoo Lee <bw80.lee@samsung.com>
+
+ [EFL][WK2] Change the install path for libewk2UnitTestInjectedBundleSample.so.
+ https://bugs.webkit.org/show_bug.cgi?id=97302
+
+ Reviewed by Gyuyoung Kim.
+
+ libewk2UnitTestInjectedBundleSample.so file is created under the
+ Source directory.
+ Change install directory for the library to under the build directory.
+
+ * PlatformEfl.cmake:
+ * UIProcess/API/efl/tests/UnitTestUtils/EWK2UnitTestEnvironment.cpp:
+ (EWK2UnitTest::EWK2UnitTestEnvironment::injectedBundleSample):
+
+2012-09-24 Vivek Galatage <vivekgalatage@gmail.com>
+
+ Web Inspector: implement testing harness for pure protocol tests.
+ https://bugs.webkit.org/show_bug.cgi?id=90675
+
+ Reviewed by Yury Semikhatsky.
+
+ Adding the export symbol definitions required on Apple Windows and WinCairo
+ ports to support Inspector Protocol testing harness.
+
+ * win/WebKit2.def:
+ * win/WebKit2CFLite.def:
+
2012-09-24 KwangYong Choi <ky0.choi@samsung.com>
[EFL][WK2] Invalid featuring of INPUT_TYPE_COLOR in test_ewk2_view.
diff --git a/Source/WebKit2/GNUmakefile.am b/Source/WebKit2/GNUmakefile.am
index ba0ac6955..52020862f 100644
--- a/Source/WebKit2/GNUmakefile.am
+++ b/Source/WebKit2/GNUmakefile.am
@@ -101,6 +101,7 @@ libwebkit2gtk_@WEBKITGTK_API_MAJOR_VERSION@_@WEBKITGTK_API_MINOR_VERSION@_la_CPP
$(webcore_cppflags) \
$(webcoregtk_cppflags) \
$(javascriptcore_cppflags) \
+ $(CLUTTER_CFLAGS) \
$(COVERAGE_CFLAGS) \
$(GEOCLUE_CFLAGS) \
$(GLIB_CFLAGS) \
@@ -162,6 +163,7 @@ libwebkit2gtk_@WEBKITGTK_API_MAJOR_VERSION@_@WEBKITGTK_API_MINOR_VERSION@_la_LIB
libjavascriptcoregtk-@WEBKITGTK_API_MAJOR_VERSION@.@WEBKITGTK_API_MINOR_VERSION@.la \
libWebCoreGtk.la \
$(CAIRO_LIBS) \
+ $(CLUTTER_LIBS) \
$(COVERAGE_LDFLAGS) \
$(FARSTREAM_LIBS) \
$(GAIL_LIBS) \
diff --git a/Source/WebKit2/GNUmakefile.list.am b/Source/WebKit2/GNUmakefile.list.am
index 6ecb2da8b..5015fb3e2 100644
--- a/Source/WebKit2/GNUmakefile.list.am
+++ b/Source/WebKit2/GNUmakefile.list.am
@@ -779,6 +779,7 @@ webkit2_sources += \
Source/WebKit2/UIProcess/gtk/WebPopupMenuProxyGtk.cpp \
Source/WebKit2/UIProcess/gtk/WebPopupMenuProxyGtk.h \
Source/WebKit2/UIProcess/gtk/WebPreferencesGtk.cpp \
+ Source/WebKit2/UIProcess/gtk/WebProcessProxyGtk.cpp \
Source/WebKit2/UIProcess/Launcher/gtk/ProcessLauncherGtk.cpp \
Source/WebKit2/UIProcess/Launcher/ProcessLauncher.cpp \
Source/WebKit2/UIProcess/Launcher/ProcessLauncher.h \
diff --git a/Source/WebKit2/PlatformEfl.cmake b/Source/WebKit2/PlatformEfl.cmake
index 8acb4c730..d3932b6dc 100644
--- a/Source/WebKit2/PlatformEfl.cmake
+++ b/Source/WebKit2/PlatformEfl.cmake
@@ -76,6 +76,7 @@ LIST(APPEND WebKit2_SOURCES
UIProcess/efl/WebPageProxyEfl.cpp
UIProcess/efl/WebPopupMenuProxyEfl.cpp
UIProcess/efl/WebPreferencesEfl.cpp
+ UIProcess/efl/WebProcessProxyEfl.cpp
UIProcess/soup/WebCookieManagerProxySoup.cpp
UIProcess/soup/WebSoupRequestManagerClient.cpp
@@ -265,6 +266,7 @@ SET(TEST_RESOURCES_DIR ${WEBKIT2_EFL_TEST_DIR}/resources)
SET(TEST_INJECTED_BUNDLE_DIR ${WEBKIT2_EFL_TEST_DIR}/InjectedBundle)
ADD_DEFINITIONS(-DTEST_RESOURCES_DIR=\"${TEST_RESOURCES_DIR}\"
+ -DTEST_LIB_DIR=\"${CMAKE_LIBRARY_OUTPUT_DIRECTORY}\"
-DTEST_THEME_DIR=\"${THEME_BINARY_DIR}\"
-DGTEST_LINKED_AS_SHARED_LIBRARY=1
-DLIBEXECDIR=\"${CMAKE_INSTALL_PREFIX}/${EXEC_INSTALL_DIR}\"
@@ -304,7 +306,6 @@ IF (ENABLE_API_TESTS)
ENDFOREACH ()
ADD_LIBRARY(ewk2UnitTestInjectedBundleSample SHARED ${TEST_INJECTED_BUNDLE_DIR}/injected_bundle_sample.cpp)
- SET_TARGET_PROPERTIES(ewk2UnitTestInjectedBundleSample PROPERTIES LIBRARY_OUTPUT_DIRECTORY "${TEST_RESOURCES_DIR}")
ENDIF ()
IF (ENABLE_INSPECTOR)
diff --git a/Source/WebKit2/Target.pri b/Source/WebKit2/Target.pri
index 81895f04d..15fa0b18a 100644
--- a/Source/WebKit2/Target.pri
+++ b/Source/WebKit2/Target.pri
@@ -623,6 +623,7 @@ SOURCES += \
UIProcess/qt/WebInspectorProxyQt.cpp \
UIProcess/qt/WebPageProxyQt.cpp \
UIProcess/qt/WebPreferencesQt.cpp \
+ UIProcess/qt/WebProcessProxyQt.cpp \
WebProcess/ApplicationCache/WebApplicationCacheManager.cpp \
WebProcess/Authentication/AuthenticationManager.cpp \
WebProcess/Battery/WebBatteryManager.cpp \
diff --git a/Source/WebKit2/UIProcess/API/efl/tests/UnitTestUtils/EWK2UnitTestEnvironment.cpp b/Source/WebKit2/UIProcess/API/efl/tests/UnitTestUtils/EWK2UnitTestEnvironment.cpp
index cd3c55d5f..0b7977f54 100644
--- a/Source/WebKit2/UIProcess/API/efl/tests/UnitTestUtils/EWK2UnitTestEnvironment.cpp
+++ b/Source/WebKit2/UIProcess/API/efl/tests/UnitTestUtils/EWK2UnitTestEnvironment.cpp
@@ -45,7 +45,7 @@ const char* EWK2UnitTestEnvironment::defaultTheme() const
const char* EWK2UnitTestEnvironment::injectedBundleSample() const
{
- return TEST_RESOURCES_DIR "/libewk2UnitTestInjectedBundleSample.so";
+ return TEST_LIB_DIR "/libewk2UnitTestInjectedBundleSample.so";
}
CString EWK2UnitTestEnvironment::urlForResource(const char* resource)
diff --git a/Source/WebKit2/UIProcess/API/gtk/WebKitContextMenuClient.cpp b/Source/WebKit2/UIProcess/API/gtk/WebKitContextMenuClient.cpp
index f9d713180..42f90b871 100644
--- a/Source/WebKit2/UIProcess/API/gtk/WebKitContextMenuClient.cpp
+++ b/Source/WebKit2/UIProcess/API/gtk/WebKitContextMenuClient.cpp
@@ -28,7 +28,7 @@ using namespace WebKit;
static void getContextMenuFromProposedMenu(WKPageRef, WKArrayRef proposedMenu, WKArrayRef*, WKHitTestResultRef hitTestResult, WKTypeRef userData, const void* clientInfo)
{
- webkitWebViewPopulateContextMenu(WEBKIT_WEB_VIEW(clientInfo), proposedMenu, hitTestResult);
+ webkitWebViewPopulateContextMenu(WEBKIT_WEB_VIEW(clientInfo), toImpl(proposedMenu), toImpl(hitTestResult));
}
void attachContextMenuClientToView(WebKitWebView* webView)
diff --git a/Source/WebKit2/UIProcess/API/gtk/WebKitEditingCommands.h b/Source/WebKit2/UIProcess/API/gtk/WebKitEditingCommands.h
index f85bf31bd..36c72a0d3 100644
--- a/Source/WebKit2/UIProcess/API/gtk/WebKitEditingCommands.h
+++ b/Source/WebKit2/UIProcess/API/gtk/WebKitEditingCommands.h
@@ -62,6 +62,15 @@ G_BEGIN_DECLS
*/
#define WEBKIT_EDITING_COMMAND_PASTE "Paste"
+/**
+ * WEBKIT_EDITING_COMMAND_SELECT_ALL:
+ *
+ * The select all command. Selects all the content of the current text field in
+ * a #WebKitWebView.
+ * It is always possible to select all text, no matter wheter the #WebKitWebView content
+ * is editable or not. You can still check it with webkit_web_view_can_execute_editing_command().
+ */
+#define WEBKIT_EDITING_COMMAND_SELECT_ALL "SelectAll"
G_END_DECLS
diff --git a/Source/WebKit2/UIProcess/API/gtk/WebKitResourceLoadClient.cpp b/Source/WebKit2/UIProcess/API/gtk/WebKitResourceLoadClient.cpp
index b38161156..4444a1ee7 100644
--- a/Source/WebKit2/UIProcess/API/gtk/WebKitResourceLoadClient.cpp
+++ b/Source/WebKit2/UIProcess/API/gtk/WebKitResourceLoadClient.cpp
@@ -38,7 +38,7 @@ using namespace WebKit;
static void didInitiateLoadForResource(WKPageRef, WKFrameRef wkFrame, uint64_t resourceIdentifier, WKURLRequestRef wkRequest, bool pageIsProvisionallyLoading, const void* clientInfo)
{
GRefPtr<WebKitURIRequest> request = adoptGRef(webkitURIRequestCreateForResourceRequest(toImpl(wkRequest)->resourceRequest()));
- webkitWebViewResourceLoadStarted(WEBKIT_WEB_VIEW(clientInfo), wkFrame, resourceIdentifier, request.get());
+ webkitWebViewResourceLoadStarted(WEBKIT_WEB_VIEW(clientInfo), toImpl(wkFrame), resourceIdentifier, request.get());
}
static void didSendRequestForResource(WKPageRef, WKFrameRef, uint64_t resourceIdentifier, WKURLRequestRef wkRequest, WKURLResponseRef wkRedirectResponse, const void* clientInfo)
diff --git a/Source/WebKit2/UIProcess/API/gtk/WebKitUIClient.cpp b/Source/WebKit2/UIProcess/API/gtk/WebKitUIClient.cpp
index 59d0b0d14..1925e6a21 100644
--- a/Source/WebKit2/UIProcess/API/gtk/WebKitUIClient.cpp
+++ b/Source/WebKit2/UIProcess/API/gtk/WebKitUIClient.cpp
@@ -34,7 +34,7 @@ using namespace WebKit;
static WKPageRef createNewPage(WKPageRef page, WKURLRequestRef, WKDictionaryRef wkWindowFeatures, WKEventModifiers, WKEventMouseButton, const void* clientInfo)
{
- return webkitWebViewCreateNewPage(WEBKIT_WEB_VIEW(clientInfo), wkWindowFeatures);
+ return static_cast<WKPageRef>(toAPI(webkitWebViewCreateNewPage(WEBKIT_WEB_VIEW(clientInfo), toImpl(wkWindowFeatures))));
}
static void showPage(WKPageRef page, const void* clientInfo)
@@ -59,8 +59,9 @@ static bool runJavaScriptConfirm(WKPageRef page, WKStringRef message, WKFrameRef
static WKStringRef runJavaScriptPrompt(WKPageRef page, WKStringRef message, WKStringRef defaultValue, WKFrameRef, const void* clientInfo)
{
- return webkitWebViewRunJavaScriptPrompt(WEBKIT_WEB_VIEW(clientInfo), toImpl(message)->string().utf8(),
- toImpl(defaultValue)->string().utf8());
+ CString result = webkitWebViewRunJavaScriptPrompt(WEBKIT_WEB_VIEW(clientInfo), toImpl(message)->string().utf8(),
+ toImpl(defaultValue)->string().utf8());
+ return WKStringCreateWithUTF8CString(result.data());
}
static bool toolbarsAreVisible(WKPageRef page, const void* clientInfo)
@@ -131,12 +132,12 @@ static void setWindowFrame(WKPageRef page, WKRect frame, const void* clientInfo)
static void mouseDidMoveOverElement(WKPageRef page, WKHitTestResultRef hitTestResult, WKEventModifiers modifiers, WKTypeRef userData, const void* clientInfo)
{
- webkitWebViewMouseTargetChanged(WEBKIT_WEB_VIEW(clientInfo), hitTestResult, wkEventModifiersToGdkModifiers(modifiers));
+ webkitWebViewMouseTargetChanged(WEBKIT_WEB_VIEW(clientInfo), toImpl(hitTestResult), wkEventModifiersToGdkModifiers(modifiers));
}
static void printFrame(WKPageRef page, WKFrameRef frame, const void*)
{
- webkitWebViewPrintFrame(WEBKIT_WEB_VIEW(toImpl(page)->viewWidget()), frame);
+ webkitWebViewPrintFrame(WEBKIT_WEB_VIEW(toImpl(page)->viewWidget()), toImpl(frame));
}
static void runOpenPanel(WKPageRef page, WKFrameRef frame, WKOpenPanelParametersRef parameters, WKOpenPanelResultListenerRef listener, const void *clientInfo)
diff --git a/Source/WebKit2/UIProcess/API/gtk/WebKitURIRequest.cpp b/Source/WebKit2/UIProcess/API/gtk/WebKitURIRequest.cpp
index b5c2b4e74..c882cb788 100644
--- a/Source/WebKit2/UIProcess/API/gtk/WebKitURIRequest.cpp
+++ b/Source/WebKit2/UIProcess/API/gtk/WebKitURIRequest.cpp
@@ -117,13 +117,6 @@ WebKitURIRequest* webkit_uri_request_new(const gchar* uri)
return WEBKIT_URI_REQUEST(g_object_new(WEBKIT_TYPE_URI_REQUEST, "uri", uri, NULL));
}
-WebKitURIRequest* webkitURIRequestCreateForResourceRequest(const WebCore::ResourceRequest& resourceRequest)
-{
- WebKitURIRequest* uriRequest = WEBKIT_URI_REQUEST(g_object_new(WEBKIT_TYPE_URI_REQUEST, NULL));
- uriRequest->priv->resourceRequest = resourceRequest;
- return uriRequest;
-}
-
/**
* webkit_uri_request_get_uri:
* @request: a #WebKitURIRequest
@@ -138,3 +131,14 @@ const gchar* webkit_uri_request_get_uri(WebKitURIRequest* request)
return request->priv->uri.data();
}
+WebKitURIRequest* webkitURIRequestCreateForResourceRequest(const WebCore::ResourceRequest& resourceRequest)
+{
+ WebKitURIRequest* uriRequest = WEBKIT_URI_REQUEST(g_object_new(WEBKIT_TYPE_URI_REQUEST, NULL));
+ uriRequest->priv->resourceRequest = resourceRequest;
+ return uriRequest;
+}
+
+const WebCore::ResourceRequest& webkitURIRequestGetResourceRequest(WebKitURIRequest* uriRequest)
+{
+ return uriRequest->priv->resourceRequest;
+}
diff --git a/Source/WebKit2/UIProcess/API/gtk/WebKitURIRequestPrivate.h b/Source/WebKit2/UIProcess/API/gtk/WebKitURIRequestPrivate.h
index db85242af..3af02a527 100644
--- a/Source/WebKit2/UIProcess/API/gtk/WebKitURIRequestPrivate.h
+++ b/Source/WebKit2/UIProcess/API/gtk/WebKitURIRequestPrivate.h
@@ -30,5 +30,6 @@
#include <WebCore/ResourceRequest.h>
WebKitURIRequest* webkitURIRequestCreateForResourceRequest(const WebCore::ResourceRequest&);
+const WebCore::ResourceRequest& webkitURIRequestGetResourceRequest(WebKitURIRequest*);
#endif // WebKitURIRequestPrivate_h
diff --git a/Source/WebKit2/UIProcess/API/gtk/WebKitWebView.cpp b/Source/WebKit2/UIProcess/API/gtk/WebKitWebView.cpp
index 45c3821b0..301be899c 100644
--- a/Source/WebKit2/UIProcess/API/gtk/WebKitWebView.cpp
+++ b/Source/WebKit2/UIProcess/API/gtk/WebKitWebView.cpp
@@ -23,6 +23,7 @@
#include "WebContextMenuItem.h"
#include "WebContextMenuItemData.h"
+#include "WebData.h"
#include "WebKitBackForwardListPrivate.h"
#include "WebKitContextMenuClient.h"
#include "WebKitContextMenuItemPrivate.h"
@@ -43,6 +44,7 @@
#include "WebKitScriptDialogPrivate.h"
#include "WebKitSettingsPrivate.h"
#include "WebKitUIClient.h"
+#include "WebKitURIRequestPrivate.h"
#include "WebKitURIResponsePrivate.h"
#include "WebKitWebContextPrivate.h"
#include "WebKitWebInspectorPrivate.h"
@@ -50,7 +52,6 @@
#include "WebKitWebViewBasePrivate.h"
#include "WebKitWebViewPrivate.h"
#include "WebKitWindowPropertiesPrivate.h"
-#include "WebPageProxy.h"
#include <JavaScriptCore/APICast.h>
#include <WebCore/DragIcon.h>
#include <WebCore/GOwnPtrGtk.h>
@@ -60,7 +61,6 @@
#include <wtf/gobject/GRefPtr.h>
#include <wtf/text/CString.h>
-using namespace WebKit;
using namespace WebCore;
enum {
@@ -145,6 +145,11 @@ static guint signals[LAST_SIGNAL] = { 0, };
G_DEFINE_TYPE(WebKitWebView, webkit_web_view, WEBKIT_TYPE_WEB_VIEW_BASE)
+static inline WebPageProxy* getPage(WebKitWebView* webView)
+{
+ return webkitWebViewBaseGetPage(reinterpret_cast<WebKitWebViewBase*>(webView));
+}
+
static gboolean webkitWebViewLoadFail(WebKitWebView* webView, WebKitLoadEvent, const char* failingURI, GError* error)
{
if (g_error_matches(error, WEBKIT_NETWORK_ERROR, WEBKIT_NETWORK_ERROR_CANCELLED)
@@ -238,28 +243,27 @@ static void allowModalDialogsChanged(WebKitSettings* settings, GParamSpec*, WebK
WebPageProxy* page = webkitWebViewBaseGetPage(WEBKIT_WEB_VIEW_BASE(webView));
if (!page)
return;
- page->setCanRunModal(webkit_settings_get_allow_modal_dialogs(settings));
+ getPage(webView)->setCanRunModal(webkit_settings_get_allow_modal_dialogs(settings));
}
static void zoomTextOnlyChanged(WebKitSettings* settings, GParamSpec*, WebKitWebView* webView)
{
- WKPageRef wkPage = toAPI(webkitWebViewBaseGetPage(WEBKIT_WEB_VIEW_BASE(webView)));
+ WebPageProxy* page = getPage(webView);
gboolean zoomTextOnly = webkit_settings_get_zoom_text_only(settings);
- gdouble pageZoomLevel = zoomTextOnly ? 1 : WKPageGetTextZoomFactor(wkPage);
- gdouble textZoomLevel = zoomTextOnly ? WKPageGetPageZoomFactor(wkPage) : 1;
- WKPageSetPageAndTextZoomFactors(wkPage, pageZoomLevel, textZoomLevel);
+ gdouble pageZoomLevel = zoomTextOnly ? 1 : page->textZoomFactor();
+ gdouble textZoomLevel = zoomTextOnly ? page->pageZoomFactor() : 1;
+ page->setPageAndTextZoomFactors(pageZoomLevel, textZoomLevel);
}
static void userAgentChanged(WebKitSettings* settings, GParamSpec*, WebKitWebView* webView)
{
- WKRetainPtr<WKStringRef> userAgent = adoptWK(WKStringCreateWithUTF8CString(webkit_settings_get_user_agent(settings)));
- WKPageSetCustomUserAgent(toAPI(webkitWebViewBaseGetPage(WEBKIT_WEB_VIEW_BASE(webView))), userAgent.get());
+ getPage(webView)->setCustomUserAgent(String::fromUTF8(webkit_settings_get_user_agent(settings)));
}
-static void webkitWebViewSetSettings(WebKitWebView* webView, WebKitSettings* settings, WKPageRef wkPage)
+static void webkitWebViewSetSettings(WebKitWebView* webView, WebKitSettings* settings)
{
webView->priv->settings = settings;
- webkitSettingsAttachSettingsToPage(webView->priv->settings.get(), wkPage);
+ webkitSettingsAttachSettingsToPage(webView->priv->settings.get(), toAPI(getPage(webView)));
g_signal_connect(settings, "notify::allow-modal-dialogs", G_CALLBACK(allowModalDialogsChanged), webView);
g_signal_connect(settings, "notify::zoom-text-only", G_CALLBACK(zoomTextOnlyChanged), webView);
g_signal_connect(settings, "notify::user-agent", G_CALLBACK(userAgentChanged), webView);
@@ -333,7 +337,7 @@ static void webkitWebViewConstructed(GObject* object)
WebKitWebViewPrivate* priv = webView->priv;
WebKitWebViewBase* webViewBase = WEBKIT_WEB_VIEW_BASE(webView);
- webkitWebViewBaseCreateWebPage(webViewBase, webkitWebContextGetWKContext(priv->context), 0);
+ webkitWebViewBaseCreateWebPage(webViewBase, toImpl(webkitWebContextGetWKContext(priv->context)), 0);
attachLoaderClientToView(webView);
attachUIClientToView(webView);
@@ -343,11 +347,10 @@ static void webkitWebViewConstructed(GObject* object)
attachContextMenuClientToView(webView);
attachFormClientToView(webView);
- WebPageProxy* page = webkitWebViewBaseGetPage(webViewBase);
- priv->backForwardList = adoptGRef(webkitBackForwardListCreate(WKPageGetBackForwardList(toAPI(page))));
+ priv->backForwardList = adoptGRef(webkitBackForwardListCreate(toAPI(getPage(webView)->backForwardList())));
GRefPtr<WebKitSettings> settings = adoptGRef(webkit_settings_new());
- webkitWebViewSetSettings(webView, settings.get(), toAPI(page));
+ webkitWebViewSetSettings(webView, settings.get());
}
static void webkitWebViewSetProperty(GObject* object, guint propId, const GValue* value, GParamSpec* paramSpec)
@@ -1155,7 +1158,9 @@ static void setCertificateToMainResource(WebKitWebView* webView)
static void webkitWebViewEmitLoadChanged(WebKitWebView* webView, WebKitLoadEvent loadEvent)
{
- if (loadEvent == WEBKIT_LOAD_FINISHED) {
+ if (loadEvent == WEBKIT_LOAD_STARTED)
+ webkitWebViewSetIsLoading(webView, true);
+ else if (loadEvent == WEBKIT_LOAD_FINISHED) {
webkitWebViewSetIsLoading(webView, false);
webView->priv->waitingForMainResource = false;
webkitWebViewDisconnectMainResourceResponseChangedSignalHandler(webView);
@@ -1233,12 +1238,7 @@ void webkitWebViewSetEstimatedLoadProgress(WebKitWebView* webView, double estima
void webkitWebViewUpdateURI(WebKitWebView* webView)
{
- WebPageProxy* page = webkitWebViewBaseGetPage(WEBKIT_WEB_VIEW_BASE(webView));
- WKRetainPtr<WKURLRef> wkURL(AdoptWK, WKPageCopyActiveURL(toAPI(page)));
- CString activeURI;
- if (wkURL)
- activeURI = toImpl(wkURL.get())->string().utf8();
-
+ CString activeURI = getPage(webView)->activeURL().utf8();
if (webView->priv->activeURI == activeURI)
return;
@@ -1246,16 +1246,17 @@ void webkitWebViewUpdateURI(WebKitWebView* webView)
g_object_notify(G_OBJECT(webView), "uri");
}
-WKPageRef webkitWebViewCreateNewPage(WebKitWebView* webView, WKDictionaryRef wkWindowFeatures)
+WebPageProxy* webkitWebViewCreateNewPage(WebKitWebView* webView, ImmutableDictionary* windowFeatures)
{
WebKitWebView* newWebView;
g_signal_emit(webView, signals[CREATE], 0, &newWebView);
if (!newWebView)
return 0;
- webkitWindowPropertiesUpdateFromWKWindowFeatures(newWebView->priv->windowProperties.get(), wkWindowFeatures);
+ webkitWindowPropertiesUpdateFromWKWindowFeatures(newWebView->priv->windowProperties.get(), toAPI(windowFeatures));
- return static_cast<WKPageRef>(WKRetain(toAPI(webkitWebViewBaseGetPage(WEBKIT_WEB_VIEW_BASE(newWebView)))));
+ RefPtr<WebPageProxy> newPage = getPage(newWebView);
+ return newPage.release().leakRef();
}
void webkitWebViewReadyToShowPage(WebKitWebView* webView)
@@ -1293,12 +1294,12 @@ bool webkitWebViewRunJavaScriptConfirm(WebKitWebView* webView, const CString& me
return dialog.confirmed;
}
-WKStringRef webkitWebViewRunJavaScriptPrompt(WebKitWebView* webView, const CString& message, const CString& defaultText)
+CString webkitWebViewRunJavaScriptPrompt(WebKitWebView* webView, const CString& message, const CString& defaultText)
{
WebKitScriptDialog dialog(WEBKIT_SCRIPT_DIALOG_PROMPT, message, defaultText);
gboolean returnValue;
g_signal_emit(webView, signals[SCRIPT_DIALOG], 0, &dialog, &returnValue);
- return dialog.text.isNull() ? 0 : WKStringCreateWithUTF8CString(dialog.text.data());
+ return dialog.text;
}
void webkitWebViewMakePolicyDecision(WebKitWebView* webView, WebKitPolicyDecisionType type, WebKitPolicyDecision* decision)
@@ -1313,22 +1314,22 @@ void webkitWebViewMakePermissionRequest(WebKitWebView* webView, WebKitPermission
g_signal_emit(webView, signals[PERMISSION_REQUEST], 0, request, &returnValue);
}
-void webkitWebViewMouseTargetChanged(WebKitWebView* webView, WKHitTestResultRef wkHitTestResult, unsigned modifiers)
+void webkitWebViewMouseTargetChanged(WebKitWebView* webView, WebHitTestResult* hitTestResult, unsigned modifiers)
{
- webkitWebViewBaseSetTooltipArea(WEBKIT_WEB_VIEW_BASE(webView), toImpl(wkHitTestResult)->elementBoundingBox());
+ webkitWebViewBaseSetTooltipArea(WEBKIT_WEB_VIEW_BASE(webView), hitTestResult->elementBoundingBox());
WebKitWebViewPrivate* priv = webView->priv;
if (priv->mouseTargetHitTestResult
&& priv->mouseTargetModifiers == modifiers
- && webkitHitTestResultCompare(priv->mouseTargetHitTestResult.get(), wkHitTestResult))
+ && webkitHitTestResultCompare(priv->mouseTargetHitTestResult.get(), toAPI(hitTestResult)))
return;
priv->mouseTargetModifiers = modifiers;
- priv->mouseTargetHitTestResult = adoptGRef(webkitHitTestResultCreate(wkHitTestResult));
+ priv->mouseTargetHitTestResult = adoptGRef(webkitHitTestResultCreate(toAPI(hitTestResult)));
g_signal_emit(webView, signals[MOUSE_TARGET_CHANGED], 0, priv->mouseTargetHitTestResult.get(), modifiers);
}
-void webkitWebViewPrintFrame(WebKitWebView* webView, WKFrameRef wkFrame)
+void webkitWebViewPrintFrame(WebKitWebView* webView, WebFrameProxy* frame)
{
GRefPtr<WebKitPrintOperation> printOperation = adoptGRef(webkit_print_operation_new(webView));
gboolean returnValue;
@@ -1336,7 +1337,7 @@ void webkitWebViewPrintFrame(WebKitWebView* webView, WKFrameRef wkFrame)
if (returnValue)
return;
- WebKitPrintOperationResponse response = webkitPrintOperationRunDialogForFrame(printOperation.get(), 0, toImpl(wkFrame));
+ WebKitPrintOperationResponse response = webkitPrintOperationRunDialogForFrame(printOperation.get(), 0, frame);
if (response == WEBKIT_PRINT_OPERATION_RESPONSE_CANCEL)
return;
g_signal_connect(printOperation.leakRef(), "finished", G_CALLBACK(g_object_unref), 0);
@@ -1360,11 +1361,11 @@ static void waitForMainResourceResponseIfWaitingForResource(WebKitWebView* webVi
g_signal_connect(priv->mainResource.get(), "notify::response", G_CALLBACK(mainResourceResponseChangedCallback), webView);
}
-void webkitWebViewResourceLoadStarted(WebKitWebView* webView, WKFrameRef wkFrame, uint64_t resourceIdentifier, WebKitURIRequest* request)
+void webkitWebViewResourceLoadStarted(WebKitWebView* webView, WebFrameProxy* frame, uint64_t resourceIdentifier, WebKitURIRequest* request)
{
WebKitWebViewPrivate* priv = webView->priv;
- bool isMainResource = WKFrameIsMainFrame(wkFrame) && !priv->mainResource;
- WebKitWebResource* resource = webkitWebResourceCreate(wkFrame, request, isMainResource);
+ bool isMainResource = frame->isMainFrame() && !priv->mainResource;
+ WebKitWebResource* resource = webkitWebResourceCreate(toAPI(frame), request, isMainResource);
if (isMainResource) {
priv->mainResource = resource;
waitForMainResourceResponseIfWaitingForResource(webView);
@@ -1468,17 +1469,17 @@ static void contextMenuDismissed(GtkMenuShell*, WebKitWebView* webView)
g_signal_emit(webView, signals[CONTEXT_MENU_DISMISSED], 0, NULL);
}
-void webkitWebViewPopulateContextMenu(WebKitWebView* webView, WKArrayRef wkProposedMenu, WKHitTestResultRef wkHitTestResult)
+void webkitWebViewPopulateContextMenu(WebKitWebView* webView, ImmutableArray* proposedMenu, WebHitTestResult* webHitTestResult)
{
WebKitWebViewBase* webViewBase = WEBKIT_WEB_VIEW_BASE(webView);
WebContextMenuProxyGtk* contextMenuProxy = webkitWebViewBaseGetActiveContextMenuProxy(webViewBase);
ASSERT(contextMenuProxy);
- GRefPtr<WebKitContextMenu> contextMenu = adoptGRef(webkitContextMenuCreate(wkProposedMenu));
- if (WKHitTestResultIsContentEditable(wkHitTestResult))
+ GRefPtr<WebKitContextMenu> contextMenu = adoptGRef(webkitContextMenuCreate(toAPI(proposedMenu)));
+ if (webHitTestResult->isContentEditable())
webkitWebViewCreateAndAppendInputMethodsMenuItem(webView, contextMenu.get());
- GRefPtr<WebKitHitTestResult> hitTestResult = adoptGRef(webkitHitTestResultCreate(wkHitTestResult));
+ GRefPtr<WebKitHitTestResult> hitTestResult = adoptGRef(webkitHitTestResultCreate(toAPI(webHitTestResult)));
GOwnPtr<GdkEvent> contextMenuEvent(webkitWebViewBaseTakeContextMenuEvent(webViewBase));
gboolean returnValue;
@@ -1558,10 +1559,7 @@ void webkit_web_view_load_uri(WebKitWebView* webView, const gchar* uri)
g_return_if_fail(WEBKIT_IS_WEB_VIEW(webView));
g_return_if_fail(uri);
- WKRetainPtr<WKURLRef> url(AdoptWK, WKURLCreateWithUTF8CString(uri));
- WebPageProxy* page = webkitWebViewBaseGetPage(WEBKIT_WEB_VIEW_BASE(webView));
- WKPageLoadURL(toAPI(page), url.get());
- webkitWebViewSetIsLoading(webView, true);
+ getPage(webView)->loadURL(String::fromUTF8(uri));
}
/**
@@ -1585,11 +1583,7 @@ void webkit_web_view_load_html(WebKitWebView* webView, const gchar* content, con
g_return_if_fail(WEBKIT_IS_WEB_VIEW(webView));
g_return_if_fail(content);
- WebPageProxy* page = webkitWebViewBaseGetPage(WEBKIT_WEB_VIEW_BASE(webView));
- WKRetainPtr<WKStringRef> contentRef(AdoptWK, WKStringCreateWithUTF8CString(content));
- WKRetainPtr<WKURLRef> baseURIRef = baseURI ? adoptWK(WKURLCreateWithUTF8CString(baseURI)) : 0;
- WKPageLoadHTMLString(toAPI(page), contentRef.get(), baseURIRef.get());
- webkitWebViewSetIsLoading(webView, true);
+ getPage(webView)->loadHTMLString(String::fromUTF8(content), String::fromUTF8(baseURI));
}
/**
@@ -1611,12 +1605,7 @@ void webkit_web_view_load_alternate_html(WebKitWebView* webView, const gchar* co
g_return_if_fail(content);
g_return_if_fail(contentURI);
- WKRetainPtr<WKStringRef> htmlString(AdoptWK, WKStringCreateWithUTF8CString(content));
- WKRetainPtr<WKURLRef> contentURL(AdoptWK, WKURLCreateWithUTF8CString(contentURI));
- WKRetainPtr<WKURLRef> baseURL = baseURI ? adoptWK(WKURLCreateWithUTF8CString(baseURI)) : 0;
- WebPageProxy* page = webkitWebViewBaseGetPage(WEBKIT_WEB_VIEW_BASE(webView));
- WKPageLoadAlternateHTMLString(toAPI(page), htmlString.get(), baseURL.get(), contentURL.get());
- webkitWebViewSetIsLoading(webView, true);
+ getPage(webView)->loadAlternateHTMLString(String::fromUTF8(content), String::fromUTF8(baseURI), String::fromUTF8(contentURI));
}
/**
@@ -1633,10 +1622,7 @@ void webkit_web_view_load_plain_text(WebKitWebView* webView, const gchar* plainT
g_return_if_fail(WEBKIT_IS_WEB_VIEW(webView));
g_return_if_fail(plainText);
- WebPageProxy* page = webkitWebViewBaseGetPage(WEBKIT_WEB_VIEW_BASE(webView));
- WKRetainPtr<WKStringRef> plainTextRef(AdoptWK, WKStringCreateWithUTF8CString(plainText));
- WKPageLoadPlainTextString(toAPI(page), plainTextRef.get());
- webkitWebViewSetIsLoading(webView, true);
+ getPage(webView)->loadPlainTextString(String::fromUTF8(plainText));
}
/**
@@ -1653,11 +1639,7 @@ void webkit_web_view_load_request(WebKitWebView* webView, WebKitURIRequest* requ
g_return_if_fail(WEBKIT_IS_WEB_VIEW(webView));
g_return_if_fail(WEBKIT_IS_URI_REQUEST(request));
- WKRetainPtr<WKURLRef> wkURL(AdoptWK, WKURLCreateWithUTF8CString(webkit_uri_request_get_uri(request)));
- WKRetainPtr<WKURLRequestRef> wkRequest(AdoptWK, WKURLRequestCreateWithWKURL(wkURL.get()));
- WebPageProxy* page = webkitWebViewBaseGetPage(WEBKIT_WEB_VIEW_BASE(webView));
- WKPageLoadURLRequest(toAPI(page), wkRequest.get());
- webkitWebViewSetIsLoading(webView, true);
+ getPage(webView)->loadURLRequest(WebURLRequest::create(webkitURIRequestGetResourceRequest(request)).leakRef());
}
/**
@@ -1688,8 +1670,7 @@ void webkit_web_view_reload(WebKitWebView* webView)
{
g_return_if_fail(WEBKIT_IS_WEB_VIEW(webView));
- WKPageReload(toAPI(webkitWebViewBaseGetPage(WEBKIT_WEB_VIEW_BASE(webView))));
- webkitWebViewSetIsLoading(webView, true);
+ getPage(webView)->reload(false);
}
/**
@@ -1703,8 +1684,7 @@ void webkit_web_view_reload_bypass_cache(WebKitWebView* webView)
{
g_return_if_fail(WEBKIT_IS_WEB_VIEW(webView));
- WKPageReloadFromOrigin(toAPI(webkitWebViewBaseGetPage(WEBKIT_WEB_VIEW_BASE(webView))));
- webkitWebViewSetIsLoading(webView, true);
+ getPage(webView)->reload(true);
}
/**
@@ -1721,7 +1701,7 @@ void webkit_web_view_stop_loading(WebKitWebView* webView)
{
g_return_if_fail(WEBKIT_IS_WEB_VIEW(webView));
- WKPageStopLoading(toAPI(webkitWebViewBaseGetPage(WEBKIT_WEB_VIEW_BASE(webView))));
+ getPage(webView)->stopLoading();
}
/**
@@ -1756,8 +1736,7 @@ void webkit_web_view_go_back(WebKitWebView* webView)
{
g_return_if_fail(WEBKIT_IS_WEB_VIEW(webView));
- WKPageGoBack(toAPI(webkitWebViewBaseGetPage(WEBKIT_WEB_VIEW_BASE(webView))));
- webkitWebViewSetIsLoading(webView, true);
+ getPage(webView)->goBack();
}
/**
@@ -1772,7 +1751,7 @@ gboolean webkit_web_view_can_go_back(WebKitWebView* webView)
{
g_return_val_if_fail(WEBKIT_IS_WEB_VIEW(webView), FALSE);
- return WKPageCanGoBack(toAPI(webkitWebViewBaseGetPage(WEBKIT_WEB_VIEW_BASE(webView))));
+ return getPage(webView)->canGoBack();
}
/**
@@ -1787,8 +1766,7 @@ void webkit_web_view_go_forward(WebKitWebView* webView)
{
g_return_if_fail(WEBKIT_IS_WEB_VIEW(webView));
- WKPageGoForward(toAPI(webkitWebViewBaseGetPage(WEBKIT_WEB_VIEW_BASE(webView))));
- webkitWebViewSetIsLoading(webView, true);
+ getPage(webView)->goForward();
}
/**
@@ -1803,7 +1781,7 @@ gboolean webkit_web_view_can_go_forward(WebKitWebView* webView)
{
g_return_val_if_fail(WEBKIT_IS_WEB_VIEW(webView), FALSE);
- return WKPageCanGoForward(toAPI(webkitWebViewBaseGetPage(WEBKIT_WEB_VIEW_BASE(webView))));
+ return getPage(webView)->canGoForward();
}
/**
@@ -1884,12 +1862,11 @@ const gchar* webkit_web_view_get_custom_charset(WebKitWebView* webView)
{
g_return_val_if_fail(WEBKIT_IS_WEB_VIEW(webView), 0);
- WebPageProxy* page = webkitWebViewBaseGetPage(WEBKIT_WEB_VIEW_BASE(webView));
- WKRetainPtr<WKStringRef> wkCustomEncoding(AdoptWK, WKPageCopyCustomTextEncodingName(toAPI(page)));
- if (WKStringIsEmpty(wkCustomEncoding.get()))
+ String customTextEncoding = getPage(webView)->customTextEncodingName();
+ if (customTextEncoding.isEmpty())
return 0;
- webView->priv->customTextEncoding = toImpl(wkCustomEncoding.get())->string().utf8();
+ webView->priv->customTextEncoding = customTextEncoding.utf8();
return webView->priv->customTextEncoding.data();
}
@@ -1908,9 +1885,7 @@ void webkit_web_view_set_custom_charset(WebKitWebView* webView, const gchar* cha
{
g_return_if_fail(WEBKIT_IS_WEB_VIEW(webView));
- WebPageProxy* page = webkitWebViewBaseGetPage(WEBKIT_WEB_VIEW_BASE(webView));
- WKRetainPtr<WKStringRef> wkEncodingName = charset ? adoptWK(WKStringCreateWithUTF8CString(charset)) : 0;
- WKPageSetCustomTextEncodingName(toAPI(page), wkEncodingName.get());
+ getPage(webView)->setCustomTextEncodingName(String::fromUTF8(charset));
}
/**
@@ -1960,9 +1935,7 @@ void webkit_web_view_go_to_back_forward_list_item(WebKitWebView* webView, WebKit
g_return_if_fail(WEBKIT_IS_WEB_VIEW(webView));
g_return_if_fail(WEBKIT_IS_BACK_FORWARD_LIST_ITEM(listItem));
- WKPageGoToBackForwardListItem(toAPI(webkitWebViewBaseGetPage(WEBKIT_WEB_VIEW_BASE(webView))),
- webkitBackForwardListItemGetWKItem(listItem));
- webkitWebViewSetIsLoading(webView, true);
+ getPage(webView)->goToBackForwardItem(toImpl(webkitBackForwardListItemGetWKItem(listItem)));
}
/**
@@ -1985,7 +1958,7 @@ void webkit_web_view_set_settings(WebKitWebView* webView, WebKitSettings* settin
return;
webkitWebViewDisconnectSettingsSignalHandlers(webView);
- webkitWebViewSetSettings(webView, settings, toAPI(webkitWebViewBaseGetPage(WEBKIT_WEB_VIEW_BASE(webView))));
+ webkitWebViewSetSettings(webView, settings);
}
/**
@@ -2046,11 +2019,11 @@ void webkit_web_view_set_zoom_level(WebKitWebView* webView, gdouble zoomLevel)
if (webkit_web_view_get_zoom_level(webView) == zoomLevel)
return;
- WKPageRef wkPage = toAPI(webkitWebViewBaseGetPage(WEBKIT_WEB_VIEW_BASE(webView)));
+ WebPageProxy* page = getPage(webView);
if (webkit_settings_get_zoom_text_only(webView->priv->settings.get()))
- WKPageSetTextZoomFactor(wkPage, zoomLevel);
+ page->setTextZoomFactor(zoomLevel);
else
- WKPageSetPageZoomFactor(wkPage, zoomLevel);
+ page->setPageZoomFactor(zoomLevel);
g_object_notify(G_OBJECT(webView), "zoom-level");
}
@@ -2067,9 +2040,9 @@ gdouble webkit_web_view_get_zoom_level(WebKitWebView* webView)
{
g_return_val_if_fail(WEBKIT_IS_WEB_VIEW(webView), 1);
- WKPageRef wkPage = toAPI(webkitWebViewBaseGetPage(WEBKIT_WEB_VIEW_BASE(webView)));
+ WebPageProxy* page = getPage(webView);
gboolean zoomTextOnly = webkit_settings_get_zoom_text_only(webView->priv->settings.get());
- return zoomTextOnly ? WKPageGetTextZoomFactor(wkPage) : WKPageGetPageZoomFactor(wkPage);
+ return zoomTextOnly ? page->textZoomFactor() : page->pageZoomFactor();
}
struct ValidateEditingCommandAsyncData {
@@ -2114,9 +2087,7 @@ void webkit_web_view_can_execute_editing_command(WebKitWebView* webView, const c
data->cancellable = cancellable;
g_simple_async_result_set_op_res_gpointer(result, data, reinterpret_cast<GDestroyNotify>(destroyValidateEditingCommandAsyncData));
- WebPageProxy* page = webkitWebViewBaseGetPage(WEBKIT_WEB_VIEW_BASE(webView));
- WKRetainPtr<WKStringRef> wkCommand(AdoptWK, WKStringCreateWithUTF8CString(command));
- WKPageValidateCommand(toAPI(page), wkCommand.get(), result, didValidateCommand);
+ getPage(webView)->validateCommand(String::fromUTF8(command), ValidateCommandCallback::create(result, didValidateCommand));
}
/**
@@ -2158,9 +2129,7 @@ void webkit_web_view_execute_editing_command(WebKitWebView* webView, const char*
g_return_if_fail(WEBKIT_IS_WEB_VIEW(webView));
g_return_if_fail(command);
- WebPageProxy* page = webkitWebViewBaseGetPage(WEBKIT_WEB_VIEW_BASE(webView));
- WKRetainPtr<WKStringRef> wkCommand(AdoptWK, WKStringCreateWithUTF8CString(command));
- WKPageExecuteCommand(toAPI(page), wkCommand.get());
+ getPage(webView)->executeEditCommand(String::fromUTF8(command));
}
/**
@@ -2249,14 +2218,14 @@ void webkit_web_view_run_javascript(WebKitWebView* webView, const gchar* script,
g_return_if_fail(WEBKIT_IS_WEB_VIEW(webView));
g_return_if_fail(script);
- WKPageRef wkPage = toAPI(webkitWebViewBaseGetPage(WEBKIT_WEB_VIEW_BASE(webView)));
- WKRetainPtr<WKStringRef> wkScript = adoptWK(WKStringCreateWithUTF8CString(script));
GSimpleAsyncResult* result = g_simple_async_result_new(G_OBJECT(webView), callback, userData,
reinterpret_cast<gpointer>(webkit_web_view_run_javascript));
RunJavaScriptAsyncData* data = createRunJavaScriptAsyncData();
data->cancellable = cancellable;
g_simple_async_result_set_op_res_gpointer(result, data, reinterpret_cast<GDestroyNotify>(destroyRunJavaScriptAsyncData));
- WKPageRunJavaScriptInMainFrame(wkPage, wkScript.get(), result, webkitWebViewRunJavaScriptCallback);
+
+ getPage(webView)->runJavaScriptInMainFrame(String::fromUTF8(script),
+ ScriptValueCallback::create(result, webkitWebViewRunJavaScriptCallback));
}
/**
@@ -2389,10 +2358,8 @@ WebKitWebInspector* webkit_web_view_get_inspector(WebKitWebView* webView)
{
g_return_val_if_fail(WEBKIT_IS_WEB_VIEW(webView), 0);
- if (!webView->priv->inspector) {
- WebPageProxy* page = webkitWebViewBaseGetPage(WEBKIT_WEB_VIEW_BASE(webView));
- webView->priv->inspector = adoptGRef(webkitWebInspectorCreate(toAPI(page->inspector())));
- }
+ if (!webView->priv->inspector)
+ webView->priv->inspector = adoptGRef(webkitWebInspectorCreate(toAPI(getPage(webView)->inspector())));
return webView->priv->inspector.get();
}
@@ -2411,12 +2378,11 @@ gboolean webkit_web_view_can_show_mime_type(WebKitWebView* webView, const char*
g_return_val_if_fail(WEBKIT_IS_WEB_VIEW(webView), FALSE);
g_return_val_if_fail(mimeType, FALSE);
- WebPageProxy* page = webkitWebViewBaseGetPage(WEBKIT_WEB_VIEW_BASE(webView));
- return page->canShowMIMEType(String::fromUTF8(mimeType));
+ return getPage(webView)->canShowMIMEType(String::fromUTF8(mimeType));
}
struct ViewSaveAsyncData {
- WKRetainPtr<WKDataRef> wkData;
+ RefPtr<WebData> webData;
GRefPtr<GFile> file;
GRefPtr<GCancellable> cancellable;
};
@@ -2445,13 +2411,14 @@ static void getContentsAsMHTMLDataCallback(WKDataRef wkData, WKErrorRef, void* c
else {
// We need to retain the data until the asyncronous process
// initiated by the user has finished completely.
- data->wkData = wkData;
+ data->webData = toImpl(wkData);
// If we are saving to a file we need to write the data on disk before finishing.
if (g_simple_async_result_get_source_tag(result.get()) == webkit_web_view_save_to_file) {
ASSERT(G_IS_FILE(data->file.get()));
- g_file_replace_contents_async(data->file.get(), reinterpret_cast<const gchar*>(WKDataGetBytes(data->wkData.get())), WKDataGetSize(data->wkData.get()), 0, FALSE, G_FILE_CREATE_REPLACE_DESTINATION,
- data->cancellable.get(), fileReplaceContentsCallback, g_object_ref(result.get()));
+ g_file_replace_contents_async(data->file.get(), reinterpret_cast<const gchar*>(data->webData->bytes()), data->webData->size(),
+ 0, FALSE, G_FILE_CREATE_REPLACE_DESTINATION, data->cancellable.get(), fileReplaceContentsCallback,
+ g_object_ref(result.get()));
return;
}
}
@@ -2488,8 +2455,7 @@ void webkit_web_view_save(WebKitWebView* webView, WebKitSaveMode saveMode, GCanc
data->cancellable = cancellable;
g_simple_async_result_set_op_res_gpointer(result, data, reinterpret_cast<GDestroyNotify>(destroyViewSaveAsyncData));
- WKPageRef wkPage = toAPI(webkitWebViewBaseGetPage(WEBKIT_WEB_VIEW_BASE(webView)));
- WKPageGetContentsAsMHTMLData(wkPage, false, result, getContentsAsMHTMLDataCallback);
+ getPage(webView)->getContentsAsMHTMLData(DataCallback::create(result, getContentsAsMHTMLDataCallback), false);
}
/**
@@ -2516,9 +2482,9 @@ GInputStream* webkit_web_view_save_finish(WebKitWebView* webView, GAsyncResult*
GInputStream* dataStream = g_memory_input_stream_new();
ViewSaveAsyncData* data = static_cast<ViewSaveAsyncData*>(g_simple_async_result_get_op_res_gpointer(simple));
- gsize length = WKDataGetSize(data->wkData.get());
+ gsize length = data->webData->size();
if (length)
- g_memory_input_stream_add_data(G_MEMORY_INPUT_STREAM(dataStream), g_memdup(WKDataGetBytes(data->wkData.get()), length), length, g_free);
+ g_memory_input_stream_add_data(G_MEMORY_INPUT_STREAM(dataStream), g_memdup(data->webData->bytes(), length), length, g_free);
return dataStream;
}
@@ -2555,8 +2521,7 @@ void webkit_web_view_save_to_file(WebKitWebView* webView, GFile* file, WebKitSav
data->cancellable = cancellable;
g_simple_async_result_set_op_res_gpointer(result, data, reinterpret_cast<GDestroyNotify>(destroyViewSaveAsyncData));
- WKPageRef wkPage = toAPI(webkitWebViewBaseGetPage(WEBKIT_WEB_VIEW_BASE(webView)));
- WKPageGetContentsAsMHTMLData(wkPage, false, result, getContentsAsMHTMLDataCallback);
+ getPage(webView)->getContentsAsMHTMLData(DataCallback::create(result, getContentsAsMHTMLDataCallback), false);
}
/**
diff --git a/Source/WebKit2/UIProcess/API/gtk/WebKitWebViewBase.cpp b/Source/WebKit2/UIProcess/API/gtk/WebKitWebViewBase.cpp
index 5338e2bd3..b42b2ee8f 100644
--- a/Source/WebKit2/UIProcess/API/gtk/WebKitWebViewBase.cpp
+++ b/Source/WebKit2/UIProcess/API/gtk/WebKitWebViewBase.cpp
@@ -775,7 +775,7 @@ static void webkit_web_view_base_class_init(WebKitWebViewBaseClass* webkitWebVie
WebKitWebViewBase* webkitWebViewBaseCreate(WebContext* context, WebPageGroup* pageGroup)
{
WebKitWebViewBase* webkitWebViewBase = WEBKIT_WEB_VIEW_BASE(g_object_new(WEBKIT_TYPE_WEB_VIEW_BASE, NULL));
- webkitWebViewBaseCreateWebPage(webkitWebViewBase, toAPI(context), toAPI(pageGroup));
+ webkitWebViewBaseCreateWebPage(webkitWebViewBase, context, pageGroup);
return webkitWebViewBase;
}
@@ -789,11 +789,11 @@ WebPageProxy* webkitWebViewBaseGetPage(WebKitWebViewBase* webkitWebViewBase)
return webkitWebViewBase->priv->pageProxy.get();
}
-void webkitWebViewBaseCreateWebPage(WebKitWebViewBase* webkitWebViewBase, WKContextRef context, WKPageGroupRef pageGroup)
+void webkitWebViewBaseCreateWebPage(WebKitWebViewBase* webkitWebViewBase, WebContext* context, WebPageGroup* pageGroup)
{
WebKitWebViewBasePrivate* priv = webkitWebViewBase->priv;
- priv->pageProxy = toImpl(context)->createWebPage(priv->pageClient.get(), toImpl(pageGroup));
+ priv->pageProxy = context->createWebPage(priv->pageClient.get(), pageGroup);
priv->pageProxy->initializeWebPage();
#if ENABLE(FULLSCREEN_API)
diff --git a/Source/WebKit2/UIProcess/API/gtk/WebKitWebViewBasePrivate.h b/Source/WebKit2/UIProcess/API/gtk/WebKitWebViewBasePrivate.h
index 8d0f865ff..4bf2886e5 100644
--- a/Source/WebKit2/UIProcess/API/gtk/WebKitWebViewBasePrivate.h
+++ b/Source/WebKit2/UIProcess/API/gtk/WebKitWebViewBasePrivate.h
@@ -38,7 +38,7 @@ using namespace WebKit;
WebKitWebViewBase* webkitWebViewBaseCreate(WebContext*, WebPageGroup*);
GtkIMContext* webkitWebViewBaseGetIMContext(WebKitWebViewBase*);
WebPageProxy* webkitWebViewBaseGetPage(WebKitWebViewBase*);
-void webkitWebViewBaseCreateWebPage(WebKitWebViewBase*, WKContextRef, WKPageGroupRef);
+void webkitWebViewBaseCreateWebPage(WebKitWebViewBase*, WebContext*, WebPageGroup*);
void webkitWebViewBaseSetTooltipText(WebKitWebViewBase*, const char*);
void webkitWebViewBaseSetTooltipArea(WebKitWebViewBase*, const WebCore::IntRect&);
void webkitWebViewBaseForwardNextKeyEvent(WebKitWebViewBase*);
diff --git a/Source/WebKit2/UIProcess/API/gtk/WebKitWebViewPrivate.h b/Source/WebKit2/UIProcess/API/gtk/WebKitWebViewPrivate.h
index 5ad2853bb..6aa965d1c 100644
--- a/Source/WebKit2/UIProcess/API/gtk/WebKitWebViewPrivate.h
+++ b/Source/WebKit2/UIProcess/API/gtk/WebKitWebViewPrivate.h
@@ -28,33 +28,34 @@
#define WebKitWebViewPrivate_h
#include "WebKitWebView.h"
-#include <WebKit2/WebKit2_C.h>
#include <wtf/text/CString.h>
+using namespace WebKit;
+
void webkitWebViewLoadChanged(WebKitWebView*, WebKitLoadEvent);
void webkitWebViewLoadFailed(WebKitWebView*, WebKitLoadEvent, const char* failingURI, GError*);
void webkitWebViewSetEstimatedLoadProgress(WebKitWebView*, double estimatedLoadProgress);
void webkitWebViewSetTitle(WebKitWebView*, const CString&);
void webkitWebViewUpdateURI(WebKitWebView*);
-WKPageRef webkitWebViewCreateNewPage(WebKitWebView*, WKDictionaryRef wkWindowFeatures);
+WebPageProxy* webkitWebViewCreateNewPage(WebKitWebView*, ImmutableDictionary* windowFeatures);
void webkitWebViewReadyToShowPage(WebKitWebView*);
void webkitWebViewRunAsModal(WebKitWebView*);
void webkitWebViewClosePage(WebKitWebView*);
void webkitWebViewRunJavaScriptAlert(WebKitWebView*, const CString& message);
bool webkitWebViewRunJavaScriptConfirm(WebKitWebView*, const CString& message);
-WKStringRef webkitWebViewRunJavaScriptPrompt(WebKitWebView*, const CString& message, const CString& defaultText);
+CString webkitWebViewRunJavaScriptPrompt(WebKitWebView*, const CString& message, const CString& defaultText);
void webkitWebViewMakePermissionRequest(WebKitWebView*, WebKitPermissionRequest*);
void webkitWebViewMakePolicyDecision(WebKitWebView*, WebKitPolicyDecisionType, WebKitPolicyDecision*);
-void webkitWebViewMouseTargetChanged(WebKitWebView*, WKHitTestResultRef, unsigned modifiers);
-void webkitWebViewPrintFrame(WebKitWebView*, WKFrameRef);
-void webkitWebViewResourceLoadStarted(WebKitWebView*, WKFrameRef, uint64_t resourceIdentifier, WebKitURIRequest*);
+void webkitWebViewMouseTargetChanged(WebKitWebView*, WebHitTestResult*, unsigned modifiers);
+void webkitWebViewPrintFrame(WebKitWebView*, WebFrameProxy*);
+void webkitWebViewResourceLoadStarted(WebKitWebView*, WebFrameProxy*, uint64_t resourceIdentifier, WebKitURIRequest*);
void webkitWebViewRunFileChooserRequest(WebKitWebView*, WebKitFileChooserRequest*);
WebKitWebResource* webkitWebViewGetLoadingWebResource(WebKitWebView*, uint64_t resourceIdentifier);
void webkitWebViewRemoveLoadingWebResource(WebKitWebView*, uint64_t resourceIdentifier);
WebKitWebResource* webkitWebViewResourceLoadFinished(WebKitWebView*, uint64_t resourceIdentifier);
bool webkitWebViewEnterFullScreen(WebKitWebView*);
bool webkitWebViewLeaveFullScreen(WebKitWebView*);
-void webkitWebViewPopulateContextMenu(WebKitWebView*, WKArrayRef proposedMenu, WKHitTestResultRef);
+void webkitWebViewPopulateContextMenu(WebKitWebView*, ImmutableArray* proposedMenu, WebHitTestResult*);
void webkitWebViewSubmitFormRequest(WebKitWebView*, WebKitFormSubmissionRequest*);
#endif // WebKitWebViewPrivate_h
diff --git a/Source/WebKit2/UIProcess/API/gtk/docs/webkit2gtk-sections.txt b/Source/WebKit2/UIProcess/API/gtk/docs/webkit2gtk-sections.txt
index 4f5b36c4d..bbf979b64 100644
--- a/Source/WebKit2/UIProcess/API/gtk/docs/webkit2gtk-sections.txt
+++ b/Source/WebKit2/UIProcess/API/gtk/docs/webkit2gtk-sections.txt
@@ -70,6 +70,7 @@ WebKitSaveMode
WEBKIT_EDITING_COMMAND_CUT
WEBKIT_EDITING_COMMAND_COPY
WEBKIT_EDITING_COMMAND_PASTE
+WEBKIT_EDITING_COMMAND_SELECT_ALL
<SUBSECTION>
webkit_web_view_new
diff --git a/Source/WebKit2/UIProcess/API/gtk/tests/TestWebViewEditor.cpp b/Source/WebKit2/UIProcess/API/gtk/tests/TestWebViewEditor.cpp
index 97ebe5b27..93315db68 100644
--- a/Source/WebKit2/UIProcess/API/gtk/tests/TestWebViewEditor.cpp
+++ b/Source/WebKit2/UIProcess/API/gtk/tests/TestWebViewEditor.cpp
@@ -131,10 +131,70 @@ static void testWebViewEditorCutCopyPasteEditable(EditorTest* test, gconstpointe
g_assert_cmpstr(clipboardText.get(), ==, "All work and no play make Jack a dull boy.");
}
+static void testWebViewEditorSelectAllNonEditable(EditorTest* test, gconstpointer)
+{
+ static const char* selectedSpanHTML = "<html><body contentEditable=\"false\">"
+ "<span id=\"mainspan\">All work and no play <span id=\"subspan\">make Jack a dull</span> boy.</span>"
+ "<script>document.getSelection().collapse();\n"
+ "document.getSelection().selectAllChildren(document.getElementById('subspan'));\n"
+ "</script></body></html>";
+
+ g_assert(test->canExecuteEditingCommand(WEBKIT_EDITING_COMMAND_SELECT_ALL));
+
+ test->loadHtml(selectedSpanHTML, 0);
+ test->waitUntilLoadFinished();
+
+ g_assert(test->canExecuteEditingCommand(WEBKIT_EDITING_COMMAND_SELECT_ALL));
+
+ test->copyClipboard();
+ GOwnPtr<char> clipboardText(gtk_clipboard_wait_for_text(test->m_clipboard));
+
+ // Initially only the subspan is selected.
+ g_assert_cmpstr(clipboardText.get(), ==, "make Jack a dull");
+
+ webkit_web_view_execute_editing_command(test->m_webView, WEBKIT_EDITING_COMMAND_SELECT_ALL);
+ test->copyClipboard();
+ clipboardText.set(gtk_clipboard_wait_for_text(test->m_clipboard));
+
+ // The mainspan should be selected after calling SELECT_ALL.
+ g_assert_cmpstr(clipboardText.get(), ==, "All work and no play make Jack a dull boy.");
+}
+
+static void testWebViewEditorSelectAllEditable(EditorTest* test, gconstpointer)
+{
+ static const char* selectedSpanHTML = "<html><body contentEditable=\"true\">"
+ "<span id=\"mainspan\">All work and no play <span id=\"subspan\">make Jack a dull</span> boy.</span>"
+ "<script>document.getSelection().collapse();\n"
+ "document.getSelection().selectAllChildren(document.getElementById('subspan'));\n"
+ "</script></body></html>";
+
+ g_assert(test->canExecuteEditingCommand(WEBKIT_EDITING_COMMAND_SELECT_ALL));
+
+ test->loadHtml(selectedSpanHTML, 0);
+ test->waitUntilLoadFinished();
+
+ g_assert(test->canExecuteEditingCommand(WEBKIT_EDITING_COMMAND_SELECT_ALL));
+
+ test->copyClipboard();
+ GOwnPtr<char> clipboardText(gtk_clipboard_wait_for_text(test->m_clipboard));
+
+ // Initially only the subspan is selected.
+ g_assert_cmpstr(clipboardText.get(), ==, "make Jack a dull");
+
+ webkit_web_view_execute_editing_command(test->m_webView, WEBKIT_EDITING_COMMAND_SELECT_ALL);
+ test->copyClipboard();
+ clipboardText.set(gtk_clipboard_wait_for_text(test->m_clipboard));
+
+ // The mainspan should be selected after calling SELECT_ALL.
+ g_assert_cmpstr(clipboardText.get(), ==, "All work and no play make Jack a dull boy.");
+}
+
void beforeAll()
{
EditorTest::add("WebKitWebView", "cut-copy-paste/non-editable", testWebViewEditorCutCopyPasteNonEditable);
EditorTest::add("WebKitWebView", "cut-copy-paste/editable", testWebViewEditorCutCopyPasteEditable);
+ EditorTest::add("WebKitWebView", "select-all/non-editable", testWebViewEditorSelectAllNonEditable);
+ EditorTest::add("WebKitWebView", "select-all/editable", testWebViewEditorSelectAllEditable);
}
void afterAll()
diff --git a/Source/WebKit2/UIProcess/API/mac/WKProcessGroup.mm b/Source/WebKit2/UIProcess/API/mac/WKProcessGroup.mm
index f19381891..8b4770046 100644
--- a/Source/WebKit2/UIProcess/API/mac/WKProcessGroup.mm
+++ b/Source/WebKit2/UIProcess/API/mac/WKProcessGroup.mm
@@ -83,7 +83,7 @@ static void setUpConnectionClient(WKProcessGroup *processGroup, WKContextRef con
_data = [[WKProcessGroupData alloc] init];
if (bundleURL)
- _data->_contextRef = adoptWK(WKContextCreateWithInjectedBundlePath(adoptWK(WKStringCreateWithCFString((CFStringRef)[bundleURL absoluteString])).get()));
+ _data->_contextRef = adoptWK(WKContextCreateWithInjectedBundlePath(adoptWK(WKStringCreateWithCFString((CFStringRef)[bundleURL path])).get()));
else
_data->_contextRef = adoptWK(WKContextCreate());
diff --git a/Source/WebKit2/UIProcess/Launcher/ProcessLauncher.h b/Source/WebKit2/UIProcess/Launcher/ProcessLauncher.h
index 3144a43b6..5945e1e28 100644
--- a/Source/WebKit2/UIProcess/Launcher/ProcessLauncher.h
+++ b/Source/WebKit2/UIProcess/Launcher/ProcessLauncher.h
@@ -61,9 +61,11 @@ public:
bool useXPC;
#endif
#endif
+#if PLATFORM(EFL)
#ifndef NDEBUG
String processCmdPrefix;
#endif
+#endif
};
static PassRefPtr<ProcessLauncher> create(Client* client, const LaunchOptions& launchOptions)
diff --git a/Source/WebKit2/UIProcess/WebProcessProxy.cpp b/Source/WebKit2/UIProcess/WebProcessProxy.cpp
index 13ca474f3..579783eed 100644
--- a/Source/WebKit2/UIProcess/WebProcessProxy.cpp
+++ b/Source/WebKit2/UIProcess/WebProcessProxy.cpp
@@ -108,21 +108,8 @@ void WebProcessProxy::connect()
ProcessLauncher::LaunchOptions launchOptions;
launchOptions.processType = ProcessLauncher::WebProcess;
-
-#if PLATFORM(MAC)
- // We want the web process to match the architecture of the UI process.
- launchOptions.architecture = ProcessLauncher::LaunchOptions::MatchCurrentArchitecture;
- launchOptions.executableHeap = false;
-#if HAVE(XPC)
- launchOptions.useXPC = getenv("WEBKIT_USE_XPC_SERVICE_FOR_WEB_PROCESS");
-#endif
-#endif
-#ifndef NDEBUG
- const char* webProcessCmdPrefix = getenv("WEB_PROCESS_CMD_PREFIX");
- if (webProcessCmdPrefix && *webProcessCmdPrefix)
- launchOptions.processCmdPrefix = String::fromUTF8(webProcessCmdPrefix);
-#endif
-
+ platformConnect(launchOptions);
+
m_processLauncher = ProcessLauncher::create(this, launchOptions);
}
diff --git a/Source/WebKit2/UIProcess/WebProcessProxy.h b/Source/WebKit2/UIProcess/WebProcessProxy.h
index 2dc204f89..c4fd3c929 100644
--- a/Source/WebKit2/UIProcess/WebProcessProxy.h
+++ b/Source/WebKit2/UIProcess/WebProcessProxy.h
@@ -123,6 +123,7 @@ private:
// Initializes the process launcher which will begin launching the process.
void connect();
+ void platformConnect(ProcessLauncher::LaunchOptions&);
// Called when the web process has crashed or we know that it will terminate soon.
// Will potentially cause the WebProcessProxy object to be freed.
diff --git a/Source/WebKit2/UIProcess/cairo/BackingStoreCairo.cpp b/Source/WebKit2/UIProcess/cairo/BackingStoreCairo.cpp
index ae0fd3669..4d98f9f0c 100644
--- a/Source/WebKit2/UIProcess/cairo/BackingStoreCairo.cpp
+++ b/Source/WebKit2/UIProcess/cairo/BackingStoreCairo.cpp
@@ -31,7 +31,7 @@
#include "UpdateInfo.h"
#include "WebPageProxy.h"
#include <WebCore/GraphicsContext.h>
-#include <cairo/cairo.h>
+#include <cairo.h>
#if PLATFORM(EFL)
#include "ewk_view_private.h"
diff --git a/Source/WebKit2/UIProcess/efl/WebProcessProxyEfl.cpp b/Source/WebKit2/UIProcess/efl/WebProcessProxyEfl.cpp
new file mode 100644
index 000000000..c057e9c34
--- /dev/null
+++ b/Source/WebKit2/UIProcess/efl/WebProcessProxyEfl.cpp
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2012 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"
+#include "WebProcessProxy.h"
+
+namespace WebKit {
+
+void WebProcessProxy::platformConnect(ProcessLauncher::LaunchOptions& launchOptions)
+{
+#ifndef NDEBUG
+ const char* webProcessCmdPrefix = getenv("WEB_PROCESS_CMD_PREFIX");
+ if (webProcessCmdPrefix && *webProcessCmdPrefix)
+ launchOptions.processCmdPrefix = String::fromUTF8(webProcessCmdPrefix);
+#else
+ UNUSED_PARAM(launchOptions);
+#endif
+}
+
+} // namespace WebKit
diff --git a/Source/WebKit2/UIProcess/gtk/WebProcessProxyGtk.cpp b/Source/WebKit2/UIProcess/gtk/WebProcessProxyGtk.cpp
new file mode 100644
index 000000000..3ad528f27
--- /dev/null
+++ b/Source/WebKit2/UIProcess/gtk/WebProcessProxyGtk.cpp
@@ -0,0 +1,35 @@
+/*
+ * Copyright (C) 2012 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"
+#include "WebProcessProxy.h"
+
+namespace WebKit {
+
+void WebProcessProxy::platformConnect(ProcessLauncher::LaunchOptions&)
+{
+}
+
+} // namespace WebKit
diff --git a/Source/WebKit2/UIProcess/mac/WebProcessProxyMac.mm b/Source/WebKit2/UIProcess/mac/WebProcessProxyMac.mm
index 66422a147..73f3ddc02 100644
--- a/Source/WebKit2/UIProcess/mac/WebProcessProxyMac.mm
+++ b/Source/WebKit2/UIProcess/mac/WebProcessProxyMac.mm
@@ -149,4 +149,15 @@ bool WebProcessProxy::fullKeyboardAccessEnabled()
return [WKFullKeyboardAccessWatcher fullKeyboardAccessEnabled];
}
+void WebProcessProxy::platformConnect(ProcessLauncher::LaunchOptions& launchOptions)
+{
+ // We want the web process to match the architecture of the UI process.
+ launchOptions.architecture = ProcessLauncher::LaunchOptions::MatchCurrentArchitecture;
+ launchOptions.executableHeap = false;
+
+#if HAVE(XPC)
+ launchOptions.useXPC = [[NSUserDefaults standardUserDefaults] boolForKey:@"WebKit2UseXPCServiceForWebProcess"];
+#endif
+}
+
} // namespace WebKit
diff --git a/Source/WebKit2/UIProcess/qt/WebProcessProxyQt.cpp b/Source/WebKit2/UIProcess/qt/WebProcessProxyQt.cpp
new file mode 100644
index 000000000..3ad528f27
--- /dev/null
+++ b/Source/WebKit2/UIProcess/qt/WebProcessProxyQt.cpp
@@ -0,0 +1,35 @@
+/*
+ * Copyright (C) 2012 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"
+#include "WebProcessProxy.h"
+
+namespace WebKit {
+
+void WebProcessProxy::platformConnect(ProcessLauncher::LaunchOptions&)
+{
+}
+
+} // namespace WebKit
diff --git a/Source/WebKit2/UIProcess/win/WebProcessProxyWin.cpp b/Source/WebKit2/UIProcess/win/WebProcessProxyWin.cpp
index 1856b3b00..fef2c68b3 100644
--- a/Source/WebKit2/UIProcess/win/WebProcessProxyWin.cpp
+++ b/Source/WebKit2/UIProcess/win/WebProcessProxyWin.cpp
@@ -33,4 +33,8 @@ Vector<HWND> WebProcessProxy::windowsToReceiveSentMessagesWhileWaitingForSyncRep
return Vector<HWND>();
}
+void WebProcessProxy::platformConnect(ProcessLauncher::LaunchOptions&)
+{
+}
+
} // namespace WebKit
diff --git a/Source/WebKit2/WebProcess/InjectedBundle/API/c/WKBundlePage.cpp b/Source/WebKit2/WebProcess/InjectedBundle/API/c/WKBundlePage.cpp
index 18247b664..c635e6e84 100644
--- a/Source/WebKit2/WebProcess/InjectedBundle/API/c/WKBundlePage.cpp
+++ b/Source/WebKit2/WebProcess/InjectedBundle/API/c/WKBundlePage.cpp
@@ -44,6 +44,7 @@
#include <WebCore/AccessibilityObject.h>
#include <WebCore/Frame.h>
#include <WebCore/KURL.h>
+#include <WebCore/MIMETypeRegistry.h>
#include <WebCore/Page.h>
#if ENABLE(WEB_INTENTS)
@@ -413,3 +414,21 @@ void WKBundlePageConfirmCompositionWithText(WKBundlePageRef pageRef, WKStringRef
{
toImpl(pageRef)->confirmCompositionForTesting(toImpl(text)->string());
}
+
+bool WKBundlePageCanShowMIMEType(WKBundlePageRef, WKStringRef mimeTypeRef)
+{
+ using WebCore::MIMETypeRegistry;
+
+ const WTF::String mimeType = toImpl(mimeTypeRef)->string();
+
+ if (MIMETypeRegistry::isSupportedNonImageMIMEType(mimeType))
+ return true;
+
+ if (MIMETypeRegistry::isSupportedImageMIMEType(mimeType))
+ return true;
+
+ if (mimeType.startsWith("text/", false))
+ return !MIMETypeRegistry::isUnsupportedTextMIMEType(mimeType);
+
+ return false;
+}
diff --git a/Source/WebKit2/WebProcess/InjectedBundle/API/c/WKBundlePagePrivate.h b/Source/WebKit2/WebProcess/InjectedBundle/API/c/WKBundlePagePrivate.h
index b7c82b811..c7393ba3f 100644
--- a/Source/WebKit2/WebProcess/InjectedBundle/API/c/WKBundlePagePrivate.h
+++ b/Source/WebKit2/WebProcess/InjectedBundle/API/c/WKBundlePagePrivate.h
@@ -71,8 +71,10 @@ WK_EXPORT bool WKBundlePageHasComposition(WKBundlePageRef page);
WK_EXPORT void WKBundlePageConfirmComposition(WKBundlePageRef page);
WK_EXPORT void WKBundlePageConfirmCompositionWithText(WKBundlePageRef page, WKStringRef text);
+WK_EXPORT bool WKBundlePageCanShowMIMEType(WKBundlePageRef, WKStringRef mimeType);
+
WK_EXPORT void* WKAccessibilityRootObject(WKBundlePageRef);
-WK_EXPORT void* WKAccessibilityFocusedObject(WKBundlePageRef);
+WK_EXPORT void* WKAccessibilityFocusedObject(WKBundlePageRef);
#ifdef __cplusplus
}
diff --git a/Source/WebKit2/WebProcess/Plugins/Netscape/x11/NetscapePluginX11.cpp b/Source/WebKit2/WebProcess/Plugins/Netscape/x11/NetscapePluginX11.cpp
index da2478d5a..5c9e67872 100644
--- a/Source/WebKit2/WebProcess/Plugins/Netscape/x11/NetscapePluginX11.cpp
+++ b/Source/WebKit2/WebProcess/Plugins/Netscape/x11/NetscapePluginX11.cpp
@@ -39,7 +39,7 @@
#elif PLATFORM(GTK)
#include "PlatformContextCairo.h"
#include "RefPtrCairo.h"
-#include <cairo/cairo-xlib.h>
+#include <cairo-xlib.h>
#include <gtk/gtk.h>
#ifndef GTK_API_VERSION_2
#include <gtk/gtkx.h>
diff --git a/Source/WebKit2/win/WebKit2.def b/Source/WebKit2/win/WebKit2.def
index 1cdc404c0..e0b7da9ab 100644
--- a/Source/WebKit2/win/WebKit2.def
+++ b/Source/WebKit2/win/WebKit2.def
@@ -222,6 +222,7 @@ EXPORTS
?setDOMException@WebCore@@YAXPAVExecState@JSC@@H@Z
?setFantasyFontFamily@Settings@WebCore@@QAEXABVAtomicString@WTF@@W4UScriptCode@@@Z
?setFixedFontFamily@Settings@WebCore@@QAEXABVAtomicString@WTF@@W4UScriptCode@@@Z
+ ?setImagesEnabled@Settings@WebCore@@QAEX_N@Z
?setMockScrollbarsEnabled@Settings@WebCore@@SAX_N@Z
?mockScrollbarsEnabled@Settings@WebCore@@SA_NXZ
?setUsesOverlayScrollbars@Settings@WebCore@@SAX_N@Z
@@ -289,3 +290,23 @@ EXPORTS
?numberOfPages@PrintContext@WebCore@@SAHPAVFrame@2@ABVFloatSize@2@@Z
?pageProperty@PrintContext@WebCore@@SA?AVString@WTF@@PAVFrame@2@PBDH@Z
?pageSizeAndMarginsInPixels@PrintContext@WebCore@@SA?AVString@WTF@@PAVFrame@2@HHHHHHH@Z
+ ??0InspectorFrontendClientLocal@WebCore@@QAE@PAVInspectorController@1@PAVPage@1@V?$PassOwnPtr@VSettings@InspectorFrontendClientLocal@WebCore@@@WTF@@@Z
+ ??1InspectorFrontendClientLocal@WebCore@@UAE@XZ
+ ?changeAttachedWindowHeight@InspectorFrontendClientLocal@WebCore@@UAEXI@Z
+ ?close@DOMWindow@WebCore@@QAEXPAVScriptExecutionContext@2@@Z
+ ?connectFrontend@InspectorController@WebCore@@QAEXPAVInspectorFrontendChannel@2@@Z
+ ?disconnectFrontend@InspectorController@WebCore@@QAEXXZ
+ ?document@DOMWindow@WebCore@@QBEPAVDocument@2@XZ
+ ?doDispatchMessageOnFrontendPage@InspectorClient@WebCore@@SA_NPAVPage@2@ABVString@WTF@@@Z
+ ?frontendLoaded@InspectorFrontendClientLocal@WebCore@@UAEXXZ
+ ?getProperty@Settings@InspectorFrontendClientLocal@WebCore@@UAE?AVString@WTF@@ABV45@@Z
+ ?moveWindowBy@InspectorFrontendClientLocal@WebCore@@UAEXMM@Z
+ ?open@DOMWindow@WebCore@@QAE?AV?$PassRefPtr@VDOMWindow@WebCore@@@WTF@@ABVString@4@ABVAtomicString@4@0PAV12@2@Z
+ ?openInNewTab@InspectorFrontendClientLocal@WebCore@@UAEXABVString@WTF@@@Z
+ ?requestAttachWindow@InspectorFrontendClientLocal@WebCore@@UAEXXZ
+ ?requestDetachWindow@InspectorFrontendClientLocal@WebCore@@UAEXXZ
+ ?sendMessageToBackend@InspectorFrontendClientLocal@WebCore@@UAEXABVString@WTF@@@Z
+ ?setInspectorFrontendClient@InspectorController@WebCore@@QAEXV?$PassOwnPtr@VInspectorFrontendClient@WebCore@@@WTF@@@Z
+ ?setProperty@Settings@InspectorFrontendClientLocal@WebCore@@UAEXABVString@WTF@@0@Z
+ ?toJS@WebCore@@YA?AVJSValue@JSC@@PAVExecState@3@PAVJSDOMGlobalObject@1@PAVDOMWindow@1@@Z
+ ?windowObjectCleared@InspectorFrontendClientLocal@WebCore@@UAEXXZ
diff --git a/Source/WebKit2/win/WebKit2CFLite.def b/Source/WebKit2/win/WebKit2CFLite.def
index 64bf790c0..3675ac250 100644
--- a/Source/WebKit2/win/WebKit2CFLite.def
+++ b/Source/WebKit2/win/WebKit2CFLite.def
@@ -279,3 +279,23 @@ EXPORTS
?numberOfPages@PrintContext@WebCore@@SAHPAVFrame@2@ABVFloatSize@2@@Z
?pageProperty@PrintContext@WebCore@@SA?AVString@WTF@@PAVFrame@2@PBDH@Z
?pageSizeAndMarginsInPixels@PrintContext@WebCore@@SA?AVString@WTF@@PAVFrame@2@HHHHHHH@Z
+ ??0InspectorFrontendClientLocal@WebCore@@QAE@PAVInspectorController@1@PAVPage@1@V?$PassOwnPtr@VSettings@InspectorFrontendClientLocal@WebCore@@@WTF@@@Z
+ ??1InspectorFrontendClientLocal@WebCore@@UAE@XZ
+ ?changeAttachedWindowHeight@InspectorFrontendClientLocal@WebCore@@UAEXI@Z
+ ?close@DOMWindow@WebCore@@QAEXPAVScriptExecutionContext@2@@Z
+ ?connectFrontend@InspectorController@WebCore@@QAEXPAVInspectorFrontendChannel@2@@Z
+ ?disconnectFrontend@InspectorController@WebCore@@QAEXXZ
+ ?document@DOMWindow@WebCore@@QBEPAVDocument@2@XZ
+ ?doDispatchMessageOnFrontendPage@InspectorClient@WebCore@@SA_NPAVPage@2@ABVString@WTF@@@Z
+ ?frontendLoaded@InspectorFrontendClientLocal@WebCore@@UAEXXZ
+ ?getProperty@Settings@InspectorFrontendClientLocal@WebCore@@UAE?AVString@WTF@@ABV45@@Z
+ ?moveWindowBy@InspectorFrontendClientLocal@WebCore@@UAEXMM@Z
+ ?open@DOMWindow@WebCore@@QAE?AV?$PassRefPtr@VDOMWindow@WebCore@@@WTF@@ABVString@4@ABVAtomicString@4@0PAV12@2@Z
+ ?openInNewTab@InspectorFrontendClientLocal@WebCore@@UAEXABVString@WTF@@@Z
+ ?requestAttachWindow@InspectorFrontendClientLocal@WebCore@@UAEXXZ
+ ?requestDetachWindow@InspectorFrontendClientLocal@WebCore@@UAEXXZ
+ ?sendMessageToBackend@InspectorFrontendClientLocal@WebCore@@UAEXABVString@WTF@@@Z
+ ?setInspectorFrontendClient@InspectorController@WebCore@@QAEXV?$PassOwnPtr@VInspectorFrontendClient@WebCore@@@WTF@@@Z
+ ?setProperty@Settings@InspectorFrontendClientLocal@WebCore@@UAEXABVString@WTF@@0@Z
+ ?toJS@WebCore@@YA?AVJSValue@JSC@@PAVExecState@3@PAVJSDOMGlobalObject@1@PAVDOMWindow@1@@Z
+ ?windowObjectCleared@InspectorFrontendClientLocal@WebCore@@UAEXXZ
diff --git a/Source/api.pri b/Source/api.pri
index b46696fe3..815cd77a9 100644
--- a/Source/api.pri
+++ b/Source/api.pri
@@ -31,9 +31,12 @@ MODULE = webkit
QT_API_DEPENDS = core gui network
build?(webkit1): QT_API_DEPENDS += widgets
-# We want the QtWebKit API forwarding includes to live in the root build dir.
-MODULE_BASE_DIR = $$_PRO_FILE_PWD_
-MODULE_BASE_OUTDIR = $$ROOT_BUILD_DIR
+qmakeVersion=$$[QMAKE_VERSION]
+equals(qmakeVersion, 3.0) {
+ # We want the QtWebKit API forwarding includes to live in the root build dir.
+ MODULE_BASE_DIR = $$_PRO_FILE_PWD_
+ MODULE_BASE_OUTDIR = $$ROOT_BUILD_DIR
+}
# We load the relevant modules here, so that the effects of each module
# on the QT variable can be picked up when we later load(qt_module).
diff --git a/Source/autotools/symbols.filter b/Source/autotools/symbols.filter
index d5d54106a..49676cf18 100644
--- a/Source/autotools/symbols.filter
+++ b/Source/autotools/symbols.filter
@@ -65,6 +65,7 @@ _ZN7WebCore14FormController22getReferencedFilePathsERKN3WTF6VectorINS1_6StringEL
_ZN7WebCore14FrameSelection19absoluteCaretBoundsEv;
_ZN7WebCore14SchemeRegistry49registerURLSchemeAsBypassingContentSecurityPolicyERKN3WTF6StringE;
_ZN7WebCore14SchemeRegistry57removeURLSchemeRegisteredAsBypassingContentSecurityPolicyERKN3WTF6StringE;
+_ZN7WebCore15InspectorClient31doDispatchMessageOnFrontendPageEPNS_4PageERKN3WTF6StringE;
_ZN7WebCore15setDOMExceptionEPN3JSC9ExecStateEi;
_ZN7WebCore15toDOMStringListEPN3JSC9ExecStateENS0_7JSValueE;
_ZN7WebCore16HTMLInputElement17setSuggestedValueERKN3WTF6StringE;
@@ -74,6 +75,9 @@ _ZN7WebCore17cacheDOMStructureEPNS_17JSDOMGlobalObjectEPN3JSC9StructureEPKNS2_9C
_ZN7WebCore17HistoryController26saveDocumentAndScrollStateEv;
_ZN7WebCore17InspectorCounters12counterValueENS0_11CounterTypeE;
_ZN7WebCore18HTMLContentElement6createEPNS_8DocumentE;
+_ZN7WebCore19InspectorController15connectFrontendEPNS_24InspectorFrontendChannelE;
+_ZN7WebCore19InspectorController18disconnectFrontendEv;
+_ZN7WebCore19InspectorController26setInspectorFrontendClientEN3WTF10PassOwnPtrINS_23InspectorFrontendClientEEE;
_ZN7WebCore19InspectorController39setResourcesDataSizeLimitsFromInternalsEii;
_ZN7WebCore20CachedResourceLoader31garbageCollectDocumentResourcesEv;
_ZN7WebCore20NodeRenderingContextC1EPNS_4NodeE;
@@ -92,10 +96,21 @@ _ZN7WebCore24DocumentMarkerController10markersForEPNS_4NodeENS_14DocumentMarker1
_ZN7WebCore24DocumentMarkerController18addTextMatchMarkerEPKNS_5RangeEb;
_ZN7WebCore25computeViewportAttributesENS_17ViewportArgumentsEiiifNS_7IntSizeE;
_ZN7WebCore25jsStringWithCacheSlowCaseEPN3JSC9ExecStateERN3WTF7HashMapIPNS3_10StringImplENS0_4WeakINS0_8JSStringEEENS3_7PtrHashIS6_EENS3_10HashTraitsIS6_EENSC_IS9_EEEES6_;
+_ZN7WebCore28InspectorFrontendClientLocal12moveWindowByEff;
+_ZN7WebCore28InspectorFrontendClientLocal12openInNewTabERKN3WTF6StringE;
+_ZN7WebCore28InspectorFrontendClientLocal14frontendLoadedEv;
+_ZN7WebCore28InspectorFrontendClientLocal19requestAttachWindowEv;
+_ZN7WebCore28InspectorFrontendClientLocal19requestDetachWindowEv;
+_ZN7WebCore28InspectorFrontendClientLocal19windowObjectClearedEv;
+_ZN7WebCore28InspectorFrontendClientLocal20sendMessageToBackendERKN3WTF6StringE;
+_ZN7WebCore28InspectorFrontendClientLocal26changeAttachedWindowHeightEj;
+_ZN7WebCore28InspectorFrontendClientLocalC2EPNS_19InspectorControllerEPNS_4PageEN3WTF10PassOwnPtrINS0_8SettingsEEE;
+_ZN7WebCore28InspectorFrontendClientLocalD2Ev;
_ZN7WebCore30overrideUserPreferredLanguagesERKN3WTF6VectorINS0_6StringELj0EEE;
_ZN7WebCore30overrideUserPreferredLanguagesERKN3WTF6VectorINS0_6StringELm0EEE;
_ZN7WebCore40restrictMinimumScaleFactorToViewportSizeERNS_18ViewportAttributesENS_7IntSizeE;
_ZN7WebCore4toJSEPN3JSC9ExecStateEPNS_17JSDOMGlobalObjectEPNS_13DOMStringListE;
+_ZN7WebCore4toJSEPN3JSC9ExecStateEPNS_17JSDOMGlobalObjectEPNS_9DOMWindowE;
_ZN7WebCore50restrictScaleFactorToInitialScaleIfNotUserScalableERNS_18ViewportAttributesE;
_ZN7WebCore6JSNode10putVirtualEPN3JSC9ExecStateERKNS1_10IdentifierENS1_7JSValueERNS1_15PutPropertySlotE;
_ZN7WebCore6JSNode20visitChildrenVirtualERN3JSC11SlotVisitorE;
@@ -105,6 +120,8 @@ _ZN7WebCore7Element20removeShadowRootListEv;
_ZN7WebCore7Element17setShadowPseudoIdERKN3WTF12AtomicStringERi;
_ZN7WebCore7jsArrayEPN3JSC9ExecStateEPNS_17JSDOMGlobalObjectEN3WTF10PassRefPtrINS_13DOMStringListEEE;
_ZN7WebCore7toRangeEN3JSC7JSValueE;
+_ZN7WebCore9DOMWindow4openERKN3WTF6StringERKNS1_12AtomicStringES4_PS0_S8_;
+_ZN7WebCore9DOMWindow5closeEPNS_22ScriptExecutionContextE;
_ZN7WebCore9JSElement10putVirtualEPN3JSC9ExecStateERKNS1_10IdentifierENS1_7JSValueERNS1_15PutPropertySlotE;
_ZN7WebCore9JSElement6s_infoE;
_ZN7WebCore9toElementEN3JSC7JSValueE;
@@ -145,6 +162,7 @@ _ZN7WebCore14ScrollableArea28setScrollOffsetFromInternalsERKNS_8IntPointE;
_ZN7WebCore10ScrollView23setScrollbarsSuppressedEbb;
_ZN7WebCore10ScrollView21setDelegatesScrollingEb;
_ZN7WebCore4Node14removedLastRefEv;
+_ZN7WebCore8Settings16setImagesEnabledEb;
_ZN7WebCore8Settings18setFixedFontFamilyERKN3WTF12AtomicStringE11UScriptCode;
_ZN7WebCore8Settings18setSerifFontFamilyERKN3WTF12AtomicStringE11UScriptCode;
_ZN7WebCore8Settings20setCursiveFontFamilyERKN3WTF12AtomicStringE11UScriptCode;
@@ -182,6 +200,8 @@ _ZN7WebCore26ContextDestructionObserver16contextDestroyedEv;
_ZN7WebCore12PrintContext13numberOfPagesEPNS_5FrameERKNS_9FloatSizeE;
_ZN7WebCore12PrintContext12pagePropertyEPNS_5FrameEPKci;
_ZN7WebCore12PrintContext26pageSizeAndMarginsInPixelsEPNS_5FrameEiiiiiii;
+_ZNK7WebCore9DOMWindow8documentEv;
+_ZTVN7WebCore28InspectorFrontendClientLocal8SettingsE;
local:
_Z*;
diff --git a/Source/cmake/OptionsEfl.cmake b/Source/cmake/OptionsEfl.cmake
index 549056a3e..0ae4eced9 100644
--- a/Source/cmake/OptionsEfl.cmake
+++ b/Source/cmake/OptionsEfl.cmake
@@ -7,7 +7,7 @@ ADD_DEFINITIONS(-DBUILDING_EFL__=1)
ADD_DEFINITIONS(-DWTF_PLATFORM_EFL=1)
SET(WTF_PLATFORM_EFL 1)
-FIND_PACKAGE(Cairo 1.10 REQUIRED)
+FIND_PACKAGE(Cairo 1.10.2 REQUIRED)
FIND_PACKAGE(Fontconfig 2.8.0 REQUIRED)
FIND_PACKAGE(Sqlite REQUIRED)
FIND_PACKAGE(LibXml2 2.6 REQUIRED)
@@ -18,7 +18,7 @@ FIND_PACKAGE(JPEG REQUIRED)
FIND_PACKAGE(PNG REQUIRED)
FIND_PACKAGE(ZLIB REQUIRED)
-FIND_PACKAGE(GLIB 2.31.8 REQUIRED COMPONENTS gio gobject gthread)
+FIND_PACKAGE(GLIB 2.33.2 REQUIRED COMPONENTS gio gobject gthread)
FIND_PACKAGE(LibSoup 2.39.4.1 REQUIRED)
SET(ENABLE_GLIB_SUPPORT ON)
@@ -77,6 +77,7 @@ WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_NAVIGATOR_CONTENT_UTILS ON)
WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_NETSCAPE_PLUGIN_API OFF)
WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_NETWORK_INFO ON)
WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_PAGE_VISIBILITY_API ON)
+WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_REGIONS ON)
WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_REQUEST_ANIMATION_FRAME ON)
WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_SHADOW_DOM ON)
WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_SHARED_WORKERS ON)
@@ -104,15 +105,15 @@ IF (ENABLE_ECORE_X)
ENDIF ()
FIND_PACKAGE(Eina 1.2 REQUIRED)
-FIND_PACKAGE(Evas 1.0 REQUIRED)
+FIND_PACKAGE(Evas 1.2 REQUIRED)
FIND_PACKAGE(Ecore 1.2 COMPONENTS Evas File Input ${ECORE_ADDITIONAL_COMPONENTS})
-FIND_PACKAGE(Edje 1.0 REQUIRED)
+FIND_PACKAGE(Edje 1.2 REQUIRED)
FIND_PACKAGE(Eeze 1.2 REQUIRED)
-FIND_PACKAGE(Efreet 1.0 REQUIRED)
-FIND_PACKAGE(E_DBus 1.1 COMPONENTS EUKit)
+FIND_PACKAGE(Efreet 1.2 REQUIRED)
+FIND_PACKAGE(E_DBus 1.2 COMPONENTS EUKit)
-FIND_PACKAGE(Freetype REQUIRED)
-FIND_PACKAGE(HarfBuzz REQUIRED)
+FIND_PACKAGE(Freetype 2.4.2 REQUIRED)
+FIND_PACKAGE(HarfBuzz 0.9.2 REQUIRED)
SET(WTF_USE_FREETYPE 1)
SET(WTF_USE_HARFBUZZ_NG 1)
ADD_DEFINITIONS(-DWTF_USE_FREETYPE=1)