summaryrefslogtreecommitdiffstats
path: root/WebCore
diff options
context:
space:
mode:
Diffstat (limited to 'WebCore')
-rw-r--r--WebCore/Android.mk5
-rw-r--r--WebCore/CMakeLists.txt9
-rw-r--r--WebCore/CMakeListsEfl.txt2
-rw-r--r--WebCore/ChangeLog5326
-rw-r--r--WebCore/DerivedSources.cpp1
-rw-r--r--WebCore/DerivedSources.make11
-rw-r--r--WebCore/English.lproj/localizedStrings.jsbin42440 -> 43046 bytes
-rw-r--r--WebCore/ForwardingHeaders/wtf/DecimalNumber.h4
-rw-r--r--WebCore/GNUmakefile.am78
-rw-r--r--WebCore/WebCore.exp.in18
-rw-r--r--WebCore/WebCore.gyp/WebCore.gyp9
-rw-r--r--WebCore/WebCore.gypi44
-rw-r--r--WebCore/WebCore.pri3
-rw-r--r--WebCore/WebCore.pro62
-rw-r--r--WebCore/WebCore.vcproj/WebCore.vcproj286
-rw-r--r--WebCore/WebCore.xcodeproj/project.pbxproj146
-rw-r--r--WebCore/accessibility/AccessibilityRenderObject.cpp7
-rw-r--r--WebCore/bindings/gobject/WebKitHTMLElementWrapperFactory.cpp9
-rw-r--r--WebCore/bindings/js/JSInjectedScriptHostCustom.cpp6
-rw-r--r--WebCore/bindings/js/JSInspectorFrontendHostCustom.cpp19
-rw-r--r--WebCore/bindings/js/JSNodeFilterCondition.cpp19
-rw-r--r--WebCore/bindings/js/JSWebGLRenderingContextCustom.cpp20
-rw-r--r--WebCore/bindings/js/ScriptDebugServer.cpp5
-rw-r--r--WebCore/bindings/js/ScriptDebugServer.h1
-rw-r--r--WebCore/bindings/js/ScriptProfiler.cpp5
-rw-r--r--WebCore/bindings/js/ScriptProfiler.h1
-rw-r--r--WebCore/bindings/objc/DOM.mm2
-rw-r--r--WebCore/bindings/scripts/CodeGeneratorJS.pm14
-rw-r--r--WebCore/bindings/scripts/CodeGeneratorV8.pm22
-rw-r--r--WebCore/bindings/v8/ScriptDebugServer.cpp85
-rw-r--r--WebCore/bindings/v8/ScriptDebugServer.h7
-rw-r--r--WebCore/bindings/v8/ScriptProfiler.cpp5
-rw-r--r--WebCore/bindings/v8/ScriptProfiler.h1
-rw-r--r--WebCore/bindings/v8/V8DOMWrapper.cpp6
-rw-r--r--WebCore/bindings/v8/V8HiddenPropertyName.h2
-rw-r--r--WebCore/bindings/v8/V8NodeFilterCondition.cpp15
-rw-r--r--WebCore/bindings/v8/V8Proxy.cpp22
-rw-r--r--WebCore/bindings/v8/V8Proxy.h4
-rw-r--r--WebCore/bindings/v8/custom/V8InjectedScriptHostCustom.cpp18
-rw-r--r--WebCore/bindings/v8/custom/V8InspectorFrontendHostCustom.cpp29
-rw-r--r--WebCore/bindings/v8/custom/V8WebGLRenderingContextCustom.cpp35
-rw-r--r--WebCore/bridge/qt/qt_runtime.cpp2
-rw-r--r--WebCore/css/CSSComputedStyleDeclaration.cpp2
-rw-r--r--WebCore/css/CSSParser.cpp59
-rw-r--r--WebCore/css/CSSPropertyNames.in1
-rw-r--r--WebCore/css/CSSStyleSelector.cpp31
-rw-r--r--WebCore/css/CSSStyleSelector.h3
-rw-r--r--WebCore/css/makeprop.pl14
-rw-r--r--WebCore/dom/ContainerNode.cpp180
-rw-r--r--WebCore/dom/ContainerNode.h18
-rw-r--r--WebCore/dom/DOMImplementation.cpp4
-rw-r--r--WebCore/dom/DeviceOrientationController.cpp17
-rw-r--r--WebCore/dom/Document.cpp574
-rw-r--r--WebCore/dom/Document.h46
-rw-r--r--WebCore/dom/DocumentFragment.cpp6
-rw-r--r--WebCore/dom/DocumentFragment.h2
-rw-r--r--WebCore/dom/DocumentMarkerController.cpp527
-rw-r--r--WebCore/dom/DocumentMarkerController.h72
-rw-r--r--WebCore/dom/DocumentParser.cpp13
-rw-r--r--WebCore/dom/DocumentParser.h32
-rw-r--r--WebCore/dom/Element.cpp11
-rw-r--r--WebCore/dom/EventNames.h3
-rw-r--r--WebCore/dom/EventTarget.cpp10
-rw-r--r--WebCore/dom/EventTarget.h6
-rw-r--r--WebCore/dom/Node.cpp19
-rw-r--r--WebCore/dom/Node.h28
-rw-r--r--WebCore/dom/Position.h2
-rw-r--r--WebCore/dom/RawDataDocumentParser.h7
-rw-r--r--WebCore/dom/ScriptableDocumentParser.h3
-rw-r--r--WebCore/dom/SelectElement.cpp1
-rw-r--r--WebCore/dom/TreeWalker.cpp2
-rw-r--r--WebCore/dom/XMLDocumentParser.cpp52
-rw-r--r--WebCore/dom/XMLDocumentParser.h23
-rw-r--r--WebCore/dom/XMLDocumentParserLibxml2.cpp90
-rw-r--r--WebCore/dom/XMLDocumentParserQt.cpp59
-rw-r--r--WebCore/editing/ApplyStyleCommand.cpp81
-rw-r--r--WebCore/editing/ApplyStyleCommand.h5
-rw-r--r--WebCore/editing/CompositeEditCommand.cpp24
-rw-r--r--WebCore/editing/CompositeEditCommand.h1
-rw-r--r--WebCore/editing/CreateLinkCommand.cpp5
-rw-r--r--WebCore/editing/DeleteSelectionCommand.cpp4
-rw-r--r--WebCore/editing/Editor.cpp33
-rw-r--r--WebCore/editing/Editor.h3
-rw-r--r--WebCore/editing/FormatBlockCommand.cpp2
-rw-r--r--WebCore/editing/IndentOutdentCommand.cpp2
-rw-r--r--WebCore/editing/InsertLineBreakCommand.cpp2
-rw-r--r--WebCore/editing/InsertListCommand.cpp63
-rw-r--r--WebCore/editing/InsertParagraphSeparatorCommand.cpp2
-rw-r--r--WebCore/editing/InsertTextCommand.cpp2
-rw-r--r--WebCore/editing/MoveSelectionCommand.cpp2
-rw-r--r--WebCore/editing/RemoveFormatCommand.cpp5
-rw-r--r--WebCore/editing/ReplaceSelectionCommand.cpp2
-rw-r--r--WebCore/editing/SelectionController.cpp34
-rw-r--r--WebCore/editing/SelectionController.h10
-rw-r--r--WebCore/editing/SplitTextNodeCommand.cpp4
-rw-r--r--WebCore/editing/TextIterator.cpp5
-rw-r--r--WebCore/editing/TypingCommand.cpp2
-rw-r--r--WebCore/editing/UnlinkCommand.cpp4
-rw-r--r--WebCore/editing/VisibleSelection.h2
-rw-r--r--WebCore/editing/htmlediting.h3
-rw-r--r--WebCore/editing/markup.cpp835
-rw-r--r--WebCore/features.pri4
-rw-r--r--WebCore/history/HistoryItem.cpp20
-rw-r--r--WebCore/history/HistoryItem.h2
-rw-r--r--WebCore/html/FileReader.cpp6
-rw-r--r--WebCore/html/FileReader.h2
-rw-r--r--WebCore/html/FileStreamProxy.cpp35
-rw-r--r--WebCore/html/FileStreamProxy.h27
-rw-r--r--WebCore/html/FileThreadTask.h8
-rw-r--r--WebCore/html/FileWriter.cpp (renamed from WebCore/platform/graphics/chromium/TransformLayerChromium.cpp)52
-rw-r--r--WebCore/html/FileWriter.h112
-rw-r--r--WebCore/html/FileWriter.idl62
-rw-r--r--WebCore/html/HTMLAnchorElement.h2
-rw-r--r--WebCore/html/HTMLAppletElement.h2
-rw-r--r--WebCore/html/HTMLAreaElement.cpp2
-rw-r--r--WebCore/html/HTMLAreaElement.h2
-rw-r--r--WebCore/html/HTMLAudioElement.h1
-rw-r--r--WebCore/html/HTMLBRElement.h3
-rw-r--r--WebCore/html/HTMLBaseElement.h3
-rw-r--r--WebCore/html/HTMLBaseFontElement.h3
-rw-r--r--WebCore/html/HTMLBlockquoteElement.h3
-rw-r--r--WebCore/html/HTMLBodyElement.h3
-rw-r--r--WebCore/html/HTMLCanvasElement.cpp34
-rw-r--r--WebCore/html/HTMLCanvasElement.h5
-rw-r--r--WebCore/html/HTMLConstructionSite.cpp21
-rw-r--r--WebCore/html/HTMLConstructionSite.h6
-rw-r--r--WebCore/html/HTMLDListElement.h3
-rw-r--r--WebCore/html/HTMLDataGridCellElement.h4
-rw-r--r--WebCore/html/HTMLDataGridColElement.h2
-rw-r--r--WebCore/html/HTMLDataGridElement.cpp7
-rw-r--r--WebCore/html/HTMLDataGridElement.h3
-rw-r--r--WebCore/html/HTMLDataGridRowElement.cpp7
-rw-r--r--WebCore/html/HTMLDataGridRowElement.h3
-rw-r--r--WebCore/html/HTMLDataListElement.cpp5
-rw-r--r--WebCore/html/HTMLDataListElement.h2
-rw-r--r--WebCore/html/HTMLDirectoryElement.h3
-rw-r--r--WebCore/html/HTMLDivElement.h3
-rw-r--r--WebCore/html/HTMLDocument.cpp11
-rw-r--r--WebCore/html/HTMLDocument.h4
-rw-r--r--WebCore/html/HTMLDocumentParser.cpp109
-rw-r--r--WebCore/html/HTMLDocumentParser.h20
-rw-r--r--WebCore/html/HTMLElement.cpp354
-rw-r--r--WebCore/html/HTMLElement.h15
-rw-r--r--WebCore/html/HTMLElementStack.cpp4
-rw-r--r--WebCore/html/HTMLEmbedElement.cpp4
-rw-r--r--WebCore/html/HTMLEmbedElement.h3
-rw-r--r--WebCore/html/HTMLFieldSetElement.cpp5
-rw-r--r--WebCore/html/HTMLFieldSetElement.h3
-rw-r--r--WebCore/html/HTMLFontElement.h3
-rw-r--r--WebCore/html/HTMLFormCollection.cpp2
-rw-r--r--WebCore/html/HTMLFormControlElement.cpp7
-rw-r--r--WebCore/html/HTMLFormControlElement.h3
-rw-r--r--WebCore/html/HTMLFormElement.cpp2
-rw-r--r--WebCore/html/HTMLFormElement.h3
-rw-r--r--WebCore/html/HTMLFrameElement.h3
-rw-r--r--WebCore/html/HTMLFrameSetElement.cpp9
-rw-r--r--WebCore/html/HTMLFrameSetElement.h4
-rw-r--r--WebCore/html/HTMLHRElement.h3
-rw-r--r--WebCore/html/HTMLHeadElement.cpp17
-rw-r--r--WebCore/html/HTMLHeadElement.h6
-rw-r--r--WebCore/html/HTMLHeadingElement.cpp14
-rw-r--r--WebCore/html/HTMLHeadingElement.h4
-rw-r--r--WebCore/html/HTMLHtmlElement.cpp6
-rw-r--r--WebCore/html/HTMLHtmlElement.h4
-rw-r--r--WebCore/html/HTMLIFrameElement.h3
-rw-r--r--WebCore/html/HTMLImageElement.h3
-rw-r--r--WebCore/html/HTMLInputElement.cpp18
-rw-r--r--WebCore/html/HTMLInputElement.h3
-rw-r--r--WebCore/html/HTMLIsIndexElement.h2
-rw-r--r--WebCore/html/HTMLKeygenElement.cpp5
-rw-r--r--WebCore/html/HTMLKeygenElement.h1
-rw-r--r--WebCore/html/HTMLLIElement.h3
-rw-r--r--WebCore/html/HTMLLabelElement.h2
-rw-r--r--WebCore/html/HTMLLinkElement.h3
-rw-r--r--WebCore/html/HTMLMapElement.cpp6
-rw-r--r--WebCore/html/HTMLMapElement.h4
-rw-r--r--WebCore/html/HTMLMarqueeElement.h3
-rw-r--r--WebCore/html/HTMLMediaElement.cpp6
-rw-r--r--WebCore/html/HTMLMediaElement.h1
-rw-r--r--WebCore/html/HTMLMenuElement.h3
-rw-r--r--WebCore/html/HTMLMetaElement.h3
-rw-r--r--WebCore/html/HTMLMeterElement.cpp2
-rw-r--r--WebCore/html/HTMLModElement.h3
-rw-r--r--WebCore/html/HTMLNoScriptElement.cpp5
-rw-r--r--WebCore/html/HTMLNoScriptElement.h1
-rw-r--r--WebCore/html/HTMLOListElement.h3
-rw-r--r--WebCore/html/HTMLObjectElement.cpp33
-rw-r--r--WebCore/html/HTMLObjectElement.h2
-rw-r--r--WebCore/html/HTMLOptGroupElement.cpp6
-rw-r--r--WebCore/html/HTMLOptGroupElement.h1
-rw-r--r--WebCore/html/HTMLOptionElement.cpp5
-rw-r--r--WebCore/html/HTMLOptionElement.h3
-rw-r--r--WebCore/html/HTMLParagraphElement.cpp5
-rw-r--r--WebCore/html/HTMLParagraphElement.h4
-rw-r--r--WebCore/html/HTMLParamElement.h8
-rw-r--r--WebCore/html/HTMLParserScheduler.h8
-rw-r--r--WebCore/html/HTMLPlugInElement.cpp5
-rw-r--r--WebCore/html/HTMLPlugInElement.h3
-rw-r--r--WebCore/html/HTMLPreElement.h3
-rw-r--r--WebCore/html/HTMLPreloadScanner.cpp10
-rw-r--r--WebCore/html/HTMLPreloadScanner.h6
-rw-r--r--WebCore/html/HTMLProgressElement.cpp2
-rw-r--r--WebCore/html/HTMLQuoteElement.h3
-rw-r--r--WebCore/html/HTMLScriptElement.h4
-rw-r--r--WebCore/html/HTMLScriptRunner.cpp9
-rw-r--r--WebCore/html/HTMLScriptRunner.h9
-rw-r--r--WebCore/html/HTMLSelectElement.cpp7
-rw-r--r--WebCore/html/HTMLSelectElement.h3
-rw-r--r--WebCore/html/HTMLSourceElement.h3
-rw-r--r--WebCore/html/HTMLStyleElement.h4
-rw-r--r--WebCore/html/HTMLTableCaptionElement.h3
-rw-r--r--WebCore/html/HTMLTableCellElement.h3
-rw-r--r--WebCore/html/HTMLTableColElement.cpp20
-rw-r--r--WebCore/html/HTMLTableColElement.h3
-rw-r--r--WebCore/html/HTMLTableElement.cpp25
-rw-r--r--WebCore/html/HTMLTableElement.h6
-rw-r--r--WebCore/html/HTMLTableRowElement.cpp22
-rw-r--r--WebCore/html/HTMLTableRowElement.h6
-rw-r--r--WebCore/html/HTMLTableSectionElement.cpp22
-rw-r--r--WebCore/html/HTMLTableSectionElement.h5
-rw-r--r--WebCore/html/HTMLTextAreaElement.h2
-rw-r--r--WebCore/html/HTMLTitleElement.h2
-rw-r--r--WebCore/html/HTMLToken.h2
-rw-r--r--WebCore/html/HTMLTokenizer.h5
-rw-r--r--WebCore/html/HTMLTreeBuilder.cpp260
-rw-r--r--WebCore/html/HTMLTreeBuilder.h53
-rw-r--r--WebCore/html/HTMLUListElement.h3
-rw-r--r--WebCore/html/HTMLVideoElement.cpp4
-rw-r--r--WebCore/html/HTMLVideoElement.h1
-rw-r--r--WebCore/html/HTMLViewSourceDocument.cpp4
-rw-r--r--WebCore/html/HTMLViewSourceDocument.h2
-rw-r--r--WebCore/html/HTMLViewSourceParser.cpp14
-rw-r--r--WebCore/html/HTMLViewSourceParser.h13
-rw-r--r--WebCore/html/LegacyHTMLTreeBuilder.cpp1786
-rw-r--r--WebCore/html/LegacyHTMLTreeBuilder.h306
-rw-r--r--WebCore/html/StepRange.cpp2
-rw-r--r--WebCore/html/ThreadableBlobRegistry.cpp6
-rw-r--r--WebCore/html/ValidityState.cpp2
-rw-r--r--WebCore/html/ValidityState.h2
-rw-r--r--WebCore/html/canvas/CanvasRenderingContext.cpp13
-rw-r--r--WebCore/html/canvas/CanvasRenderingContext.h1
-rw-r--r--WebCore/html/canvas/CanvasRenderingContext2D.cpp28
-rw-r--r--WebCore/html/canvas/Float32Array.cpp2
-rw-r--r--WebCore/html/canvas/Float32Array.h2
-rw-r--r--WebCore/html/canvas/TypedArrayBase.h2
-rw-r--r--WebCore/html/canvas/WebGLBuffer.cpp1
-rw-r--r--WebCore/html/canvas/WebGLBuffer.h1
-rw-r--r--WebCore/html/canvas/WebGLFramebuffer.cpp2
-rw-r--r--WebCore/html/canvas/WebGLRenderingContext.cpp347
-rw-r--r--WebCore/html/canvas/WebGLRenderingContext.h23
-rw-r--r--WebCore/html/canvas/WebGLRenderingContext.idl345
-rw-r--r--WebCore/html/canvas/WebGLTexture.cpp5
-rw-r--r--WebCore/html/canvas/WebGLTexture.h2
-rw-r--r--WebCore/inspector/CodeGeneratorInspector.pm290
-rw-r--r--WebCore/inspector/ConsoleMessage.cpp6
-rw-r--r--WebCore/inspector/ConsoleMessage.h6
-rw-r--r--WebCore/inspector/InjectedScript.h1
-rw-r--r--WebCore/inspector/InjectedScriptHost.cpp14
-rw-r--r--WebCore/inspector/InjectedScriptHost.h6
-rw-r--r--WebCore/inspector/Inspector.idl22
-rw-r--r--WebCore/inspector/InspectorApplicationCacheAgent.cpp4
-rw-r--r--WebCore/inspector/InspectorApplicationCacheAgent.h6
-rw-r--r--WebCore/inspector/InspectorBackend.cpp8
-rw-r--r--WebCore/inspector/InspectorBackend.h3
-rw-r--r--WebCore/inspector/InspectorCSSStore.cpp1
-rw-r--r--WebCore/inspector/InspectorCSSStore.h1
-rw-r--r--WebCore/inspector/InspectorController.cpp418
-rw-r--r--WebCore/inspector/InspectorController.h42
-rw-r--r--WebCore/inspector/InspectorDOMAgent.cpp136
-rw-r--r--WebCore/inspector/InspectorDOMAgent.h18
-rw-r--r--WebCore/inspector/InspectorDOMStorageResource.cpp4
-rw-r--r--WebCore/inspector/InspectorDOMStorageResource.h6
-rw-r--r--WebCore/inspector/InspectorDatabaseResource.cpp4
-rw-r--r--WebCore/inspector/InspectorDatabaseResource.h4
-rw-r--r--WebCore/inspector/InspectorDebuggerAgent.cpp24
-rw-r--r--WebCore/inspector/InspectorDebuggerAgent.h8
-rw-r--r--WebCore/inspector/InspectorFrontendClientLocal.cpp3
-rw-r--r--WebCore/inspector/InspectorFrontendHost.cpp6
-rw-r--r--WebCore/inspector/InspectorProfilerAgent.cpp210
-rw-r--r--WebCore/inspector/InspectorProfilerAgent.h93
-rw-r--r--WebCore/inspector/InspectorResource.cpp6
-rw-r--r--WebCore/inspector/InspectorResource.h6
-rw-r--r--WebCore/inspector/InspectorStorageAgent.cpp4
-rw-r--r--WebCore/inspector/InspectorStorageAgent.h10
-rw-r--r--WebCore/inspector/InspectorTimelineAgent.cpp6
-rw-r--r--WebCore/inspector/InspectorTimelineAgent.h8
-rw-r--r--WebCore/inspector/InspectorValues.h6
-rw-r--r--WebCore/inspector/front-end/BreakpointManager.js57
-rw-r--r--WebCore/inspector/front-end/BreakpointsSidebarPane.js197
-rw-r--r--WebCore/inspector/front-end/CSSCompletions.js34
-rw-r--r--WebCore/inspector/front-end/Callback.js3
-rw-r--r--WebCore/inspector/front-end/ConsoleView.js4
-rw-r--r--WebCore/inspector/front-end/ContextMenu.js13
-rw-r--r--WebCore/inspector/front-end/DOMAgent.js91
-rw-r--r--WebCore/inspector/front-end/ElementsPanel.js12
-rw-r--r--WebCore/inspector/front-end/ElementsTreeOutline.js17
-rw-r--r--WebCore/inspector/front-end/ExtensionAPI.js2
-rw-r--r--WebCore/inspector/front-end/Panel.js23
-rw-r--r--WebCore/inspector/front-end/ProfilesPanel.js19
-rw-r--r--WebCore/inspector/front-end/ResourcesPanel.js5
-rw-r--r--WebCore/inspector/front-end/ScriptView.js3
-rw-r--r--WebCore/inspector/front-end/ScriptsPanel.js108
-rw-r--r--WebCore/inspector/front-end/Section.js23
-rw-r--r--WebCore/inspector/front-end/Settings.js58
-rw-r--r--WebCore/inspector/front-end/SourceCSSTokenizer.js56
-rw-r--r--WebCore/inspector/front-end/SourceCSSTokenizer.re2js54
-rw-r--r--WebCore/inspector/front-end/SourceFrame.js28
-rw-r--r--WebCore/inspector/front-end/SourceView.js9
-rw-r--r--WebCore/inspector/front-end/StylesSidebarPane.js273
-rw-r--r--WebCore/inspector/front-end/inspector.css6
-rw-r--r--WebCore/inspector/front-end/inspector.js100
-rw-r--r--WebCore/loader/Cache.cpp9
-rw-r--r--WebCore/loader/Cache.h3
-rw-r--r--WebCore/loader/CachedMetadata.h2
-rw-r--r--WebCore/loader/CachedResource.h3
-rw-r--r--WebCore/loader/CachedResourceClient.h12
-rw-r--r--WebCore/loader/CachedXBLDocument.cpp110
-rw-r--r--WebCore/loader/CachedXBLDocument.h65
-rw-r--r--WebCore/loader/DocLoader.cpp25
-rw-r--r--WebCore/loader/DocLoader.h3
-rw-r--r--WebCore/loader/FTPDirectoryDocument.cpp11
-rw-r--r--WebCore/loader/FTPDirectoryDocument.h2
-rw-r--r--WebCore/loader/FrameLoader.h2
-rw-r--r--WebCore/loader/ImageDocument.cpp17
-rw-r--r--WebCore/loader/ImageDocument.h2
-rw-r--r--WebCore/loader/MediaDocument.cpp11
-rw-r--r--WebCore/loader/MediaDocument.h2
-rw-r--r--WebCore/loader/PingLoader.cpp73
-rw-r--r--WebCore/loader/PingLoader.h71
-rw-r--r--WebCore/loader/PluginDocument.cpp15
-rw-r--r--WebCore/loader/PluginDocument.h2
-rw-r--r--WebCore/loader/RedirectScheduler.cpp6
-rw-r--r--WebCore/loader/ResourceLoader.cpp9
-rw-r--r--WebCore/loader/ResourceLoader.h3
-rw-r--r--WebCore/loader/SinkDocument.cpp11
-rw-r--r--WebCore/loader/SinkDocument.h2
-rw-r--r--WebCore/loader/SubframeLoader.cpp32
-rw-r--r--WebCore/loader/SubframeLoader.h1
-rw-r--r--WebCore/loader/TextDocument.cpp23
-rw-r--r--WebCore/loader/TextDocument.h4
-rw-r--r--WebCore/loader/icon/IconDatabase.cpp21
-rw-r--r--WebCore/loader/icon/IconDatabase.h5
-rw-r--r--WebCore/loader/loader.cpp10
-rw-r--r--WebCore/manual-tests/indexed-database.html86
-rw-r--r--WebCore/mathml/RenderMathMLFraction.cpp2
-rw-r--r--WebCore/mathml/RenderMathMLUnderOver.cpp24
-rw-r--r--WebCore/notifications/Notification.cpp41
-rw-r--r--WebCore/notifications/Notification.h15
-rw-r--r--WebCore/notifications/NotificationCenter.h4
-rw-r--r--WebCore/page/FocusController.cpp9
-rw-r--r--WebCore/page/Frame.cpp28
-rw-r--r--WebCore/page/Frame.h10
-rw-r--r--WebCore/page/FrameView.cpp31
-rw-r--r--WebCore/page/FrameView.h3
-rw-r--r--WebCore/page/Geolocation.cpp18
-rw-r--r--WebCore/page/Page.cpp2
-rw-r--r--WebCore/page/PageGroup.h1
-rw-r--r--WebCore/page/SecurityOrigin.cpp13
-rw-r--r--WebCore/page/Settings.cpp2
-rw-r--r--WebCore/page/Settings.h12
-rw-r--r--WebCore/page/SpeechInput.cpp4
-rw-r--r--WebCore/page/SpeechInput.h3
-rw-r--r--WebCore/page/SpeechInputClient.h3
-rw-r--r--WebCore/page/brew/FrameBrew.cpp6
-rw-r--r--WebCore/page/chromium/FrameChromium.cpp84
-rw-r--r--WebCore/page/efl/FrameEfl.cpp6
-rw-r--r--WebCore/page/gtk/FrameGtk.cpp6
-rw-r--r--WebCore/page/haiku/FrameHaiku.cpp7
-rw-r--r--WebCore/page/mac/FrameMac.mm4
-rw-r--r--WebCore/page/qt/FrameQt.cpp11
-rw-r--r--WebCore/page/win/FrameCGWin.cpp2
-rw-r--r--WebCore/page/win/FrameCairoWin.cpp2
-rw-r--r--WebCore/page/wince/FrameWince.cpp7
-rw-r--r--WebCore/page/wx/FrameWx.cpp6
-rw-r--r--WebCore/platform/AsyncFileStream.h74
-rw-r--r--WebCore/platform/ContextMenu.cpp4
-rw-r--r--WebCore/platform/Cursor.h9
-rw-r--r--WebCore/platform/FileStream.cpp (renamed from WebCore/html/FileStream.cpp)21
-rw-r--r--WebCore/platform/FileStream.h (renamed from WebCore/html/FileStream.h)19
-rw-r--r--WebCore/platform/FileStreamClient.h (renamed from WebCore/html/FileStreamClient.h)6
-rw-r--r--WebCore/platform/PlatformTouchPoint.h1
-rw-r--r--WebCore/platform/chromium/ChromiumBridge.h4
-rw-r--r--WebCore/platform/chromium/ClipboardChromium.cpp7
-rw-r--r--WebCore/platform/efl/PopupMenuEfl.cpp3
-rw-r--r--WebCore/platform/efl/RenderThemeEfl.cpp23
-rw-r--r--WebCore/platform/efl/RenderThemeEfl.h6
-rw-r--r--WebCore/platform/graphics/GraphicsContext.h8
-rw-r--r--WebCore/platform/graphics/GraphicsContext3D.cpp5
-rw-r--r--WebCore/platform/graphics/GraphicsContext3D.h15
-rw-r--r--WebCore/platform/graphics/ImageSource.cpp5
-rw-r--r--WebCore/platform/graphics/ImageSource.h3
-rw-r--r--WebCore/platform/graphics/MediaPlayer.cpp67
-rw-r--r--WebCore/platform/graphics/cairo/FontCairo.cpp8
-rw-r--r--WebCore/platform/graphics/cairo/GraphicsContextCairo.cpp43
-rw-r--r--WebCore/platform/graphics/cairo/GraphicsContextPlatformPrivateCairo.h1
-rw-r--r--WebCore/platform/graphics/cairo/ImageBufferCairo.cpp15
-rw-r--r--WebCore/platform/graphics/cairo/ImageCairo.cpp14
-rw-r--r--WebCore/platform/graphics/cairo/PlatformRefPtrCairo.cpp (renamed from WebCore/platform/graphics/cairo/GRefPtrCairo.cpp)10
-rw-r--r--WebCore/platform/graphics/cairo/PlatformRefPtrCairo.h (renamed from WebCore/platform/graphics/cairo/GRefPtrCairo.h)14
-rw-r--r--WebCore/platform/graphics/cg/ImageSourceCG.cpp4
-rw-r--r--WebCore/platform/graphics/chromium/CanvasLayerChromium.cpp76
-rw-r--r--WebCore/platform/graphics/chromium/CanvasLayerChromium.h27
-rw-r--r--WebCore/platform/graphics/chromium/ContentLayerChromium.cpp301
-rw-r--r--WebCore/platform/graphics/chromium/ContentLayerChromium.h90
-rw-r--r--WebCore/platform/graphics/chromium/GLES2Canvas.cpp66
-rw-r--r--WebCore/platform/graphics/chromium/GLES2Canvas.h2
-rw-r--r--WebCore/platform/graphics/chromium/GraphicsLayerChromium.cpp6
-rw-r--r--WebCore/platform/graphics/chromium/ImageLayerChromium.cpp19
-rw-r--r--WebCore/platform/graphics/chromium/ImageLayerChromium.h8
-rw-r--r--WebCore/platform/graphics/chromium/LayerChromium.cpp331
-rw-r--r--WebCore/platform/graphics/chromium/LayerChromium.h125
-rw-r--r--WebCore/platform/graphics/chromium/LayerRendererChromium.cpp664
-rw-r--r--WebCore/platform/graphics/chromium/LayerRendererChromium.h91
-rwxr-xr-xWebCore/platform/graphics/chromium/TilingData.cpp16
-rw-r--r--WebCore/platform/graphics/chromium/VideoFrameChromium.h81
-rw-r--r--WebCore/platform/graphics/chromium/VideoFrameProvider.h (renamed from WebCore/platform/graphics/chromium/TransformLayerChromium.h)32
-rw-r--r--WebCore/platform/graphics/chromium/VideoLayerChromium.cpp28
-rw-r--r--WebCore/platform/graphics/chromium/VideoLayerChromium.h15
-rw-r--r--WebCore/platform/graphics/filters/FEComposite.cpp2
-rw-r--r--WebCore/platform/graphics/filters/FEGaussianBlur.cpp6
-rw-r--r--WebCore/platform/graphics/filters/FEGaussianBlur.h2
-rw-r--r--WebCore/platform/graphics/gstreamer/GStreamerGWorld.cpp164
-rw-r--r--WebCore/platform/graphics/gstreamer/GStreamerGWorld.h24
-rw-r--r--WebCore/platform/graphics/gstreamer/MediaPlayerPrivateGStreamer.cpp3
-rw-r--r--WebCore/platform/graphics/gstreamer/PlatformVideoWindow.h54
-rw-r--r--WebCore/platform/graphics/gstreamer/PlatformVideoWindowGtk.cpp60
-rw-r--r--WebCore/platform/graphics/gtk/ImageBufferGtk.cpp2
-rw-r--r--WebCore/platform/graphics/mac/FontCustomPlatformData.cpp2
-rw-r--r--WebCore/platform/graphics/mac/FontPlatformDataMac.mm18
-rw-r--r--WebCore/platform/graphics/mac/GraphicsContext3DMac.mm42
-rw-r--r--WebCore/platform/graphics/mac/GraphicsLayerCA.mm15
-rw-r--r--WebCore/platform/graphics/qt/ContextShadow.cpp162
-rw-r--r--WebCore/platform/graphics/qt/ContextShadow.h33
-rw-r--r--WebCore/platform/graphics/qt/FontQt.cpp82
-rw-r--r--WebCore/platform/graphics/qt/GradientQt.cpp25
-rw-r--r--WebCore/platform/graphics/qt/GraphicsContext3DQt.cpp110
-rw-r--r--WebCore/platform/graphics/qt/GraphicsContextQt.cpp105
-rw-r--r--WebCore/platform/graphics/qt/GraphicsLayerQt.h3
-rw-r--r--WebCore/platform/graphics/qt/ImageBufferQt.cpp12
-rw-r--r--WebCore/platform/graphics/qt/ImageDecoderQt.cpp20
-rw-r--r--WebCore/platform/graphics/qt/ImageDecoderQt.h2
-rw-r--r--WebCore/platform/graphics/qt/TransparencyLayer.h2
-rw-r--r--WebCore/platform/graphics/skia/BitmapImageSingleFrameSkia.h11
-rw-r--r--WebCore/platform/graphics/skia/GraphicsContext3DSkia.cpp32
-rw-r--r--WebCore/platform/graphics/skia/GraphicsContextSkia.cpp4
-rw-r--r--WebCore/platform/graphics/skia/ImageBufferSkia.cpp13
-rw-r--r--WebCore/platform/graphics/skia/ImageSkia.cpp21
-rw-r--r--WebCore/platform/graphics/skia/NativeImageSkia.cpp8
-rw-r--r--WebCore/platform/graphics/skia/NativeImageSkia.h5
-rw-r--r--WebCore/platform/graphics/skia/PlatformContextSkia.cpp8
-rw-r--r--WebCore/platform/graphics/win/FontCustomPlatformDataCairo.cpp8
-rw-r--r--WebCore/platform/graphics/win/FontCustomPlatformDataCairo.h9
-rw-r--r--WebCore/platform/graphics/win/WKCACFLayer.cpp30
-rw-r--r--WebCore/platform/graphics/win/WKCACFLayer.h23
-rwxr-xr-xWebCore/platform/graphics/win/WebTiledLayer.cpp20
-rw-r--r--WebCore/platform/graphics/win/WebTiledLayer.h4
-rw-r--r--WebCore/platform/gtk/ClipboardGtk.cpp2
-rw-r--r--WebCore/platform/gtk/CursorGtk.cpp70
-rw-r--r--WebCore/platform/gtk/CursorGtk.h50
-rw-r--r--WebCore/platform/gtk/DataObjectGtk.h4
-rw-r--r--WebCore/platform/gtk/GRefPtrGtk.cpp8
-rw-r--r--WebCore/platform/gtk/GRefPtrGtk.h8
-rw-r--r--WebCore/platform/gtk/GtkVersioning.h2
-rw-r--r--WebCore/platform/gtk/PasteboardGtk.cpp2
-rw-r--r--WebCore/platform/gtk/PasteboardHelper.cpp2
-rw-r--r--WebCore/platform/gtk/PopupMenuGtk.h2
-rw-r--r--WebCore/platform/gtk/RenderThemeGtk.cpp6
-rw-r--r--WebCore/platform/gtk/RenderThemeGtk.h2
-rw-r--r--WebCore/platform/gtk/ScrollViewGtk.cpp18
-rw-r--r--WebCore/platform/gtk/ScrollbarGtk.cpp18
-rw-r--r--WebCore/platform/gtk/gtk2drawing.c54
-rw-r--r--WebCore/platform/gtk/gtkdrawing.h3
-rw-r--r--WebCore/platform/image-decoders/ImageDecoder.cpp16
-rw-r--r--WebCore/platform/image-decoders/ImageDecoder.h18
-rw-r--r--WebCore/platform/image-decoders/bmp/BMPImageDecoder.cpp9
-rw-r--r--WebCore/platform/image-decoders/bmp/BMPImageDecoder.h2
-rw-r--r--WebCore/platform/image-decoders/gif/GIFImageDecoder.cpp7
-rw-r--r--WebCore/platform/image-decoders/gif/GIFImageDecoder.h2
-rw-r--r--WebCore/platform/image-decoders/ico/ICOImageDecoder.cpp12
-rw-r--r--WebCore/platform/image-decoders/ico/ICOImageDecoder.h2
-rw-r--r--WebCore/platform/image-decoders/jpeg/JPEGImageDecoder.cpp7
-rw-r--r--WebCore/platform/image-decoders/jpeg/JPEGImageDecoder.h2
-rw-r--r--WebCore/platform/image-decoders/png/PNGImageDecoder.cpp9
-rw-r--r--WebCore/platform/image-decoders/png/PNGImageDecoder.h2
-rw-r--r--WebCore/platform/image-decoders/skia/ImageDecoderSkia.cpp2
-rw-r--r--WebCore/platform/mock/SpeechInputClientMock.cpp2
-rw-r--r--WebCore/platform/mock/SpeechInputClientMock.h2
-rw-r--r--WebCore/platform/network/BlobData.cpp5
-rw-r--r--WebCore/platform/network/BlobData.h28
-rw-r--r--WebCore/platform/network/BlobRegistry.h11
-rw-r--r--WebCore/platform/network/BlobRegistryImpl.cpp62
-rw-r--r--WebCore/platform/network/BlobRegistryImpl.h4
-rw-r--r--WebCore/platform/network/BlobResourceHandle.cpp589
-rw-r--r--WebCore/platform/network/BlobResourceHandle.h116
-rw-r--r--WebCore/platform/network/BlobStorageData.h69
-rw-r--r--WebCore/platform/network/CredentialStorage.cpp1
-rw-r--r--WebCore/platform/network/FormData.cpp10
-rw-r--r--WebCore/platform/network/FormData.h24
-rw-r--r--WebCore/platform/network/HTTPParsers.cpp57
-rw-r--r--WebCore/platform/network/HTTPParsers.h3
-rw-r--r--WebCore/platform/network/ResourceHandle.cpp9
-rw-r--r--WebCore/platform/network/ResourceHandle.h3
-rw-r--r--WebCore/platform/network/ResourceHandleClient.h5
-rw-r--r--WebCore/platform/network/ResourceHandleInternal.h2
-rw-r--r--WebCore/platform/network/mac/ResourceHandleMac.mm7
-rw-r--r--WebCore/platform/network/win/ResourceHandleWin.cpp168
-rw-r--r--WebCore/platform/qt/CursorQt.cpp444
-rw-r--r--WebCore/platform/qt/PasteboardQt.cpp5
-rw-r--r--WebCore/platform/qt/WidgetQt.cpp8
-rw-r--r--WebCore/platform/sql/SQLiteStatement.cpp20
-rw-r--r--WebCore/platform/sql/SQLiteStatement.h2
-rw-r--r--WebCore/platform/text/TextCodecLatin1.cpp2
-rw-r--r--WebCore/platform/text/qt/TextCodecQt.cpp2
-rw-r--r--WebCore/platform/win/BitmapInfo.cpp13
-rw-r--r--WebCore/platform/win/BitmapInfo.h21
-rw-r--r--WebCore/platform/win/PopupMenuWin.cpp2
-rw-r--r--WebCore/plugins/PluginView.cpp4
-rw-r--r--WebCore/plugins/PluginView.h30
-rw-r--r--WebCore/plugins/PluginViewNone.cpp8
-rw-r--r--WebCore/plugins/gtk/gtk2xtbin.c11
-rw-r--r--WebCore/plugins/qt/PluginPackageQt.cpp63
-rw-r--r--WebCore/plugins/qt/PluginViewQt.cpp57
-rw-r--r--WebCore/rendering/HitTestResult.cpp4
-rw-r--r--WebCore/rendering/InlineTextBox.cpp8
-rw-r--r--WebCore/rendering/MediaControlElements.cpp8
-rw-r--r--WebCore/rendering/MediaControlElements.h2
-rw-r--r--WebCore/rendering/PaintInfo.h6
-rw-r--r--WebCore/rendering/RenderBlock.cpp4
-rw-r--r--WebCore/rendering/RenderCounter.cpp5
-rw-r--r--WebCore/rendering/RenderLayer.cpp6
-rw-r--r--WebCore/rendering/RenderLayer.h2
-rw-r--r--WebCore/rendering/RenderLayerBacking.cpp2
-rw-r--r--WebCore/rendering/RenderLayerCompositor.cpp28
-rw-r--r--WebCore/rendering/RenderLayerCompositor.h10
-rw-r--r--WebCore/rendering/RenderListMarker.cpp131
-rw-r--r--WebCore/rendering/RenderMeter.cpp4
-rw-r--r--WebCore/rendering/RenderObject.cpp5
-rw-r--r--WebCore/rendering/RenderPath.cpp56
-rw-r--r--WebCore/rendering/RenderPath.h1
-rw-r--r--WebCore/rendering/RenderProgress.cpp2
-rw-r--r--WebCore/rendering/RenderSVGResourceClipper.cpp74
-rw-r--r--WebCore/rendering/RenderSVGResourceClipper.h2
-rw-r--r--WebCore/rendering/RenderSVGResourceContainer.cpp2
-rw-r--r--WebCore/rendering/RenderSVGResourceGradient.cpp36
-rw-r--r--WebCore/rendering/RenderSVGResourceMasker.cpp48
-rw-r--r--WebCore/rendering/RenderSVGResourceMasker.h2
-rw-r--r--WebCore/rendering/RenderSVGResourcePattern.cpp232
-rw-r--r--WebCore/rendering/RenderSVGResourcePattern.h9
-rw-r--r--WebCore/rendering/RenderSlider.cpp12
-rw-r--r--WebCore/rendering/RenderTextControl.cpp2
-rw-r--r--WebCore/rendering/RenderTextControlSingleLine.cpp12
-rw-r--r--WebCore/rendering/RenderView.h17
-rw-r--r--WebCore/rendering/SVGImageBufferTools.cpp102
-rw-r--r--WebCore/rendering/SVGImageBufferTools.h10
-rw-r--r--WebCore/rendering/SVGInlineTextBox.cpp4
-rw-r--r--WebCore/rendering/SVGRenderSupport.cpp42
-rw-r--r--WebCore/rendering/SVGRenderSupport.h5
-rw-r--r--WebCore/rendering/SVGShadowTreeElements.cpp2
-rw-r--r--WebCore/rendering/SVGShadowTreeElements.h6
-rw-r--r--WebCore/rendering/ShadowElement.cpp10
-rw-r--r--WebCore/rendering/ShadowElement.h18
-rw-r--r--WebCore/rendering/TextControlInnerElements.cpp84
-rw-r--r--WebCore/rendering/TextControlInnerElements.h28
-rw-r--r--WebCore/rendering/style/BindingURI.cpp71
-rw-r--r--WebCore/rendering/style/BindingURI.h59
-rw-r--r--WebCore/rendering/style/RenderStyle.cpp14
-rw-r--r--WebCore/rendering/style/RenderStyle.h13
-rw-r--r--WebCore/rendering/style/SVGRenderStyle.cpp4
-rw-r--r--WebCore/rendering/style/StyleRareNonInheritedData.cpp21
-rw-r--r--WebCore/rendering/style/StyleRareNonInheritedData.h12
-rw-r--r--WebCore/storage/DOMFilePath.cpp166
-rw-r--r--WebCore/storage/DOMFilePath.h86
-rw-r--r--WebCore/storage/Database.cpp6
-rw-r--r--WebCore/storage/DatabaseSync.cpp2
-rw-r--r--WebCore/storage/DatabaseTask.h8
-rw-r--r--WebCore/storage/DatabaseThread.cpp4
-rw-r--r--WebCore/storage/DatabaseTracker.cpp4
-rw-r--r--WebCore/storage/EntryCallback.h1
-rw-r--r--WebCore/storage/FileSystemCallback.h1
-rw-r--r--WebCore/storage/FileSystemCallbacks.cpp200
-rw-r--r--WebCore/storage/FileSystemCallbacks.h138
-rw-r--r--WebCore/storage/IDBAbortEvent.cpp55
-rw-r--r--WebCore/storage/IDBAbortEvent.h57
-rw-r--r--WebCore/storage/IDBCursorBackendImpl.cpp1
-rw-r--r--WebCore/storage/IDBDatabase.cpp5
-rw-r--r--WebCore/storage/IDBDatabase.h3
-rw-r--r--WebCore/storage/IDBDatabase.idl1
-rw-r--r--WebCore/storage/IDBDatabaseBackendImpl.cpp65
-rw-r--r--WebCore/storage/IDBDatabaseBackendImpl.h16
-rw-r--r--WebCore/storage/IDBDatabaseBackendInterface.h1
-rw-r--r--WebCore/storage/IDBFactoryBackendImpl.cpp31
-rw-r--r--WebCore/storage/IDBFactoryBackendImpl.h4
-rw-r--r--WebCore/storage/IDBFactoryBackendInterface.h2
-rw-r--r--WebCore/storage/IDBIndexBackendImpl.cpp15
-rw-r--r--WebCore/storage/IDBIndexBackendImpl.h14
-rw-r--r--WebCore/storage/IDBKeyPathBackendImpl.cpp36
-rw-r--r--WebCore/storage/IDBKeyPathBackendImpl.h47
-rwxr-xr-xWebCore/storage/IDBObjectStoreBackendImpl.cpp209
-rw-r--r--WebCore/storage/IDBObjectStoreBackendImpl.h21
-rw-r--r--WebCore/storage/IDBPendingTransactionMonitor.cpp72
-rw-r--r--WebCore/storage/IDBPendingTransactionMonitor.h63
-rw-r--r--WebCore/storage/IDBTransaction.cpp63
-rw-r--r--WebCore/storage/IDBTransaction.h19
-rwxr-xr-xWebCore/storage/IDBTransactionBackendImpl.cpp70
-rwxr-xr-xWebCore/storage/IDBTransactionBackendImpl.h68
-rw-r--r--WebCore/storage/IDBTransactionBackendInterface.h4
-rw-r--r--WebCore/storage/IDBTransactionCallbacks.h52
-rw-r--r--WebCore/storage/IDBTransactionCoordinator.cpp69
-rw-r--r--WebCore/storage/IDBTransactionCoordinator.h73
-rw-r--r--WebCore/storage/LocalStorageTask.h8
-rw-r--r--WebCore/storage/LocalStorageThread.cpp2
-rw-r--r--WebCore/storage/SQLTransaction.cpp3
-rw-r--r--WebCore/storage/SQLTransactionSync.cpp4
-rw-r--r--WebCore/storage/StorageNamespaceImpl.cpp4
-rw-r--r--WebCore/storage/chromium/IDBKeyPathBackendImpl.cpp42
-rw-r--r--WebCore/svg/SVGElement.cpp11
-rw-r--r--WebCore/svg/SVGFEImageElement.cpp5
-rw-r--r--WebCore/svg/SVGLength.cpp3
-rw-r--r--WebCore/svg/SVGLocatable.cpp16
-rw-r--r--WebCore/svg/SVGLocatable.h14
-rw-r--r--WebCore/svg/SVGPathBuilder.cpp2
-rw-r--r--WebCore/svg/SVGSVGElement.cpp3
-rw-r--r--WebCore/svg/SVGStyledElement.cpp2
-rw-r--r--WebCore/svg/SVGStyledLocatableElement.cpp12
-rw-r--r--WebCore/svg/SVGStyledLocatableElement.h6
-rw-r--r--WebCore/svg/SVGStyledTransformableElement.cpp12
-rw-r--r--WebCore/svg/SVGStyledTransformableElement.h6
-rw-r--r--WebCore/svg/SVGTextElement.cpp12
-rw-r--r--WebCore/svg/SVGTextElement.h6
-rw-r--r--WebCore/xml/XSLTProcessor.cpp14
630 files changed, 17377 insertions, 9216 deletions
diff --git a/WebCore/Android.mk b/WebCore/Android.mk
index ca8c31f..4a26314 100644
--- a/WebCore/Android.mk
+++ b/WebCore/Android.mk
@@ -129,6 +129,7 @@ LOCAL_SRC_FILES := $(LOCAL_SRC_FILES) \
dom/DeviceMotionEvent.cpp \
dom/Document.cpp \
dom/DocumentFragment.cpp \
+ dom/DocumentMarkerController.cpp \
dom/DocumentParser.cpp \
dom/DocumentType.cpp \
dom/DynamicNodeList.cpp \
@@ -344,6 +345,7 @@ LOCAL_SRC_FILES := $(LOCAL_SRC_FILES) \
loader/MediaDocument.cpp \
loader/NavigationAction.cpp \
loader/NetscapePlugInStreamLoader.cpp \
+ loader/PingLoader.cpp \
loader/PlaceholderDocument.cpp \
loader/PluginDocument.cpp \
loader/PolicyCallback.cpp \
@@ -438,6 +440,7 @@ LOCAL_SRC_FILES := $(LOCAL_SRC_FILES) \
platform/DragData.cpp \
platform/DragImage.cpp \
platform/FileChooser.cpp \
+ platform/FileStream.cpp \
platform/FileSystem.cpp \
platform/GeolocationService.cpp \
platform/KURL.cpp \
@@ -580,6 +583,7 @@ LOCAL_SRC_FILES := $(LOCAL_SRC_FILES) \
platform/network/AuthenticationChallengeBase.cpp \
platform/network/BlobData.cpp \
platform/network/BlobRegistryImpl.cpp \
+ platform/network/BlobResourceHandle.cpp \
platform/network/Credential.cpp \
platform/network/CredentialStorage.cpp \
platform/network/FormData.cpp \
@@ -783,7 +787,6 @@ LOCAL_SRC_FILES := $(LOCAL_SRC_FILES) \
rendering/TransformState.cpp \
rendering/break_lines.cpp \
\
- rendering/style/BindingURI.cpp \
rendering/style/ContentData.cpp \
rendering/style/CounterDirectives.cpp \
rendering/style/FillLayer.cpp \
diff --git a/WebCore/CMakeLists.txt b/WebCore/CMakeLists.txt
index 2940015..6dbf082 100644
--- a/WebCore/CMakeLists.txt
+++ b/WebCore/CMakeLists.txt
@@ -198,6 +198,7 @@ SET(WebCore_IDL_FILES
html/File.idl
html/FileList.idl
html/FileReader.idl
+ html/FileWriter.idl
html/HTMLAllCollection.idl
html/HTMLAnchorElement.idl
html/HTMLAppletElement.idl
@@ -809,6 +810,7 @@ SET(WebCore_SOURCES
dom/DeviceOrientationController.cpp
dom/DeviceOrientationEvent.cpp
dom/Document.cpp
+ dom/DocumentMarkerController.cpp
dom/DocumentFragment.cpp
dom/DocumentParser.cpp
dom/DocumentType.cpp
@@ -1023,7 +1025,6 @@ SET(WebCore_SOURCES
html/HTMLOptionsCollection.cpp
html/HTMLParagraphElement.cpp
html/HTMLParamElement.cpp
- html/LegacyHTMLTreeBuilder.cpp
html/HTMLParserErrorCodes.cpp
html/HTMLParserScheduler.cpp
html/HTMLPlugInElement.cpp
@@ -1073,6 +1074,7 @@ SET(WebCore_SOURCES
inspector/InspectorDebuggerAgent.cpp
inspector/InspectorFrontendClientLocal.cpp
inspector/InspectorFrontendHost.cpp
+ inspector/InspectorProfilerAgent.cpp
inspector/InspectorResource.cpp
inspector/InspectorValues.cpp
inspector/InspectorStorageAgent.cpp
@@ -1108,6 +1110,7 @@ SET(WebCore_SOURCES
loader/MediaDocument.cpp
loader/NavigationAction.cpp
loader/NetscapePlugInStreamLoader.cpp
+ loader/PingLoader.cpp
loader/PlaceholderDocument.cpp
loader/PluginDocument.cpp
loader/PolicyCallback.cpp
@@ -1306,6 +1309,7 @@ SET(WebCore_SOURCES
platform/network/AuthenticationChallengeBase.cpp
platform/network/BlobData.cpp
platform/network/BlobRegistryImpl.cpp
+ platform/network/BlobResourceHandle.cpp
platform/network/Credential.cpp
platform/network/FormData.cpp
platform/network/FormDataBuilder.cpp
@@ -1423,7 +1427,6 @@ SET(WebCore_SOURCES
rendering/TextControlInnerElements.cpp
rendering/TransformState.cpp
rendering/break_lines.cpp
- rendering/style/BindingURI.cpp
rendering/style/ContentData.cpp
rendering/style/CounterDirectives.cpp
rendering/style/FillLayer.cpp
@@ -1455,10 +1458,12 @@ SET(WebCore_SOURCES
storage/DatabaseTracker.cpp
storage/DirectoryEntry.cpp
storage/DirectoryReader.cpp
+ storage/DOMFilePath.cpp
storage/DOMFileSystem.cpp
storage/Entry.cpp
storage/EntryArray.cpp
storage/FileEntry.cpp
+ storage/FileSystemCallbacks.cpp
storage/IDBAny.cpp
storage/IDBDatabase.cpp
storage/IDBDatabaseBackendImpl.cpp
diff --git a/WebCore/CMakeListsEfl.txt b/WebCore/CMakeListsEfl.txt
index 5c8cdf2..b58982d 100644
--- a/WebCore/CMakeListsEfl.txt
+++ b/WebCore/CMakeListsEfl.txt
@@ -70,7 +70,7 @@ IF (WTF_PLATFORM_CAIRO)
platform/graphics/cairo/FontCustomPlatformData.cpp
platform/graphics/cairo/FontPlatformDataCairo.cpp
platform/graphics/cairo/GOwnPtrCairo.cpp
- platform/graphics/cairo/GRefPtrCairo.cpp
+ platform/graphics/cairo/PlatformRefPtrCairo.cpp
platform/graphics/cairo/GlyphPageTreeNodeCairo.cpp
platform/graphics/cairo/GradientCairo.cpp
platform/graphics/cairo/GraphicsContextCairo.cpp
diff --git a/WebCore/ChangeLog b/WebCore/ChangeLog
index a107c10..90f722c 100644
--- a/WebCore/ChangeLog
+++ b/WebCore/ChangeLog
@@ -1,3 +1,5325 @@
+2010-08-25 Sheriff Bot <webkit.review.bot@gmail.com>
+
+ Unreviewed, rolling out r66074.
+ http://trac.webkit.org/changeset/66074
+ https://bugs.webkit.org/show_bug.cgi?id=44660
+
+ Chromium canary turned red (Requested by yuzo on #webkit).
+
+ * bindings/generic/RuntimeEnabledFeatures.cpp:
+ * bindings/generic/RuntimeEnabledFeatures.h:
+ * bindings/js/JSXMLHttpRequestCustom.cpp:
+ (WebCore::JSXMLHttpRequest::responseText):
+ * bindings/v8/custom/V8XMLHttpRequestCustom.cpp:
+ (WebCore::V8XMLHttpRequest::responseTextAccessorGetter):
+ * xml/XMLHttpRequest.cpp:
+ (WebCore::XMLHttpRequest::responseText):
+ (WebCore::XMLHttpRequest::responseXML):
+ (WebCore::XMLHttpRequest::open):
+ (WebCore::XMLHttpRequest::abort):
+ (WebCore::XMLHttpRequest::clearResponse):
+ (WebCore::XMLHttpRequest::didFinishLoading):
+ * xml/XMLHttpRequest.h:
+ * xml/XMLHttpRequest.idl:
+
+2010-08-25 Mark Rowe <mrowe@apple.com>
+
+ Reviewed by Dan Bernstein.
+
+ <rdar://problem/8205479> WebCore's icon database often prevents Safari from being killable via sudden termination
+
+ We need to ensure that each call to disableSuddenTermination is balanced by a corresponding call to enableSuddenTermination.
+ It's possbile for several calls to IconDatabase::wakeSyncThread to correspond to only a single iteration of the loop within
+ IconDatabase::syncThreadMainLoop. This results in the sudden termination disable count growing without bound rather than
+ being balanced when the work completes. We can prevent this by ensuring that we only disable sudden termination once for each
+ corresponding iteration of the sync thread's main loop.
+
+ * loader/icon/IconDatabase.cpp:
+ (WebCore::IconDatabase::IconDatabase):
+ (WebCore::IconDatabase::wakeSyncThread): Only disable sudden termination if it has not yet been disabled for this iteration of
+ the sync thread's main loop.
+ (WebCore::IconDatabase::syncThreadMainLoop): Clear the flag indicating that sudden termination has been disabled after reenabling it
+ so that future calls to wakeSyncThread disable sudden termination once more.
+ * loader/icon/IconDatabase.h:
+
+2010-08-25 Michael Nordman <michaeln@google.com>
+
+ Reviewed by David Levin.
+
+ https://bugs.webkit.org/show_bug.cgi?id=44133
+ IDL bindings for XmlHttpRequest.responseBlob support, doesn't do anything yet.
+ Adds two new attributes, asBlob and responseBlob.
+ Runtime disabled by default, also behind a new ENABLE_XHR_RESPONSE_BLOB compile time guard.
+
+ No new tests, just adding some stubs.
+
+ * bindings/generic/RuntimeEnabledFeatures.cpp:
+ * bindings/generic/RuntimeEnabledFeatures.h:
+ (WebCore::RuntimeEnabledFeatures::setResponseBlobEnabled):
+ (WebCore::RuntimeEnabledFeatures::responseBlobEnabled):
+ (WebCore::RuntimeEnabledFeatures::asBlobEnabled):
+ * bindings/js/JSXMLHttpRequestCustom.cpp:
+ (WebCore::JSXMLHttpRequest::responseText): Changed to allow an exceptional return path.
+ * bindings/v8/custom/V8XMLHttpRequestCustom.cpp:
+ (WebCore::V8XMLHttpRequest::responseTextAccessorGetter): Changed to allow an exceptional return path.
+ * xml/XMLHttpRequest.cpp:
+ (WebCore::XMLHttpRequest::responseText): Changed to raise an exception when accessed with asBlob set to true.
+ (WebCore::XMLHttpRequest::responseXML): Changed to raise an exception when accessed with asBlob set to true.
+ (WebCore::XMLHttpRequest::responseBlob): Added stub method, returns 0 for now.
+ (WebCore::XMLHttpRequest::setAsBlob): Sets the asBlob attribute, raises exception if called at an inappropriate time.
+ (WebCore::XMLHttpRequest::open): Resets asBlob to false, the default value.
+ (WebCore::XMLHttpRequest::abort): Clears m_responseBlob.
+ (WebCore::XMLHttpRequest::clearResponse): Clears m_responseBlob.
+ (WebCore::XMLHttpRequest::didFinishLoading): Added a FIXME to populate m_responseBlob.
+ * xml/XMLHttpRequest.h:
+ (WebCore::XMLHttpRequest::asBlob):
+ * xml/XMLHttpRequest.idl:
+
+2010-08-24 Victoria Kirst <vrk@google.com>
+
+ Reviewed by Darin Fisher.
+
+ Adding a means of communication between WebKit/WebCore and
+ chromium in order to share video frames. This adds the necessary
+ WebKit-side classes and methods, but does not actually use them
+ yet - that will be committed in a separate patch after the
+ corresponding Chromium side is committed.
+
+ https://bugs.webkit.org/show_bug.cgi?id=44539
+
+ No new tests, as these new classes/APIs are not yet used.
+
+ * platform/graphics/chromium/VideoFrameChromium.h: Added.
+ (WebCore::VideoFrameChromium::):
+ * platform/graphics/chromium/VideoFrameProvider.h: Added.
+ * platform/graphics/chromium/VideoLayerChromium.cpp:
+ (WebCore::VideoLayerChromium::create):
+ (WebCore::VideoLayerChromium::VideoLayerChromium):
+ * platform/graphics/chromium/VideoLayerChromium.h:
+
+2010-08-25 Kenneth Russell <kbr@google.com>
+
+ Reviewed by Simon Fraser.
+
+ Source data passed to TypedArray creators should be const
+ https://bugs.webkit.org/show_bug.cgi?id=44649
+
+ Compiled and ran existing WebGL tests to verify.
+
+ * html/canvas/Float32Array.cpp:
+ (WebCore::Float32Array::create):
+ * html/canvas/Float32Array.h:
+ * html/canvas/TypedArrayBase.h:
+ (WebCore::TypedArrayBase::create):
+
+2010-08-25 Eric Seidel <eric@webkit.org>
+
+ Unreviewed, just removing a dead enum.
+
+ Remove endTagRequirement now that the LegacyHTMLDocumentParser is dead
+ https://bugs.webkit.org/show_bug.cgi?id=44626
+
+ Remove HTMLTagStatus since it's not used anymore.
+
+ * html/HTMLElement.h:
+
+2010-08-25 Chris Fleizach <cfleizach@apple.com>
+
+ Reviewed by David Kilzer.
+
+ AX: CSS first letter text transform causes crash
+ https://bugs.webkit.org/show_bug.cgi?id=44352
+
+ Test: accessibility/first-letter-text-transform-causes-crash.html
+
+ * accessibility/AccessibilityRenderObject.cpp:
+ (WebCore::nextContinuation):
+
+2010-08-25 Eric Seidel <eric@webkit.org>
+
+ Reviewed by Adam Barth.
+
+ Remove endTagRequirement now that the LegacyHTMLDocumentParser is dead
+ https://bugs.webkit.org/show_bug.cgi?id=44626
+
+ Serialization is covered by a bunch of tests. innerHTML behavior is sadly not.
+ In either case, this is just moving code and should have no functional change.
+
+ * editing/markup.cpp:
+ (WebCore::elementCannotHaveEndTag):
+ (WebCore::MarkupAccumulator::shouldSelfClose):
+ (WebCore::MarkupAccumulator::appendEndMarkup):
+ (WebCore::serializeNodesWithNamespaces):
+ * html/HTMLAnchorElement.h:
+ * html/HTMLAreaElement.h:
+ * html/HTMLBRElement.h:
+ * html/HTMLBaseElement.h:
+ * html/HTMLBaseFontElement.h:
+ * html/HTMLBlockquoteElement.h:
+ * html/HTMLBodyElement.h:
+ * html/HTMLCanvasElement.cpp:
+ * html/HTMLCanvasElement.h:
+ * html/HTMLDListElement.h:
+ * html/HTMLDataGridCellElement.h:
+ * html/HTMLDataGridColElement.h:
+ * html/HTMLDirectoryElement.h:
+ * html/HTMLDivElement.h:
+ * html/HTMLElement.cpp:
+ (WebCore::HTMLElement::nodeName):
+ (WebCore::HTMLElement::ieForbidsInsertHTML):
+ (WebCore::HTMLElement::deprecatedCreateContextualFragment):
+ (WebCore::HTMLElement::setInnerText):
+ (WebCore::HTMLElement::setOuterText):
+ * html/HTMLElement.h:
+ * html/HTMLEmbedElement.h:
+ * html/HTMLFontElement.h:
+ * html/HTMLFormControlElement.h:
+ * html/HTMLFormElement.h:
+ * html/HTMLFrameElement.h:
+ * html/HTMLFrameSetElement.h:
+ * html/HTMLHRElement.h:
+ * html/HTMLHeadElement.h:
+ * html/HTMLHeadingElement.h:
+ * html/HTMLHtmlElement.h:
+ * html/HTMLIFrameElement.h:
+ * html/HTMLImageElement.h:
+ * html/HTMLInputElement.h:
+ * html/HTMLIsIndexElement.h:
+ * html/HTMLLIElement.h:
+ * html/HTMLLinkElement.h:
+ * html/HTMLMapElement.h:
+ * html/HTMLMarqueeElement.h:
+ * html/HTMLMenuElement.h:
+ * html/HTMLMetaElement.h:
+ * html/HTMLModElement.h:
+ * html/HTMLOListElement.h:
+ * html/HTMLOptionElement.h:
+ * html/HTMLParagraphElement.h:
+ * html/HTMLParamElement.h:
+ * html/HTMLPlugInElement.h:
+ * html/HTMLPreElement.h:
+ * html/HTMLQuoteElement.h:
+ * html/HTMLScriptElement.h:
+ * html/HTMLSourceElement.h:
+ * html/HTMLStyleElement.h:
+ * html/HTMLTableCaptionElement.h:
+ * html/HTMLTableCellElement.h:
+ * html/HTMLTableColElement.cpp:
+ * html/HTMLTableColElement.h:
+ * html/HTMLTableElement.h:
+ * html/HTMLTableRowElement.h:
+ * html/HTMLTableSectionElement.h:
+ * html/HTMLUListElement.h:
+
+2010-08-20 Zhenyao Mo <zmo@google.com>
+
+ Reviewed by Kenneth Russell.
+
+ WebGL must enforce restrictions even if running on OpenGL ES 2.0
+ https://bugs.webkit.org/show_bug.cgi?id=42908
+
+ * html/canvas/WebGLFramebuffer.cpp:
+ (WebCore::WebGLFramebuffer::getColorBufferFormat): Get format at given level instead of 0.
+ * html/canvas/WebGLRenderingContext.cpp: Add two new flags and use them to replace the original isGLES2Compliant().
+ (WebCore::WebGLRenderingContext::WebGLRenderingContext):
+ (WebCore::WebGLRenderingContext::bindTexture):
+ (WebCore::WebGLRenderingContext::blendEquation):
+ (WebCore::WebGLRenderingContext::blendEquationSeparate):
+ (WebCore::WebGLRenderingContext::bufferData):
+ (WebCore::WebGLRenderingContext::bufferSubData):
+ (WebCore::WebGLRenderingContext::checkFramebufferStatus):
+ (WebCore::WebGLRenderingContext::clear):
+ (WebCore::WebGLRenderingContext::copyTexImage2D):
+ (WebCore::WebGLRenderingContext::copyTexSubImage2D):
+ (WebCore::WebGLRenderingContext::disable):
+ (WebCore::WebGLRenderingContext::drawArrays):
+ (WebCore::WebGLRenderingContext::drawElements):
+ (WebCore::WebGLRenderingContext::enable):
+ (WebCore::WebGLRenderingContext::generateMipmap):
+ (WebCore::WebGLRenderingContext::hint):
+ (WebCore::WebGLRenderingContext::isEnabled):
+ (WebCore::WebGLRenderingContext::texImage2DBase):
+ (WebCore::WebGLRenderingContext::texParameter):
+ (WebCore::WebGLRenderingContext::isGLES2NPOTStrict):
+ (WebCore::WebGLRenderingContext::isErrorGeneratedOnOutOfBoundsAccesses):
+ * html/canvas/WebGLRenderingContext.h: Declare two new flags.
+ * html/canvas/WebGLTexture.cpp: Get format at given level instead of 0.
+ (WebCore::WebGLTexture::getInternalFormat):
+ * html/canvas/WebGLTexture.h: Ditto.
+ * platform/graphics/GraphicsContext3D.h: Add three new flags.
+ * platform/graphics/mac/GraphicsContext3DMac.mm: Ditto.
+ (WebCore::GraphicsContext3D::isGLES2NPOTStrict):
+ (WebCore::GraphicsContext3D::isErrorGeneratedOnOutOfBoundsAccesses):
+ * platform/graphics/qt/GraphicsContext3DQt.cpp: Ditto.
+ (WebCore::GraphicsContext3D::isGLES2NPOTStrict):
+ (WebCore::GraphicsContext3D::isErrorGeneratedOnOutOfBoundsAccesses):
+
+2010-08-25 Brent Fulgham <bfulgham@webkit.org>
+
+ Build correction, no review.
+
+ * WebCore.vcproj/WebCore.vcproj: Add missing implementation
+ for PlatformRefPtrCairo.
+
+2010-08-25 Cris Neckar <cdn@chromium.org>
+
+ Reviewed by Darin Adler.
+
+ Added abort condition for RenderCounters when traversing a detached render tree.
+ https://bugs.webkit.org/show_bug.cgi?id=43812
+
+ Test: fast/css/counters/counter-traverse-object-crash.html
+
+ * rendering/RenderCounter.cpp:
+ (WebCore::findPlaceForCounter):
+
+2010-08-25 Chris Marrin <cmarrin@apple.com>
+
+ Reviewed by Simon Fraser.
+
+ https://bugs.webkit.org/show_bug.cgi?id=44629
+ Add layer consistency checking and fix found crashing bug
+
+ The crash was being caused by some of the calls which mutated
+ the sublayer list leaving the list in an inconsistent state.
+ This eventually lead to a crash. It would also lead to visual
+ artifacts if the crash didn't occur. Added consistency checking
+ to catch this and any other inconsistencies in the sublayer list.
+
+ The particular bug in this case was caused by clamping an index
+ for insertion to the current size of the sublayer list. CACF uses
+ an index equal to the current length to indicate an append operation.
+ With tiled layers the apparent size of the list is one less than its
+ actual size (to accomodate the layer which holds the list of tiles)
+ so this clamping was causing the new layer to get inserted before the
+ tile parent. The tile parent was then mistaken for a WKCACFLayer and
+ it eventually tried to deref that layer, causing the crash.
+
+ I also added some protection when destroying a WKCACFLayer. The user data
+ for the corresponding CACFLayer is now changed to 0xDeadBeef rather than
+ null. This allows dangling layers to be more easily identified. This
+ value is checked and ASSERTed if seen. I also remove the sublayers
+ on destruction to make the consistency checks work properly while
+ a layer is being destroyed.
+
+ Test: compositing/tiling/crash-reparent-tiled-layer.html
+
+ * platform/graphics/win/WKCACFLayer.cpp:
+ * platform/graphics/win/WKCACFLayer.h:
+ * platform/graphics/win/WebTiledLayer.cpp:
+ * platform/graphics/win/WebTiledLayer.h:
+
+2010-08-25 Ryosuke Niwa <rniwa@webkit.org>
+
+ Reviewed by Darin Adler.
+
+ WebCore::InsertListCommand::modifyRange infinite loop (100% CPU usage)
+ https://bugs.webkit.org/show_bug.cgi?id=33668
+
+ The bug was caused by enclosingListChild returning a list child whose enclosing list is
+ a sibling of the current list child. Fixed enclosingListChild to traverse upwards
+ in the DOM to find the list child which is a sibling of the current list child.
+ Also fixed adjacentEnclosingList to only returns the list that belongs to the same outer list.
+
+ In doApplyForSingleParagraph, if the start or the end of currentSelection existed inside a list content
+ moved by moveParagraphWithClones, either end could point to a wrong position after the move.
+ Fixed this problem by checking this condition upfront and restoring later.
+
+ In doApply, if moveParagraph or moveParagraphWithClones, endOfSelection or startOfLastParagraph
+ could be null or orphaned, fixed this problem by indexForVisiblePosition.
+
+ Test: editing/execCommand/insert-list-orphaned-item-with-nested-lists.html
+
+ * editing/InsertListCommand.cpp:
+ (WebCore::InsertListCommand::doApply):
+ (WebCore::enclosingListChild):
+ (WebCore::InsertListCommand::doApplyForSingleParagraph):
+ (WebCore::adjacentEnclosingList):
+ (WebCore::InsertListCommand::listifyParagraph):
+
+2010-08-25 Brent Fulgham <bfulgham@webkit.org>
+
+ Build corrections, no review.
+
+ * platform/graphics/cairo/GraphicsContextPlatformPrivateCairo.h:
+ Add include for new (missing) "CairoPath.h" class.
+ * platform/graphics/cairo/PlatformRefPtrCairo.h: Correct
+ include and compilation guards to match coding conventions.
+ * platform/graphics/win/FontCustomPlatformDataCairo.cpp:
+ Change implementation to match CG version, using the
+ FontCustomPlatformData name, rather than the original
+ FontCustomPlatformDataCairo.
+ * platform/graphics/win/FontCustomPlatformDataCairo.h:
+ Same as for the .cpp file.
+
+2010-08-25 Krzysztof Czech <k.czech@samsung.com>
+
+ Reviewed by Kenneth Rohde Christiansen.
+
+ [EFL] Crash while calling PopupMenuEfl destructor
+ https://bugs.webkit.org/show_bug.cgi?id=44497
+
+ Condition checks if m_view is defined
+ before popup is hide
+
+ * platform/efl/PopupMenuEfl.cpp:
+ (WebCore::PopupMenuEfl::~PopupMenuEfl):
+
+2010-08-24 Ryosuke Niwa <rniwa@webkit.org>
+
+ Reviewed by Tony Chang.
+
+ Creating a link when selecting multiple nodes creates multiple links
+ https://bugs.webkit.org/show_bug.cgi?id=30836
+
+ The bug was caused by applyInlineStyleToRange calling addInlineStyleIfNeeded
+ on each inline element. Modified applyInlineStyleToRange to call addInlineStyleIfNeeded
+ once for all inline elements with the same style difference.
+
+ Because this implies that anchor element may wrap other inline elements when added,
+ modified pushDownInlineStyleAroundNode to push down styled elements.
+
+ Removed pushPartiallySelectedAnchorElementsDown from CompositeEditCommand since
+ ApplyStyleCommand now correctly pushes down anchors at the start and the end of the selection.
+
+ Test: editing/execCommand/toggle-link.html
+
+ * editing/ApplyStyleCommand.cpp:
+ (WebCore::StyleChange::operator==): Added.
+ (WebCore::StyleChange::operator!=): Added.
+ (WebCore::ApplyStyleCommand::applyInlineStyleToRange): Wraps inline elements with
+ the same style difference by one element instead of wrapping each element separately.
+ (WebCore::ApplyStyleCommand::extractInlineStyleToPushDown): Extracts styled element.
+ (WebCore::ApplyStyleCommand::applyInlineStyleToPushDown): Avoids adding styled element.
+ (WebCore::ApplyStyleCommand::pushDownInlineStyleAroundNode): Pushes down styled element.
+ (WebCore::ApplyStyleCommand::surroundNodeRangeWithElement): No longer checks inline-ness.
+ (WebCore::ApplyStyleCommand::addInlineStyleIfNeeded): Adds style even when m_removeOnly.
+ Callers should set addStyledElement = DoNotAddStyledElement to avoid adding styled element.
+ * editing/ApplyStyleCommand.h:
+ * editing/CompositeEditCommand.cpp: Removed pushPartiallySelectedAnchorElementsDown.
+ * editing/CompositeEditCommand.h: Removed pushPartiallySelectedAnchorElementsDown.
+ * editing/CreateLinkCommand.cpp:
+ (WebCore::CreateLinkCommand::doApply): used to call pushPartiallySelectedAnchorElementsDown.
+ * editing/UnlinkCommand.cpp:
+ (WebCore::UnlinkCommand::doApply): Used to call pushPartiallySelectedAnchorElementsDown.
+
+2010-08-24 Zhenyao Mo <zmo@google.com>
+
+ Reviewed by Kenneth Russell.
+
+ Passing premultiplyAlpha=false to tex{Sub}Image2D loses information (skia)
+ https://bugs.webkit.org/show_bug.cgi?id=38282
+
+ Test: fast/canvas/webgl/gl-teximage.html
+
+ * platform/graphics/GraphicsContext3D.cpp: Fix a bug where alpha channel is ignored.
+ * platform/graphics/ImageSource.cpp: Add premultiplyAlpha flag.
+ (WebCore::ImageSource::ImageSource):
+ (WebCore::ImageSource::setData):
+ * platform/graphics/ImageSource.h: Ditto.
+ * platform/graphics/cg/ImageSourceCG.cpp: Ditto.
+ (WebCore::ImageSource::ImageSource):
+ * platform/graphics/qt/ImageDecoderQt.cpp: Ditto.
+ (WebCore::ImageDecoder::create):
+ (WebCore::ImageDecoderQt::ImageDecoderQt):
+ (WebCore::ImageDecoderQt::frameCount):
+ (WebCore::ImageDecoderQt::forceLoadEverything):
+ * platform/graphics/qt/ImageDecoderQt.h: Ditto.
+ * platform/graphics/skia/GraphicsContext3DSkia.cpp: Fix the premultiplyAlpha data loss issue in skia.
+ (WebCore::GraphicsContext3D::getImageData):
+ * platform/image-decoders/ImageDecoder.cpp: Add premultiplyAlpha flag.
+ (WebCore::ImageDecoder::create):
+ (WebCore::RGBA32Buffer::RGBA32Buffer):
+ (WebCore::RGBA32Buffer::operator=):
+ * platform/image-decoders/ImageDecoder.h: Ditto.
+ (WebCore::RGBA32Buffer::premultiplyAlpha):
+ (WebCore::RGBA32Buffer::setPremultiplyAlpha):
+ (WebCore::RGBA32Buffer::setRGBA):
+ (WebCore::ImageDecoder::ImageDecoder):
+ * platform/image-decoders/bmp/BMPImageDecoder.cpp: Ditto.
+ (WebCore::BMPImageDecoder::BMPImageDecoder):
+ (WebCore::BMPImageDecoder::frameBufferAtIndex):
+ * platform/image-decoders/bmp/BMPImageDecoder.h: Ditto.
+ * platform/image-decoders/gif/GIFImageDecoder.cpp: Ditto.
+ (WebCore::GIFImageDecoder::GIFImageDecoder):
+ (WebCore::GIFImageDecoder::frameCount):
+ * platform/image-decoders/gif/GIFImageDecoder.h: Ditto.
+ * platform/image-decoders/ico/ICOImageDecoder.cpp: Ditto.
+ (WebCore::ICOImageDecoder::ICOImageDecoder):
+ (WebCore::ICOImageDecoder::frameCount):
+ (WebCore::ICOImageDecoder::decodeAtIndex):
+ * platform/image-decoders/ico/ICOImageDecoder.h: Ditto.
+ * platform/image-decoders/jpeg/JPEGImageDecoder.cpp: Ditto.
+ (WebCore::JPEGImageDecoder::JPEGImageDecoder):
+ (WebCore::JPEGImageDecoder::frameBufferAtIndex):
+ * platform/image-decoders/jpeg/JPEGImageDecoder.h: Ditto.
+ * platform/image-decoders/png/PNGImageDecoder.cpp: Ditto.
+ (WebCore::PNGImageDecoder::PNGImageDecoder):
+ (WebCore::PNGImageDecoder::frameBufferAtIndex):
+ * platform/image-decoders/png/PNGImageDecoder.h: Ditto.
+ * platform/image-decoders/skia/ImageDecoderSkia.cpp: Ditto.
+ (WebCore::RGBA32Buffer::RGBA32Buffer):
+ (WebCore::RGBA32Buffer::operator=):
+
+2010-08-25 Adam Barth <abarth@webkit.org>
+
+ Reviewed by Eric Seidel.
+
+ Remove XBL
+ https://bugs.webkit.org/show_bug.cgi?id=44621
+
+ This patch removes support for XBL. XBL seems cool, but this code is
+ old and pretty bitrotten. If we decide to support XBL in the future,
+ we can recover this code from this revision. As it stands, it doesn't
+ seem worth half-maintaining this code.
+
+ * Android.mk:
+ * CMakeLists.txt:
+ * GNUmakefile.am:
+ * WebCore.gypi:
+ * WebCore.pro:
+ * WebCore.vcproj/WebCore.vcproj:
+ * WebCore.xcodeproj/project.pbxproj:
+ * css/CSSComputedStyleDeclaration.cpp:
+ (WebCore::CSSComputedStyleDeclaration::getPropertyCSSValue):
+ * css/CSSParser.cpp:
+ (WebCore::CSSParser::parseValue):
+ * css/CSSPropertyNames.in:
+ * css/CSSStyleSelector.cpp:
+ (WebCore::CSSStyleSelector::applyProperty):
+ * dom/Document.cpp:
+ (WebCore::Document::Document):
+ (WebCore::Document::~Document):
+ * dom/Document.h:
+ * loader/Cache.cpp:
+ (WebCore::createResource):
+ (WebCore::Cache::getStatistics):
+ * loader/Cache.h:
+ * loader/CachedResource.h:
+ (WebCore::CachedResource::):
+ * loader/CachedResourceClient.h:
+ (WebCore::CachedResourceClient::setXSLStyleSheet):
+ (WebCore::CachedResourceClient::fontLoaded):
+ * loader/CachedXBLDocument.cpp: Removed.
+ * loader/CachedXBLDocument.h: Removed.
+ * loader/DocLoader.cpp:
+ (WebCore::DocLoader::canRequest):
+ * loader/DocLoader.h:
+ * loader/loader.cpp:
+ (WebCore::cachedResourceTypeToTargetType):
+ (WebCore::Loader::determinePriority):
+ * rendering/style/BindingURI.cpp: Removed.
+ * rendering/style/BindingURI.h: Removed.
+ * rendering/style/RenderStyle.cpp:
+ * rendering/style/RenderStyle.h:
+ * rendering/style/StyleRareNonInheritedData.cpp:
+ (WebCore::StyleRareNonInheritedData::StyleRareNonInheritedData):
+ (WebCore::StyleRareNonInheritedData::operator==):
+ * rendering/style/StyleRareNonInheritedData.h:
+
+2010-08-25 Andreas Kling <andreas.kling@nokia.com>
+
+ Reviewed by Ariya Hidayat.
+
+ [Qt] GraphicsContext: Construct with the correct default LineJoin (MiterJoin)
+
+ We weren't setting it explicitly which caused us to use Qt::MiterJoin when
+ we actually want Qt::SvgMiterJoin.
+
+ Fixes display glitches on the "Monster" chrome experiment among other things.
+
+ * platform/graphics/qt/GraphicsContextQt.cpp:
+ (WebCore::GraphicsContext::GraphicsContext):
+
+2010-08-25 Rafael Antognolli <antognolli@profusion.mobi>
+
+ Unreviewed build fix.
+
+ [EFL] Build fix for revision 66024
+ https://bugs.webkit.org/show_bug.cgi?id=44631
+
+ No new features added, so no new tests.
+
+ * CMakeListsEfl.txt: change GRefPtrCairo.cpp by PlatformRefPtrCairo.cpp.
+
+2010-08-25 Ryosuke Niwa <rniwa@webkit.org>
+
+ Reviewed by Darin Adler.
+
+ Various designmode=&quot;on&quot;/&quot;off&quot; &amp; execCommand(&quot;Undo&quot;) NULL pointer crashes
+ https://bugs.webkit.org/show_bug.cgi?id=32823
+
+ The bug was caused by changeSelectionAfterCommand which updates the selection
+ without checking the whether new selection is valid or not.
+
+ Fixed changeSelectionAfterCommand so that it won't update the selection
+ when either end of the new selection is orphaned. Also fixed various editing commands
+ to exit early if either end of the selection is orphaned.
+
+ Tests: editing/undo/orphaned-selection-crash-bug32823-1.html
+ editing/undo/orphaned-selection-crash-bug32823-2.html
+ editing/undo/orphaned-selection-crash-bug32823-3.html
+ editing/undo/orphaned-selection-crash-bug32823-4.html
+
+ * editing/Editor.cpp:
+ (WebCore::Editor::changeSelectionAfterCommand): No longer sets orphaned selection.
+ * editing/VisibleSelection.h:
+ (WebCore::VisibleSelection::isNonOrphanedRange): Added.
+ (WebCore::VisibleSelection::isNonOrphanedCaretOrRange): Added.
+ * editing/DeleteSelectionCommand.cpp:
+ (WebCore::DeleteSelectionCommand::doApply): Added an early exist. See above.
+ * editing/FormatBlockCommand.cpp:
+ (WebCore::FormatBlockCommand::doApply): Ditto.
+ * editing/IndentOutdentCommand.cpp:
+ (WebCore::IndentOutdentCommand::doApply): Ditto.
+ * editing/InsertLineBreakCommand.cpp:
+ (WebCore::InsertLineBreakCommand::doApply): Ditto.
+ * editing/InsertListCommand.cpp:
+ (WebCore::InsertListCommand::doApply): Ditto.
+ * editing/InsertParagraphSeparatorCommand.cpp:
+ (WebCore::InsertParagraphSeparatorCommand::doApply): Ditto.
+ * editing/InsertTextCommand.cpp:
+ (WebCore::InsertTextCommand::input): Ditto.
+ * editing/MoveSelectionCommand.cpp:
+ (WebCore::MoveSelectionCommand::doApply): Ditto.
+ * editing/RemoveFormatCommand.cpp:
+ (WebCore::RemoveFormatCommand::doApply): Ditto.
+ * editing/ReplaceSelectionCommand.cpp:
+ (WebCore::ReplaceSelectionCommand::doApply): Ditto.
+ * editing/TypingCommand.cpp:
+ (WebCore::TypingCommand::doApply): Ditto.
+ * editing/UnlinkCommand.cpp:
+ (WebCore::UnlinkCommand::doApply): Ditto.
+
+2010-08-25 Simon Fraser <simon.fraser@apple.com>
+
+ Reviewed by Dan Bernstein.
+
+ Flash content draws in front of site's drop down menu at http://www.monster.com/
+ https://bugs.webkit.org/show_bug.cgi?id=41330
+
+ If an iframe with composited content became overlapped, we failed to
+ consider that iframe for compositing if it had no RenderLayer, so the layering
+ would be incorrect.
+
+ Overlap is detected at painting time, but it's bad for FrameView::setIsOverlapped()
+ to call setNeedsStyleRecalc(), because this would cause subsequent calls to
+ FrameView::paintContents() in the same painting batch to bail with needsLayout().
+
+ Instead, we do the setNeedsStyleRecalc() from RenderLayerCompositor::notifyIFramesOfCompositingChange(),
+ so that the parent document has a chance to update style, and give the iframe a RenderLayer.
+ Then setIsOverlapped() simply needs to schedule a layer update, which we do on a timer.
+
+ When dumping layers via Frame::layerTreeAsText(), if a layer update is pending, then
+ update the layers.
+
+ Test: compositing/iframes/become-overlapped-iframe.html
+
+ * page/Frame.cpp:
+ (WebCore::Frame::layerTreeAsText):
+ * page/FrameView.cpp:
+ (WebCore::FrameView::setIsOverlapped):
+ * rendering/RenderLayerCompositor.cpp:
+ (WebCore::RenderLayerCompositor::RenderLayerCompositor):
+ (WebCore::RenderLayerCompositor::scheduleCompositingLayerUpdate):
+ (WebCore::RenderLayerCompositor::compositingLayerUpdatePending):
+ (WebCore::RenderLayerCompositor::updateCompositingLayersTimerFired):
+ (WebCore::RenderLayerCompositor::updateCompositingLayers):
+ (WebCore::RenderLayerCompositor::notifyIFramesOfCompositingChange):
+ * rendering/RenderLayerCompositor.h:
+
+2010-08-25 Martin Robinson <mrobinson@igalia.com>
+
+ Reviewed by Gustavo Noronha Silva.
+
+ Cairo and EFL port shouldn't depend on glib.
+ https://bugs.webkit.org/show_bug.cgi?id=44354
+
+ No new tests as functionality has not changed.
+
+ Replace occurrences of GRefPtr and adoptGRef with PlatformRefPtr and
+ adoptPlatformRef. Rename GRefPtrCairo to PlatformRefPtrCairo.
+
+ * GNUmakefile.am:
+ * platform/Cursor.h:
+ * platform/graphics/cairo/GRefPtrCairo.cpp: Removed.
+ * platform/graphics/cairo/GRefPtrCairo.h: Removed.
+ * platform/graphics/cairo/ImageCairo.cpp:
+ (WebCore::Image::drawPattern):
+ * platform/graphics/cairo/PlatformRefPtrCairo.cpp: Added.
+ (WTF::refPlatformPtr):
+ (WTF::derefPlatformPtr):
+ * platform/graphics/cairo/PlatformRefPtrCairo.h: Added.
+ * platform/graphics/gtk/ImageBufferGtk.cpp:
+ (WebCore::ImageBuffer::toDataURL):
+ * platform/gtk/ClipboardGtk.cpp:
+ (WebCore::ClipboardGtk::declareAndWriteDragImage):
+ * platform/gtk/CursorGtk.cpp:
+ (WebCore::createNamedCursor):
+ (WebCore::createCustomCursor):
+ (WebCore::Cursor::ensurePlatformCursor):
+ * platform/gtk/DataObjectGtk.h:
+ * platform/gtk/GRefPtrGtk.cpp:
+ (WTF::refPlatformPtr):
+ (WTF::derefPlatformPtr):
+ * platform/gtk/GRefPtrGtk.h:
+ * platform/gtk/PasteboardGtk.cpp:
+ (WebCore::Pasteboard::writeImage):
+ * platform/gtk/PasteboardHelper.cpp:
+ (WebCore::PasteboardHelper::dropAtomsForContext):
+ * platform/gtk/PopupMenuGtk.h:
+ * platform/gtk/RenderThemeGtk.cpp:
+ (WebCore::RenderThemeGtk::RenderThemeGtk):
+ (WebCore::paintMozillaGtkWidget):
+ * platform/gtk/RenderThemeGtk.h:
+
+2010-08-25 Eric Carlson <eric.carlson@apple.com>
+
+ Reviewed by Alexey Proskuryakov.
+
+ HTMLMediaElement.canPlayType must be case insensitive for MIME type.
+ https://bugs.webkit.org/show_bug.cgi?id=44577
+
+ * platform/graphics/MediaPlayer.cpp:
+ (WebCore::MediaPlayer::load):
+ (WebCore::MediaPlayer::supportsType):
+
+2010-08-25 Xan Lopez <xlopez@igalia.com>
+
+ Reviewed by Martin Robinson.
+
+ [GTK] CodeGeneratorGObject not picking up FEATURE_DEFINES
+ https://bugs.webkit.org/show_bug.cgi?id=44608
+
+ Move FEATURE_DEFINES declaration to the toplevel GNUmakefile.am,
+ since it's used there now too.
+
+ * GNUmakefile.am:
+
+2010-08-25 Dawit Alemayehu <adawit@kde.org>
+
+ Reviewed by Ariya Hidayat.
+
+ Proper workaround for missing Gtk initialization in Adobe's flash plugins.
+ https://bugs.webkit.org/show_bug.cgi?id=44405
+
+ * plugins/qt/PluginPackageQt.cpp:
+ (WebCore::initializeGtk):
+ (WebCore::PluginPackage::load):
+
+2010-08-25 Ilya Tikhonovsky <loislo@chromium.org>
+
+ Reviewed by Yury Semikhatsky.
+
+ WebInspector: InspectorBackendStub.js is not updated when Inspector.idl changes.
+ https://bugs.webkit.org/show_bug.cgi?id=44604
+
+ * WebCore.xcodeproj/project.pbxproj:
+
+2010-08-25 Pavel Podivilov <podivilov@chromium.org>
+
+ Reviewed by Yury Semikhatsky.
+
+ Web Inspector: don't stop on DOM breakpoints when all breakpoints are deactivated
+ https://bugs.webkit.org/show_bug.cgi?id=44509
+
+ * bindings/v8/ScriptDebugServer.cpp:
+ (WebCore::ScriptDebugServer::ScriptDebugServer):
+ (WebCore::ScriptDebugServer::setBreakpointsActivated):
+ (WebCore::ScriptDebugServer::breakProgram):
+ * bindings/v8/ScriptDebugServer.h:
+ * inspector/InspectorDebuggerAgent.cpp:
+ (WebCore::InspectorDebuggerAgent::create):
+
+2010-08-25 Yury Semikhatsky <yurys@chromium.org>
+
+ Reviewed by Pavel Feldman.
+
+ Web Inspector: lazily request frontend settings instead of pushing them on connect
+ https://bugs.webkit.org/show_bug.cgi?id=44607
+
+ * html/HTMLDocument.cpp:
+ (WebCore::HTMLDocument::createParser):
+ * inspector/Inspector.idl:
+ * inspector/InspectorController.cpp:
+ (WebCore::InspectorController::getSettings):
+ (WebCore::InspectorController::connectFrontend):
+ (WebCore::InspectorController::populateScriptObjects): this method is now called explicitely from the frontend,
+ it should be gone eventually once all panels request initial data lazily.
+ * inspector/InspectorController.h:
+ * inspector/front-end/ProfilesPanel.js:
+ (WebInspector.ProfilesPanel.prototype.show):
+ (WebInspector.ProfilesPanel.prototype.profilerWasEnabled):
+ (WebInspector.ProfilesPanel.prototype._reset):
+ * inspector/front-end/Settings.js:
+ (WebInspector.Settings):
+ (WebInspector.Settings.initialize.populateApplicationSettings):
+ (WebInspector.Settings.initialize.populateSessionSettings):
+ (WebInspector.Settings.initialize):
+ * inspector/front-end/inspector.js:
+ (WebInspector.doLoadedDone):
+
+2010-08-25 Pavel Feldman <pfeldman@chromium.org>
+
+ Reviewed by Yury Semikhatsky.
+
+ Web Inspector: support checked and disabled context menu items.
+ https://bugs.webkit.org/show_bug.cgi?id=44612
+
+ * platform/ContextMenu.cpp:
+ (WebCore::ContextMenu::checkOrEnableIfNeeded):
+
+2010-08-25 Pavel Feldman <pfeldman@chromium.org>
+
+ Reviewed by Yury Semikhatsky.
+
+ Web Inspector: support disabled and checked context menu items.
+ https://bugs.webkit.org/show_bug.cgi?id=44601
+
+ * bindings/js/JSInspectorFrontendHostCustom.cpp:
+ (WebCore::JSInspectorFrontendHost::showContextMenu):
+ * bindings/v8/custom/V8InspectorFrontendHostCustom.cpp:
+ (WebCore::V8InspectorFrontendHost::showContextMenuCallback):
+ * inspector/front-end/ContextMenu.js:
+ (WebInspector.ContextMenu.prototype.appendItem):
+
+2010-08-25 Zaheer Ahmad <zaheer.mot@gmail.com>
+
+ Reviewed by Xan Lopez.
+
+ [GTK] GTK port doesnt compile with video turned off
+ https://bugs.webkit.org/show_bug.cgi?id=44236
+
+ Generate the audio GObject DOM bindings only if video enabled
+ * WebCore/GNUMakefile.am
+ * WebCore/bindings/gobject/WebKitHTMLElementWrapperFactory.cpp:
+ Make the audio code invocation conditional
+
+
+2010-08-24 Pavel Podivilov <podivilov@chromium.org>
+
+ Reviewed by Pavel Feldman.
+
+ Web Inspector: add "Attribute Modified" and "Node Removed" DOM breakpoints
+ https://bugs.webkit.org/show_bug.cgi?id=44532
+
+ Test: inspector/dom-breakpoint.html
+
+ * inspector/InspectorDOMAgent.cpp:
+ (WebCore::InspectorDOMAgent::setDOMBreakpoint):
+ (WebCore::InspectorDOMAgent::removeDOMBreakpoint):
+ (WebCore::InspectorDOMAgent::didInsertDOMNode):
+ (WebCore::InspectorDOMAgent::didRemoveDOMNode):
+ (WebCore::InspectorDOMAgent::didModifyDOMAttr):
+ * inspector/front-end/DOMAgent.js:
+ * inspector/front-end/ElementsTreeOutline.js:
+ (WebInspector.ElementsTreeElement.prototype._populateTagContextMenu):
+
+2010-08-25 Satish Sampath <satish@chromium.org>
+
+ Reviewed by Jeremy Orlow.
+
+ Pass the element's bounds to embedder during speech recognition.
+ https://bugs.webkit.org/show_bug.cgi?id=44427
+
+ The embedder would typically want to show a native UI with information, settings etc.
+ By passing the display bounds of the html element, the embedder can position the
+ native speech recognition UI appropriately.
+
+ * page/SpeechInput.cpp:
+ (WebCore::SpeechInput::startRecognition):
+ * page/SpeechInput.h:
+ * page/SpeechInputClient.h:
+ * platform/mock/SpeechInputClientMock.cpp:
+ (WebCore::SpeechInputClientMock::startRecognition):
+ * platform/mock/SpeechInputClientMock.h:
+ * rendering/TextControlInnerElements.cpp:
+ (WebCore::InputFieldSpeechButtonElement::defaultEventHandler):
+ (WebCore::InputFieldSpeechButtonElement::detach):
+
+2010-08-25 Yongjun Zhang <yongjun_zhang@apple.com>
+
+ Reviewed by Alexey Proskuryakov.
+
+ https://bugs.webkit.org/show_bug.cgi?id=44461
+ Assertion failure at WebCore/platform/network/CredentialStorage.cpp:85.
+
+ Remove the assertion at CredentialStorage.cpp:85 since it is legal to have
+ multiple forward slashes after the path component.
+
+ No test needed.
+
+ * platform/network/CredentialStorage.cpp:
+ (WebCore::protectionSpaceMapKeyFromURL):
+
+2010-08-25 Pavel Feldman <pfeldman@chromium.org>
+
+ Reviewed by Yury Semikhatsky.
+
+ Web Inspector: search in Scripts panel brings ui back to original search view.
+ https://bugs.webkit.org/show_bug.cgi?id=44516
+
+ * inspector/front-end/Panel.js:
+ (WebInspector.Panel.prototype.searchCanceled):
+ (WebInspector.Panel.prototype.jumpToNextSearchResult):
+ (WebInspector.Panel.prototype.jumpToPreviousSearchResult):
+ * inspector/front-end/ResourcesPanel.js:
+ * inspector/front-end/ScriptsPanel.js:
+ (WebInspector.ScriptsPanel):
+ (WebInspector.ScriptsPanel.prototype.searchCanceled):
+ (WebInspector.ScriptsPanel.prototype.performSearch.finishedCallback):
+ (WebInspector.ScriptsPanel.prototype.performSearch):
+ (WebInspector.ScriptsPanel.prototype.jumpToNextSearchResult):
+ (WebInspector.ScriptsPanel.prototype.jumpToPreviousSearchResult):
+
+2010-08-25 Kent Tamura <tkent@chromium.org>
+
+ Reviewed by Shinichiro Hamaji
+
+ <input type=number>: Support auto-repeat by mouse press
+ https://bugs.webkit.org/show_bug.cgi?id=44476
+
+ Like arrow button of scrollbars, spinbuttons of <input
+ type=number> should continue to increase/decrease their values
+ while the mouse button is pressed.
+
+ No new tests because the new behavior strongly depends on a timer.
+
+ * rendering/TextControlInnerElements.cpp:
+ (WebCore::SpinButtonElement::SpinButtonElement):
+ Initializes the timer.
+ (WebCore::SpinButtonElement::defaultEventHandler):
+ Starts the timer by a mousedown event.
+ (WebCore::SpinButtonElement::startRepeatingTimer):
+ (WebCore::SpinButtonElement::stopRepeatingTimer):
+ (WebCore::SpinButtonElement::repeatingTimerFired):
+ * rendering/TextControlInnerElements.h:
+
+2010-08-25 Gabor Loki <loki@webkit.org>
+
+ Reviewed by Gavin Barraclough.
+
+ Avoid increasing required alignment of target type warning
+ https://bugs.webkit.org/show_bug.cgi?id=43963
+
+ Fix alignment warnings on Qt.
+
+ * bridge/qt/qt_runtime.cpp:
+ (JSC::Bindings::convertQVariantToValue):
+ * platform/graphics/qt/ImageBufferQt.cpp:
+ (WebCore::getImageData):
+ (WebCore::putImageData):
+ * platform/image-decoders/ImageDecoder.h:
+ (WebCore::RGBA32Buffer::getAddr):
+ * platform/text/qt/TextCodecQt.cpp:
+ (WebCore::TextCodecQt::decode):
+
+2010-08-25 Kent Tamura <tkent@chromium.org>
+
+ Reviewed by Shinichiro Hamaji
+
+ Fix a bug that a spin-button doesn't release mouse capturing
+ https://bugs.webkit.org/show_bug.cgi?id=44411
+
+ - LeftButton should be checked only for clickEvent.
+ Note that this change doesn't change the behavior because
+ button() value is initialized with LeftButton even for
+ mousemoveEvent.
+ - Should pass a SpinButtonElement node to setCapturingMouseEventsNode().
+
+ Test: fast/forms/input-spinbutton-capturing.html
+
+ * rendering/TextControlInnerElements.cpp:
+ (WebCore::SpinButtonElement::defaultEventHandler):
+
+2010-08-25 Gabor Loki <loki@webkit.org>
+
+ Reviewed by Gavin Barraclough.
+
+ Avoid increasing required alignment of target type warning
+ https://bugs.webkit.org/show_bug.cgi?id=43963
+
+ Fix platform independent alignment warnings.
+
+ * loader/CachedMetadata.h:
+ (WebCore::CachedMetadata::readUnsigned):
+ * platform/text/TextCodecLatin1.cpp:
+ (WebCore::TextCodecLatin1::decode):
+
+2010-08-25 Patrick Gansterer <paroga@paroga.com>
+
+ Reviewed by Adam Roben.
+
+ Add missing methods at ResourceHandleWin
+ https://bugs.webkit.org/show_bug.cgi?id=44453
+
+ * platform/network/win/ResourceHandleWin.cpp:
+ (WebCore::ResourceHandle::willLoadFromCache):
+ (WebCore::prefetchDNS):
+ (WebCore::ResourceHandle::bufferedData):
+ (WebCore::ResourceHandle::supportsBufferedData):
+ (WebCore::ResourceHandle::loadsBlocked):
+ (WebCore::ResourceHandle::platformSetDefersLoading):
+
+2010-08-25 Adam Barth <abarth@webkit.org>
+
+ Second attempt to fix Qt build
+
+ * dom/XMLDocumentParserQt.cpp:
+ (WebCore::XMLDocumentParser::parseDtd):
+
+2010-08-24 Eric Seidel <eric@webkit.org>
+
+ Reviewed by Adam Barth.
+
+ Remove more DTD junk now that the LegacyHTMLDocumentParser is gone
+ https://bugs.webkit.org/show_bug.cgi?id=44588
+
+ Just removing dead code, thus no tests.
+
+ * html/HTMLElement.cpp:
+ (WebCore::HTMLElement::nodeName):
+ * html/HTMLElement.h:
+
+2010-08-24 Adam Barth <abarth@webkit.org>
+
+ Qt build fix.
+
+ * dom/XMLDocumentParserQt.cpp:
+ (WebCore::XMLDocumentParser::parseStartElement):
+ (WebCore::XMLDocumentParser::parseProcessingInstruction):
+ (WebCore::XMLDocumentParser::parseCdata):
+ (WebCore::XMLDocumentParser::parseComment):
+ (WebCore::XMLDocumentParser::parseDtd):
+
+2010-08-24 Adam Barth <abarth@webkit.org>
+
+ Reviewed by Eric Seidel.
+
+ Delete HTMLElement::checkDTD
+ https://bugs.webkit.org/show_bug.cgi?id=44563
+
+ This function existed to service the LegacyHTMLTreeBuilder. The new
+ HTMLTreeBuilder has this logic internalized. Pulling on this thread
+ caused me to remove a legacyParserAddChild and to discover some code
+ that shouldn't be calling these parser-specific APIs.
+
+ * dom/ContainerNode.cpp:
+ (WebCore::ContainerNode::parserAddChild):
+ (WebCore::ContainerNode::deprecatedParserAddChild):
+ * dom/ContainerNode.h:
+ * dom/DOMImplementation.cpp:
+ (WebCore::DOMImplementation::createDocument):
+ * dom/Node.cpp:
+ (WebCore::Node::deprecatedParserAddChild):
+ * dom/Node.h:
+ * dom/XMLDocumentParser.cpp:
+ (WebCore::XMLDocumentParser::enterText):
+ * dom/XMLDocumentParser.h:
+ * dom/XMLDocumentParserLibxml2.cpp:
+ (WebCore::XMLDocumentParser::startElementNs):
+ (WebCore::XMLDocumentParser::characters):
+ (WebCore::XMLDocumentParser::processingInstruction):
+ (WebCore::XMLDocumentParser::cdataBlock):
+ (WebCore::XMLDocumentParser::comment):
+ (WebCore::XMLDocumentParser::internalSubset):
+ * dom/XMLDocumentParserQt.cpp:
+ (WebCore::XMLDocumentParser::parse):
+ (WebCore::XMLDocumentParser::parseStartElement):
+ (WebCore::XMLDocumentParser::parseCharacters):
+ (WebCore::XMLDocumentParser::parseProcessingInstruction):
+ (WebCore::XMLDocumentParser::parseCdata):
+ (WebCore::XMLDocumentParser::parseComment):
+ (WebCore::XMLDocumentParser::parseDtd):
+ * html/HTMLDataGridElement.cpp:
+ * html/HTMLDataGridElement.h:
+ * html/HTMLDataGridRowElement.cpp:
+ * html/HTMLDataGridRowElement.h:
+ * html/HTMLDataListElement.cpp:
+ * html/HTMLDataListElement.h:
+ * html/HTMLDocument.cpp:
+ * html/HTMLDocument.h:
+ * html/HTMLElement.cpp:
+ * html/HTMLElement.h:
+ * html/HTMLFieldSetElement.cpp:
+ * html/HTMLFieldSetElement.h:
+ * html/HTMLFrameSetElement.cpp:
+ * html/HTMLFrameSetElement.h:
+ * html/HTMLHeadElement.cpp:
+ * html/HTMLHeadElement.h:
+ * html/HTMLHeadingElement.cpp:
+ * html/HTMLHeadingElement.h:
+ * html/HTMLHtmlElement.cpp:
+ * html/HTMLHtmlElement.h:
+ * html/HTMLKeygenElement.cpp:
+ (WebCore::HTMLKeygenElement::HTMLKeygenElement):
+ * html/HTMLMapElement.cpp:
+ * html/HTMLMapElement.h:
+ * html/HTMLMediaElement.cpp:
+ * html/HTMLMediaElement.h:
+ * html/HTMLNoScriptElement.cpp:
+ * html/HTMLNoScriptElement.h:
+ * html/HTMLOptGroupElement.cpp:
+ * html/HTMLOptGroupElement.h:
+ * html/HTMLOptionElement.cpp:
+ * html/HTMLOptionElement.h:
+ * html/HTMLParagraphElement.cpp:
+ * html/HTMLParagraphElement.h:
+ * html/HTMLPlugInElement.cpp:
+ * html/HTMLPlugInElement.h:
+ * html/HTMLScriptElement.h:
+ * html/HTMLSelectElement.cpp:
+ * html/HTMLSelectElement.h:
+ * html/HTMLStyleElement.h:
+ * html/HTMLTableColElement.cpp:
+ * html/HTMLTableColElement.h:
+ * html/HTMLTableElement.cpp:
+ * html/HTMLTableElement.h:
+ * html/HTMLTableRowElement.cpp:
+ * html/HTMLTableRowElement.h:
+ * html/HTMLTableSectionElement.cpp:
+ * html/HTMLTableSectionElement.h:
+ * html/HTMLTextAreaElement.h:
+ * html/HTMLTitleElement.h:
+ * rendering/MediaControlElements.cpp:
+ (WebCore::MediaControlElement::attachToParent):
+ (WebCore::MediaControlInputElement::attachToParent):
+ * rendering/TextControlInnerElements.cpp:
+ (WebCore::TextControlInnerElement::attachInnerElement):
+
+2010-08-24 Adam Barth <abarth@webkit.org>
+
+ Reviewed by Eric Seidel.
+
+ Remove tagPriority
+ https://bugs.webkit.org/show_bug.cgi?id=44557
+
+ This code used to be used by the old parser. Now it's unused.
+
+ * html/HTMLAnchorElement.h:
+ * html/HTMLAppletElement.h:
+ * html/HTMLAreaElement.h:
+ * html/HTMLAudioElement.h:
+ * html/HTMLBRElement.h:
+ * html/HTMLBaseElement.h:
+ * html/HTMLBaseFontElement.h:
+ * html/HTMLBlockquoteElement.h:
+ * html/HTMLBodyElement.h:
+ * html/HTMLCanvasElement.cpp:
+ * html/HTMLCanvasElement.h:
+ * html/HTMLDListElement.h:
+ * html/HTMLDataGridCellElement.h:
+ * html/HTMLDataGridColElement.h:
+ * html/HTMLDataGridElement.h:
+ * html/HTMLDataGridRowElement.h:
+ * html/HTMLDirectoryElement.h:
+ * html/HTMLDivElement.h:
+ * html/HTMLElement.cpp:
+ * html/HTMLElement.h:
+ * html/HTMLEmbedElement.h:
+ * html/HTMLFieldSetElement.h:
+ * html/HTMLFontElement.h:
+ * html/HTMLFormControlElement.h:
+ * html/HTMLFormElement.h:
+ * html/HTMLFrameElement.h:
+ * html/HTMLFrameSetElement.h:
+ * html/HTMLHRElement.h:
+ * html/HTMLHeadElement.h:
+ * html/HTMLHeadingElement.h:
+ * html/HTMLHtmlElement.h:
+ * html/HTMLIFrameElement.h:
+ * html/HTMLImageElement.h:
+ * html/HTMLInputElement.h:
+ * html/HTMLIsIndexElement.h:
+ * html/HTMLKeygenElement.h:
+ * html/HTMLLIElement.h:
+ * html/HTMLLabelElement.h:
+ * html/HTMLLinkElement.h:
+ * html/HTMLMapElement.h:
+ * html/HTMLMarqueeElement.h:
+ * html/HTMLMenuElement.h:
+ * html/HTMLMetaElement.h:
+ * html/HTMLModElement.h:
+ * html/HTMLOListElement.h:
+ * html/HTMLObjectElement.h:
+ * html/HTMLOptionElement.h:
+ * html/HTMLParagraphElement.h:
+ * html/HTMLParamElement.h:
+ * html/HTMLPreElement.h:
+ * html/HTMLQuoteElement.h:
+ * html/HTMLScriptElement.h:
+ * html/HTMLSelectElement.h:
+ * html/HTMLSourceElement.h:
+ * html/HTMLStyleElement.h:
+ * html/HTMLTableCaptionElement.h:
+ * html/HTMLTableCellElement.h:
+ * html/HTMLTableColElement.cpp:
+ * html/HTMLTableColElement.h:
+ * html/HTMLTableElement.h:
+ * html/HTMLTableRowElement.h:
+ * html/HTMLTableSectionElement.h:
+ * html/HTMLUListElement.h:
+ * html/HTMLVideoElement.h:
+
+2010-08-24 Eric Seidel <eric@webkit.org>
+
+ Reviewed by Adam Barth.
+
+ Fix one more html5lib test case for button scoping
+ https://bugs.webkit.org/show_bug.cgi?id=44583
+
+ I <3 test driven development.
+
+ * html/HTMLTreeBuilder.cpp:
+ (WebCore::HTMLTreeBuilder::processStartTagForInBody):
+
+2010-08-24 Eric Seidel <eric@webkit.org>
+
+ Reviewed by Adam Barth.
+
+ Remove HTML5 parser testing infrastructure now that we don't need it
+ https://bugs.webkit.org/show_bug.cgi?id=44581
+
+ Just removing dead code, no tests.
+
+ * dom/DocumentFragment.cpp:
+ * dom/DocumentFragment.h:
+ * page/Settings.cpp:
+ (WebCore::Settings::Settings):
+ * page/Settings.h:
+
+2010-08-24 Adam Barth <abarth@webkit.org>
+
+ Reviewed by Eric Seidel.
+
+ Remove unneeded include in HTMLPreloadScanner
+ https://bugs.webkit.org/show_bug.cgi?id=44552
+
+ Slowly but steadily sweeping up the dust in the HTML parser.
+
+ * html/HTMLPreloadScanner.cpp:
+ * html/HTMLPreloadScanner.h:
+
+2010-08-24 Kinuko Yasuda <kinuko@chromium.org>
+
+ Reviewed by Dumitru Daniliuc.
+
+ Implement virtual path utilities for FileSystem API
+ https://bugs.webkit.org/show_bug.cgi?id=44132
+
+ No new tests; tests will be added later. (Each DOMFilePath's method is briefly tested locally.)
+
+ * CMakeLists.txt:
+ * GNUmakefile.am:
+ * WebCore.gypi:
+ * WebCore.pro:
+ * WebCore.vcproj/WebCore.vcproj:
+ * WebCore.xcodeproj/project.pbxproj:
+ * storage/DOMFilePath.cpp: Added.
+ * storage/DOMFilePath.h: Added.
+
+2010-08-24 Adam Barth <abarth@webkit.org>
+
+ Reviewed by Eric Seidel.
+
+ HTMLParserScheduler::create
+ https://bugs.webkit.org/show_bug.cgi?id=44551
+
+ * html/HTMLDocumentParser.cpp:
+ (WebCore::HTMLDocumentParser::HTMLDocumentParser):
+ * html/HTMLParserScheduler.h:
+ (WebCore::HTMLParserScheduler::create):
+
+2010-08-24 Daniel Bates <dbates@rim.com>
+
+ Fix code comment as per Darin Adler's suggestion in <https://bugs.webkit.org/show_bug.cgi?id=44486#c2>.
+ I inadvertently did not update this comment when I landed changeset 65967 <http://trac.webkit.org/changeset/65967>.
+
+ * rendering/RenderListMarker.cpp:
+ (WebCore::listMarkerSuffix):
+
+2010-08-24 Daniel Bates <dbates@rim.com>
+
+ Reviewed by Darin Adler.
+
+ Suffix for CSS alphabetic list style types should fallback to
+ decimal for ordinals outside of their representable range
+ https://bugs.webkit.org/show_bug.cgi?id=44486
+
+ Test: fast/lists/w3-css3-list-styles-fallback-style.html
+
+ Fixes an issue where the decimal suffix is not used for
+ ordinals that cannot be represented by the alphabetic list
+ style type.
+
+ Currently, for ordinals that cannot be represented in the
+ alphabetic list style we use the suffix associated with the
+ list style. Instead, we should use the suffix for the decimal
+ list style ('.'). For instance, when the list style type is
+ Afar and the starting ordinal is 0, then we fallback to the
+ decimal list style suffix '.' because 0 cannot be represented
+ in Afar.
+
+ * rendering/RenderListMarker.cpp:
+ (WebCore::toRoman): Moved bounds check into WebCore::effectiveListMarkerType().
+ (WebCore::toAlphabetic): Ditto.
+ (WebCore::toHebrew): Ditto.
+ (WebCore::toArmenian): Ditto.
+ (WebCore::toGeorgian): Ditto.
+ (WebCore::toCJKIdeographic): Ditto.
+ (WebCore::effectiveListMarkerType): Added.
+ (WebCore::listMarkerSuffix): Added value parameter to prototype.
+ Modified to call WebCore::effectiveListMarkerType.
+ (WebCore::listMarkerText): Modified to call WebCore::effectiveListMarkerType().
+ (WebCore::RenderListMarker::paint): Modified to pass list item ordinal (i.e. m_listItem->value()) to WebCore::listMarkerSuffix().
+ (WebCore::RenderListMarker::calcPrefWidths): Ditto.
+ (WebCore::RenderListMarker::getRelativeMarkerRect): Ditto.
+
+2010-08-24 Gavin Barraclough <barraclough@apple.com>
+
+ Windows build fix.
+
+ * ForwardingHeaders/wtf/DecimalNumber.h: Added.
+
+2010-08-23 Gavin Barraclough <barraclough@apple.com>
+
+ Reviewed by Oliver Hunt.
+
+ https://bugs.webkit.org/show_bug.cgi?id=44487
+
+ * html/LegacyHTMLTreeBuilder.cpp:
+ (WebCore::serializeForNumberType):
+ Update function call to numberToString.
+
+2010-08-24 Eric Seidel <eric@webkit.org>
+
+ Reviewed by Adam Barth.
+
+ XMLDocumentParser needs to implement DocumentParser::detach()
+ https://bugs.webkit.org/show_bug.cgi?id=44533
+
+ Test: fast/frames/set-parent-src-synchronously.xhtml
+
+ In the example from the page we were accessing document()
+ after DocumentParser::detach() was called. To prevent this
+ I added an ASSERT(m_document) to document(), causing many
+ test cases to cover the bug shown in bug 44533.
+
+ To fix the bug, I implemented XMLDocumentParser::detach()
+ and had it call clearCurrentNodeStack(), thus making
+ it impossible for XMLDocumentParser to still have the Document
+ on the node stack after detach (which was what was causing this bug).
+
+ While fixing this, I noticed that XMLDocumentParser may have the
+ same trouble crashing that the HTMLDocumentParser did when
+ synchronously deleted from JS (for example by an iframe navigation).
+ I added a test case to cover this and protected the parser after
+ the two places it executes scripts.
+
+ * dom/DocumentParser.h:
+ (WebCore::DocumentParser::document):
+ (WebCore::DocumentParser::isDetached):
+ * dom/RawDataDocumentParser.h:
+ (WebCore::RawDataDocumentParser::finish):
+ * dom/XMLDocumentParser.cpp:
+ (WebCore::XMLDocumentParser::append):
+ (WebCore::XMLDocumentParser::detach):
+ (WebCore::XMLDocumentParser::notifyFinished):
+ * dom/XMLDocumentParser.h:
+ * dom/XMLDocumentParserLibxml2.cpp:
+ (WebCore::XMLDocumentParser::doWrite):
+ (WebCore::XMLDocumentParser::endElementNs):
+ (WebCore::XMLDocumentParser::resumeParsing):
+ * html/HTMLDocumentParser.cpp:
+ (WebCore::HTMLDocumentParser::pumpTokenizer):
+ (WebCore::HTMLDocumentParser::willPumpLexer):
+ (WebCore::HTMLDocumentParser::didPumpLexer):
+ (WebCore::HTMLDocumentParser::end):
+ (WebCore::HTMLDocumentParser::endIfDelayed):
+ (WebCore::HTMLDocumentParser::script):
+ * html/HTMLViewSourceParser.cpp:
+ (WebCore::HTMLViewSourceParser::updateTokenizerState):
+ * html/HTMLViewSourceParser.h:
+ (WebCore::HTMLViewSourceParser::document):
+ * loader/ImageDocument.cpp:
+ (WebCore::ImageDocumentParser::document):
+
+2010-08-24 Patrick Gansterer <paroga@paroga.com>
+
+ Reviewed by Adam Roben.
+
+ Add SynchronousLoader for ResourceHandleWin
+ https://bugs.webkit.org/show_bug.cgi?id=44452
+
+ * platform/network/win/ResourceHandleWin.cpp:
+ (WebCore::WebCoreSynchronousLoader::WebCoreSynchronousLoader):
+ (WebCore::WebCoreSynchronousLoader::didReceiveResponse):
+ (WebCore::WebCoreSynchronousLoader::didReceiveData):
+ (WebCore::WebCoreSynchronousLoader::didFinishLoading):
+ (WebCore::WebCoreSynchronousLoader::didFail):
+ (WebCore::ResourceHandle::loadResourceSynchronously):
+
+2010-08-24 Ryosuke Niwa <rniwa@webkit.org>
+
+ Unreviewed.
+
+ Replaced soft tab indentation by hard tab indentation for LegacyWebArchive.h.
+
+ * WebCore.xcodeproj/project.pbxproj:
+
+2010-08-24 Joseph Pecoraro <joepeck@webkit.org>
+
+ Reviewed by Mark Rowe.
+
+ Web Inspector: RemoteInspectorFrontend can be renamed to InspectorFrontend
+ https://bugs.webkit.org/show_bug.cgi?id=44499
+
+ Follow-up. No longer generate the RemoteInspectorFrontend files, just
+ generate the required InspectorFrontend files.
+
+ * DerivedSources.make:
+
+2010-08-20 Joseph Pecoraro <joepeck@webkit.org>
+
+ Reviewed by Pavel Feldman.
+
+ Web Inspector: Backend Should Provide Full Supported CSS Properties List
+ https://bugs.webkit.org/show_bug.cgi?id=40886
+
+ This allows the backend to send the front-end its complete list of
+ supported CSS Properties. This is used in CSS Autocompletion and
+ CSS Syntax Highlighting to show which styles are supported.
+
+ * css/makeprop.pl: moved CSS properties to the header file.
+ * inspector/Inspector.idl: expose getSupportedCSSProperties.
+ * inspector/InspectorDOMAgent.cpp:
+ (WebCore::InspectorDOMAgent::getSupportedCSSProperties):
+ * inspector/InspectorDOMAgent.h:
+ * inspector/front-end/CSSCompletions.js:
+ (WebInspector.CSSCompletions._firstIndexOfPrefix): handle a possible error case before properties have loaded.
+ (WebInspector.CSSCompletions._load): fill up the special array with the received properties.
+ * inspector/front-end/SourceCSSTokenizer.js:
+ (WebInspector.SourceCSSTokenizer): use the list of support properties from the backend.
+ * inspector/front-end/SourceCSSTokenizer.re2js:
+ * inspector/front-end/inspector.js: request the list of supported CSS properties on load.
+ (WebInspector.doLoadedDone):
+
+2010-08-24 Adam Barth <abarth@webkit.org>
+
+ Reviewed by Eric Seidel.
+
+ Delete LegacyHTMLTreeBuilder
+ https://bugs.webkit.org/show_bug.cgi?id=44554
+
+ There were some free functions in LegacyHTMLTreeBuilder that needed a
+ new home. I've put them in HTMLTreeBuilder, but they'll probably need
+ a better home eventually.
+
+ * Android.mk:
+ * CMakeLists.txt:
+ * GNUmakefile.am:
+ * WebCore.gypi:
+ * WebCore.pro:
+ * WebCore.vcproj/WebCore.vcproj:
+ * WebCore.xcodeproj/project.pbxproj:
+ * dom/Document.cpp:
+ (WebCore::shouldCreateImplicitHead):
+ * dom/DocumentParser.h:
+ * dom/ScriptableDocumentParser.h:
+ * html/HTMLConstructionSite.cpp:
+ * html/HTMLFormControlElement.cpp:
+ (WebCore::HTMLFormControlElement::removedFromTree):
+ * html/HTMLInputElement.cpp:
+ * html/HTMLMeterElement.cpp:
+ * html/HTMLProgressElement.cpp:
+ * html/HTMLTreeBuilder.cpp:
+ (WebCore::serializeForNumberType):
+ (WebCore::parseToDoubleForNumberType):
+ * html/HTMLTreeBuilder.h:
+ * html/HTMLViewSourceParser.h:
+ * html/LegacyHTMLTreeBuilder.cpp: Removed.
+ * html/LegacyHTMLTreeBuilder.h: Removed.
+ * html/StepRange.cpp:
+ * html/ValidityState.cpp:
+ * rendering/RenderSlider.cpp:
+
+2010-08-24 Pavel Podivilov <podivilov@chromium.org>
+
+ Reviewed by Yury Semikhatsky.
+
+ Web Inspector: show DOM breakpoints in sidebar pane
+ https://bugs.webkit.org/show_bug.cgi?id=44424
+
+ * inspector/front-end/BreakpointManager.js:
+ (WebInspector.BreakpointManager.prototype._setBreakpoint):
+ (WebInspector.BreakpointManager.prototype._breakpointRemoved):
+ (WebInspector.BreakpointManager.prototype._setBreakpointOnBackend):
+ (WebInspector.Breakpoint.prototype.set enabled):
+ (WebInspector.Breakpoint.prototype.set condition):
+ (WebInspector.Breakpoint.prototype.remove):
+ * inspector/front-end/BreakpointsSidebarPane.js:
+ (WebInspector.BreakpointsSidebarPane):
+ (WebInspector.BreakpointsSidebarPane.prototype.addBreakpoint):
+ (WebInspector.BreakpointsSidebarPane.prototype._breakpointRemoved):
+ (WebInspector.BreakpointsSidebarPane.prototype._contextMenuEventFired):
+ (WebInspector.BreakpointItem):
+ (WebInspector.BreakpointItem.prototype.element):
+ (WebInspector.BreakpointItem.prototype.remove):
+ (WebInspector.BreakpointItem.prototype._checkboxClicked):
+ (WebInspector.BreakpointItem.prototype._enableChanged):
+ (WebInspector.BreakpointItem.prototype._removed):
+ (WebInspector.JSBreakpointItem):
+ (WebInspector.JSBreakpointItem.prototype._textChanged):
+ (WebInspector.DOMBreakpointItem):
+ (WebInspector.DOMBreakpointItem.prototype.compareTo):
+ * inspector/front-end/DOMAgent.js:
+ (WebInspector.DOMBreakpointManager):
+ (WebInspector.DOMBreakpointManager.prototype.setBreakpoint):
+ (WebInspector.DOMBreakpointManager.prototype.removeBreakpointsForNode):
+ (WebInspector.DOMBreakpointManager.prototype._breakpointRemoved):
+ (WebInspector.DOMBreakpoint):
+ (WebInspector.DOMBreakpoint.prototype.get enabled):
+ (WebInspector.DOMBreakpoint.prototype.set enabled):
+ (WebInspector.DOMBreakpoint.prototype.remove):
+ * inspector/front-end/ElementsPanel.js:
+ (WebInspector.ElementsPanel):
+ (WebInspector.ElementsPanel.prototype.reset):
+ * inspector/front-end/ElementsTreeOutline.js:
+ (WebInspector.ElementsTreeElement.prototype._populateTagContextMenu):
+ * inspector/front-end/ScriptView.js:
+ (WebInspector.ScriptView):
+ * inspector/front-end/ScriptsPanel.js:
+ (WebInspector.ScriptsPanel):
+ (WebInspector.ScriptsPanel.prototype._breakpointAdded):
+ (WebInspector.ScriptsPanel.prototype.reset):
+ * inspector/front-end/SourceFrame.js:
+ (WebInspector.SourceFrame):
+ (WebInspector.SourceFrame.prototype.set visible):
+ (WebInspector.SourceFrame.prototype.addBreakpoint):
+ (WebInspector.SourceFrame.prototype._breakpointRemoved):
+ (WebInspector.SourceFrame.prototype._addBreakpointToSource):
+ (WebInspector.SourceFrame.prototype._removeBreakpointFromSource):
+ (WebInspector.SourceFrame.prototype._contextMenu.addConditionalBreakpoint):
+ (WebInspector.SourceFrame.prototype._contextMenu):
+ (WebInspector.SourceFrame.prototype._mouseDown):
+ * inspector/front-end/SourceView.js:
+ (WebInspector.SourceView):
+ (WebInspector.SourceView.prototype.updateLocalContent):
+ * inspector/front-end/inspector.js:
+ (WebInspector.createJSBreakpointsSidebarPane.breakpointAdded):
+ (WebInspector.createJSBreakpointsSidebarPane):
+ (WebInspector.createDOMBreakpointsSidebarPane.breakpointAdded):
+ (WebInspector.createDOMBreakpointsSidebarPane):
+ (WebInspector.doLoadedDone):
+
+2010-08-24 Stephen White <senorblanco@chromium.org>
+
+ Reviewed by Dumitru Daniliuc.
+
+ Speculative fix for layout test failures on Chrome/Linux.
+ https://bugs.webkit.org/show_bug.cgi?id=44550
+
+ Tests fast/canvas/arc-crash.html, fast/canvas/canvas-state-intact-after-putImageData.html, and fast/canvas/toDataURL-supportedTypes.html are failing on Chrome/Linux. Can't repro the failure locally, but this fix can't hurt.
+
+ * html/canvas/CanvasRenderingContext2D.cpp:
+ (WebCore::CanvasRenderingContext2D::paintRenderingResultsToCanvas):
+
+2010-08-24 Dumitru Daniliuc <dumi@chromium.org>
+
+ Reviewed by Dimitri Glazkov.
+
+ Fix the NodeFilter wrapper and the binding for acceptNode.
+ https://bugs.webkit.org/show_bug.cgi?id=44542
+
+ * bindings/v8/V8DOMWrapper.cpp:
+ (WebCore::V8DOMWrapper::wrapNativeNodeFilter): This function
+ should always create a filter. V8NodeFilterCondition::acceptNode()
+ will check if the given object can be used as a filter, and throw
+ an exception if it can't.
+ * bindings/v8/V8NodeFilterCondition.cpp:
+ (WebCore::V8NodeFilterCondition::acceptNode): Update this binding
+ to do the same thing that the JS binding does.
+
+2010-08-24 Simon Fraser <simon.fraser@apple.com>
+
+ Reviewed by Tony Chang.
+
+ After r65681, caret no longer displays promptly while editing form fields
+ https://bugs.webkit.org/show_bug.cgi?id=44294
+
+ The caret no longer eagerly updates its rect on every paint, so we have
+ to manually update it after scrolling the selection into view when
+ the selection changes.
+
+ Tested by the pixel results of fast/forms/input-text-scroll-left-on-blur.html
+
+ * page/Frame.cpp:
+ (WebCore::Frame::revealSelection):
+
+2010-08-24 Adam Barth <abarth@webkit.org>
+
+ Reviewed by Darin Adler.
+
+ Remove redundant call to OwnPtr::clear
+ https://bugs.webkit.org/show_bug.cgi?id=44548
+
+ As pointed out by Darin, this call to clear is not needed.
+
+ * editing/TextIterator.cpp:
+ (WebCore::plainTextToMallocAllocatedBuffer):
+
+2010-08-24 Adam Barth <abarth@webkit.org>
+
+ Reviewed by Eric Seidel.
+
+ HTMLTokenizer::create
+ https://bugs.webkit.org/show_bug.cgi?id=44477
+
+ * html/HTMLDocumentParser.cpp:
+ (WebCore::HTMLDocumentParser::HTMLDocumentParser):
+ * html/HTMLPreloadScanner.cpp:
+ (WebCore::HTMLPreloadScanner::HTMLPreloadScanner):
+ (WebCore::HTMLPreloadScanner::scan):
+ (WebCore::HTMLPreloadScanner::processToken):
+ * html/HTMLPreloadScanner.h:
+ * html/HTMLTokenizer.h:
+ (WebCore::HTMLTokenizer::create):
+ * html/HTMLViewSourceParser.cpp:
+ (WebCore::HTMLViewSourceParser::HTMLViewSourceParser):
+ (WebCore::HTMLViewSourceParser::pumpTokenizer):
+ (WebCore::HTMLViewSourceParser::updateTokenizerState):
+ * html/HTMLViewSourceParser.h:
+
+2010-08-24 Adam Barth <abarth@webkit.org>
+
+ Reviewed by Darin Adler.
+
+ Remove references to LegacyHTMLTreebuilder from HTMLTreeBuilder
+ https://bugs.webkit.org/show_bug.cgi?id=44544
+
+ * html/HTMLDocumentParser.cpp:
+ * html/HTMLDocumentParser.h:
+ * html/HTMLTreeBuilder.cpp:
+ (WebCore::HTMLTreeBuilder::HTMLTreeBuilder):
+ (WebCore::HTMLTreeBuilder::FragmentParsingContext::FragmentParsingContext):
+ (WebCore::HTMLTreeBuilder::FragmentParsingContext::document):
+ (WebCore::HTMLTreeBuilder::constructTreeFromToken):
+ (WebCore::HTMLTreeBuilder::finished):
+ * html/HTMLTreeBuilder.h:
+ (WebCore::HTMLTreeBuilder::FragmentParsingContext::contextElement):
+
+2010-08-24 Xan Lopez <xlopez@igalia.com>
+
+ Try to fix GTK+ build.
+
+ Move GTK_API_VERSION_2 define out.
+
+ * GNUmakefile.am:
+
+2010-08-24 Simon Fraser <simon.fraser@apple.com>
+
+ Reviewed by Sam Weinig.
+
+ TreeWalker traversal order is wrong when skipping and rejecting
+ https://bugs.webkit.org/show_bug.cgi?id=44377
+
+ TreeWalker's nextSibling() and previousSibling() behaved incorrectly
+ when traversing down a subtree where all nodes are skipped; it backed all
+ the way up to the root of the subtree, then jump to the subtree's parentNode.
+ This would skip later siblings.
+
+ Fix by resetting 'node' when traversing to children so that node = node->parentNode()
+ gets the correct node later.
+
+ Test: fast/dom/TreeWalker/traversal-skip-most.html
+
+ * dom/TreeWalker.cpp:
+ (WebCore::TreeWalker::previousSibling):
+ (WebCore::TreeWalker::nextSibling):
+
+2010-08-24 Hans Wennborg <hans@chromium.org>
+
+ Reviewed by Steve Block.
+
+ Remove null-checks from DeviceOrientationController
+ https://bugs.webkit.org/show_bug.cgi?id=44504
+
+ Remove checks for m_client being NULL from DeviceOrientationController.
+ It will never be NULL, and this is checked by an ASSERT on construction.
+
+ Will be covered by layout tests for device orientation.
+
+ * dom/DeviceOrientationController.cpp:
+ (WebCore::DeviceOrientationController::timerFired):
+ (WebCore::DeviceOrientationController::addListener):
+ (WebCore::DeviceOrientationController::removeListener):
+ (WebCore::DeviceOrientationController::removeAllListeners):
+
+2010-08-24 Stephen White <senorblanco@chromium.org>
+
+ Reviewed by Kenneth Russell.
+
+ Fix accelerated 2d canvas with accelerated compositing off.
+ https://bugs.webkit.org/show_bug.cgi?id=44525
+
+ Tested by running with --enable-accelerated-2d-canvas with
+ --enable-accelerated-compositing off.
+ ImageBuffer::copyImage changes covered by
+ LayoutTests/fast/canvas/canvas-pattern-*.html.
+
+ * html/HTMLCanvasElement.cpp:
+ (WebCore::HTMLCanvasElement::paint):
+ Extend the accelerated compositing check and the readback for
+ non-accelerated compositing to accelerated 2D canvas also.
+ * html/canvas/CanvasRenderingContext.cpp:
+ * html/canvas/CanvasRenderingContext.h:
+ (WebCore::CanvasRenderingContext::paintsIntoCanvasBuffer):
+ Move this logic from WebGL to common canvas context code.
+ * html/canvas/WebGLRenderingContext.h:
+ Remove implementation of paintsIntoCanvasBuffer.
+ * platform/graphics/skia/ImageBufferSkia.cpp:
+ (WebCore::ImageBuffer::copyImage):
+ When copying the image for patterns, sync the software canvas.
+ * platform/graphics/skia/PlatformContextSkia.cpp:
+ (WebCore::PlatformContextSkia::prepareForSoftwareDraw):
+ Use SkDevice::eraseColor() to clear the canvas for mixed mode rendering.
+
+2010-08-24 Adam Barth <abarth@webkit.org>
+
+ Reviewed by Eric Seidel.
+
+ Deploy adoptPtr in WebCore/editing
+ https://bugs.webkit.org/show_bug.cgi?id=44501
+
+ * editing/Editor.cpp:
+ (WebCore::Editor::Editor):
+ * editing/TextIterator.cpp:
+ (WebCore::plainTextToMallocAllocatedBuffer):
+
+2010-08-24 Adam Barth <abarth@webkit.org>
+
+ Reviewed by Eric Seidel.
+
+ Deploy adoptPtr in WebCore/history
+ https://bugs.webkit.org/show_bug.cgi?id=44502
+
+ * history/HistoryItem.cpp:
+ (WebCore::HistoryItem::HistoryItem):
+ (WebCore::HistoryItem::addRedirectURL):
+
+2010-08-24 Adam Barth <abarth@webkit.org>
+
+ Reviewed by Eric Seidel.
+
+ Partial deployment of adoptPtr to WebCore/html
+ https://bugs.webkit.org/show_bug.cgi?id=44507
+
+ Deploy adoptPtr to some more places in WebCore/html. The big chunk
+ that I haven't done yet is createRenderer, but that's going to be a big
+ patch unto itself.
+
+ * html/HTMLFormCollection.cpp:
+ (WebCore::HTMLFormCollection::formCollectionInfo):
+ * html/HTMLFormElement.cpp:
+ (WebCore::HTMLFormElement::addElementAlias):
+ * html/HTMLInputElement.cpp:
+ (WebCore::createTypeMap):
+ (WebCore::HTMLInputElement::setInputType):
+ (WebCore::HTMLInputElement::parseMappedAttribute):
+ (WebCore::HTMLInputElement::attach):
+ (WebCore::HTMLInputElement::preDispatchEventHandler):
+ * html/HTMLObjectElement.cpp:
+ (WebCore::HTMLObjectElement::parseMappedAttribute):
+ (WebCore::HTMLObjectElement::attach):
+ * html/HTMLToken.h:
+ (WebCore::HTMLToken::beginDOCTYPE):
+ * html/HTMLVideoElement.cpp:
+ (WebCore::HTMLVideoElement::attach):
+ (WebCore::HTMLVideoElement::parseMappedAttribute):
+ * html/ValidityState.h:
+ (WebCore::ValidityState::create):
+
+2010-08-24 Adam Barth <abarth@webkit.org>
+
+ Reviewed by Eric Seidel.
+
+ Partial deployment of adoptPtr to WebCore/html
+ https://bugs.webkit.org/show_bug.cgi?id=44507
+
+ There's a lot of places that need adoptPtr in WebCore/html. This patch
+ does some of them. More will follow.
+
+ * html/FileThreadTask.h:
+ (WebCore::FileThreadTask0::create):
+ (WebCore::FileThreadTask1::create):
+ (WebCore::FileThreadTask2::create):
+ (WebCore::FileThreadTask3::create):
+ * html/HTMLAreaElement.cpp:
+ (WebCore::HTMLAreaElement::mapMouseEvent):
+ * html/HTMLCanvasElement.cpp:
+ (WebCore::HTMLCanvasElement::getContext):
+ * html/HTMLElementStack.cpp:
+ (WebCore::HTMLElementStack::insertAbove):
+ (WebCore::HTMLElementStack::pushCommon):
+ * html/HTMLEmbedElement.cpp:
+ (WebCore::HTMLEmbedElement::parseMappedAttribute):
+ (WebCore::HTMLEmbedElement::attach):
+
+2010-08-24 Sam Weinig <sam@webkit.org>
+
+ Reviewed by Simon Fraser.
+
+ Improve comment for Simon.
+
+ * editing/Editor.h:
+
+2010-08-24 Sam Weinig <sam@webkit.org>
+
+ Reviewed by Oliver Hunt.
+
+ Paste event fires twice for mac WebKit
+ <rdar://problem/8094611>
+ https://bugs.webkit.org/show_bug.cgi?id=44535
+
+ The mac implementation of paste in WebKit was accidentally calling
+ Editor::tryDHTMLPaste twice, once in -[WebHTMLView paste:] and once
+ in Editor::pasteAsPlainText (which is called by -[WebHTMLView paste:]).
+ Use the new pasteAsPlainTextBypassingDHTML function to bypass the
+ second call.
+
+ Test: editing/pasteboard/paste-event-only-once.html
+
+ * WebCore.exp.in:
+ * editing/Editor.cpp:
+ (WebCore::Editor::pasteAsPlainTextBypassingDHTML):
+ * editing/Editor.h:
+ Expose a function which just pastes using from the general pasteboard,
+ bypassing all the checking and DHTML pasting.
+
+2010-08-24 Nate Chapin <japhet@chromium.org>
+
+ Unreviewed.
+
+ Chromium build fix (add a #include missing in PingLoader.cpp)
+
+ * loader/PingLoader.cpp:
+
+2010-08-24 Nate Chapin <japhet@chromium.org>
+
+ Reviewed by David Levin.
+
+ Allow image loads triggered from unload handlers to run entirely
+ independently of any other loads or navigations.
+
+ https://bugs.webkit.org/show_bug.cgi?id=30457
+
+ Test: http/tests/navigation/image-load-in-unload-handler.html
+
+ * Android.mk:
+ * CMakeLists.txt:
+ * GNUmakefile.am:
+ * WebCore.gypi:
+ * WebCore.pro:
+ * WebCore.vcproj/WebCore.vcproj:
+ * WebCore.xcodeproj/project.pbxproj:
+ * loader/DocLoader.cpp:
+ (WebCore::DocLoader::requestImage): Use PingLoader for image
+ loads in unload handlers.
+ * loader/FrameLoader.h:
+ (WebCore::FrameLoader::pageDismissalEventBeingDispatched):
+ * loader/PingLoader.cpp: Added.
+ (WebCore::PingLoader::loadImage): Set the appropriate
+ headers for an image load in unload handler (since we're
+ not using SubresourceLoader, we need to do this manually here).
+ (WebCore::PingLoader::PingLoader):
+ * loader/PingLoader.h: Added.
+ (WebCore::PingLoader::~PingLoader):
+ (WebCore::PingLoader::didReceiveResponse):
+ (WebCore::PingLoader::didReceiveData):
+ (WebCore::PingLoader::didFinishLoading):
+ (WebCore::PingLoader::didFail):
+
+2010-08-24 Pavel Feldman <pfeldman@chromium.org>
+
+ Reviewed by Yury Semikhatsky.
+
+ Web Inspector: Trace to the style that contributes to
+ the computed styles panel.
+ https://bugs.webkit.org/show_bug.cgi?id=44448
+
+ Test: inspector/styles-computed-trace.html
+
+ * English.lproj/localizedStrings.js:
+ * inspector/front-end/Section.js:
+ (WebInspector.Section.prototype.set subtitle):
+ (WebInspector.Section.prototype.get subtitleAsTextForTest):
+ * inspector/front-end/StylesSidebarPane.js:
+ (WebInspector.StylesSidebarPane.prototype._refreshUpdate):
+ (WebInspector.StylesSidebarPane.prototype._rebuildUpdate):
+ (WebInspector.StylesSidebarPane.prototype._rebuildStyleRules):
+ (WebInspector.StylesSidebarPane.prototype._refreshSectionsForStyleRules):
+ (WebInspector.StylesSidebarPane.prototype._rebuildSectionsForStyleRules):
+ (WebInspector.StylePropertiesSection.linkifyUncopyable):
+ (WebInspector.StylePropertiesSection):
+ (WebInspector.StylePropertiesSection.prototype.isPropertyInherited):
+ (WebInspector.StylePropertiesSection.prototype.isPropertyOverloaded):
+ (WebInspector.StylePropertiesSection.prototype.isPropertyDisabled):
+ (WebInspector.StylePropertiesSection.prototype.update):
+ (WebInspector.StylePropertiesSection.prototype.onpopulate):
+ (WebInspector.ComputedStylePropertiesSection):
+ (WebInspector.ComputedStylePropertiesSection.prototype.collapse):
+ (WebInspector.ComputedStylePropertiesSection.prototype._isPropertyInherited):
+ (WebInspector.ComputedStylePropertiesSection.prototype.update):
+ (WebInspector.ComputedStylePropertiesSection.prototype.onpopulate):
+ (WebInspector.ComputedStylePropertiesSection.prototype.rebuildComputedTrace):
+ (WebInspector.BlankStylePropertiesSection):
+ * inspector/front-end/inspector.css:
+ (.styles-section a::before):
+ * inspector/front-end/inspector.js:
+ (WebInspector.documentClick.followLink):
+ (WebInspector.documentClick):
+ (WebInspector.linkifyResourceAsNode):
+
+2010-08-24 Daniel Cheng <dcheng@chromium.org>
+
+ Reviewed by Eric Seidel.
+
+ [chromium] Generate drag images for HTML elements and selections.
+ https://bugs.webkit.org/show_bug.cgi?id=43449
+
+ We weren't properly generating drag images if an HTML element was set
+ as the drag feedback image. I also implemented dragImageForSelection
+ while I was working on this part of the code.
+
+ No new tests.
+
+ * WebCore.exp.in:
+ * bindings/objc/DOM.mm:
+ (-[DOMNode renderedImage]):
+ * page/Frame.h:
+ * page/brew/FrameBrew.cpp:
+ (WebCore::Frame::nodeImage):
+ * page/chromium/FrameChromium.cpp:
+ (WebCore::):
+ (WebCore::Frame::nodeImage):
+ (WebCore::Frame::dragImageForSelection):
+ * page/efl/FrameEfl.cpp:
+ (WebCore::Frame::nodeImage):
+ * page/gtk/FrameGtk.cpp:
+ (WebCore::Frame::nodeImage):
+ * page/haiku/FrameHaiku.cpp:
+ (WebCore::Frame::nodeImage):
+ * page/mac/FrameMac.mm:
+ (WebCore::Frame::nodeImage):
+ (WebCore::Frame::dragImageForSelection):
+ * page/qt/FrameQt.cpp:
+ (WebCore::Frame::nodeImage):
+ (WebCore::Frame::dragImageForSelection):
+ * page/win/FrameCGWin.cpp:
+ (WebCore::Frame::nodeImage):
+ * page/win/FrameCairoWin.cpp:
+ (WebCore::Frame::nodeImage):
+ * page/wince/FrameWince.cpp:
+ (WebCore::Frame::nodeImage):
+ * page/wx/FrameWx.cpp:
+ (WebCore::Frame::nodeImage):
+ * platform/chromium/ClipboardChromium.cpp:
+ (WebCore::ClipboardChromium::createDragImage):
+ * rendering/RenderObject.cpp:
+ (WebCore::RenderObject::selectionForegroundColor):
+
+2010-08-24 Jeremy Orlow <jorlow@chromium.org>
+
+ Reviewed by Steve Block.
+
+ IndexedDB needs to manually delete all objectStore data and indexes
+ https://bugs.webkit.org/show_bug.cgi?id=44522
+
+ Apparently it's only newer versions of SQLite that handle cascade
+ delete. The rest silently fail. So do it manually.
+
+ Test: storage/indexeddb/objectstore-removeobjectstore.html
+
+ * storage/IDBDatabaseBackendImpl.cpp:
+ (WebCore::IDBDatabaseBackendImpl::createObjectStore):
+ (WebCore::doDelete):
+ (WebCore::IDBDatabaseBackendImpl::removeObjectStore):
+ * storage/IDBDatabaseBackendImpl.h:
+ * storage/IDBFactoryBackendImpl.cpp:
+ (WebCore::createTables):
+ * storage/IDBObjectStoreBackendImpl.cpp:
+ (WebCore::IDBObjectStoreBackendImpl::removeIndex):
+ * storage/IDBObjectStoreBackendImpl.h:
+ (WebCore::IDBObjectStoreBackendImpl::create):
+ (WebCore::IDBObjectStoreBackendImpl::id):
+
+2010-08-23 Sam Weinig <sam@webkit.org>
+
+ Reviewed by Adam Barth.
+
+ Fix for <rdar://problem/8153271> and <rdar://problem/8153288>
+ Change behavior of javascript: urls in <embed> and <object> back to
+ how they behaved before r50698.
+
+ Tests: fast/loader/javascript-url-in-embed.html
+ fast/loader/javascript-url-in-object.html
+
+ * loader/SubframeLoader.cpp:
+ (WebCore::SubframeLoader::requestFrame):
+ (WebCore::SubframeLoader::requestObject):
+ (WebCore::SubframeLoader::loadOrRedirectSubframe):
+ * loader/SubframeLoader.h:
+
+2010-08-24 Xan Lopez <xlopez@igalia.com>
+
+ Reviewed by Gustavo Noronha.
+
+ Update code to compile with latest GTK+ 3.x.
+
+ * platform/gtk/gtk2drawing.c:
+ (TSOffsetStyleGCs):
+ (moz_gtk_entry_paint):
+ * plugins/gtk/gtk2xtbin.c:
+ (gtk_xtbin_new):
+
+2010-08-24 Nikolas Zimmermann <nzimmermann@rim.com>
+
+ Reviewed by Dirk Schulze.
+
+ -webkit-svg-shadow doesn't repaint on changes
+ https://bugs.webkit.org/show_bug.cgi?id=44521
+
+ Trivial fix, to make -webkit-svg-shadow react on changes.
+
+ Test: svg/css/shadow-changes.svg
+
+ * rendering/style/SVGRenderStyle.cpp:
+ (WebCore::SVGRenderStyle::diff): If 'svgShadow' is not equal, cause a repaint.
+
+2010-08-24 Dirk Schulze <krit@webkit.org>
+
+ Reviewed by Nikolas Zimmermann.
+
+ Cg logs "<Error>: CGPathCloseSubpath: no current point. " in lots of tests
+ https://bugs.webkit.org/show_bug.cgi?id=43026
+
+ Check if the path is empty before closing it.
+
+ * svg/SVGPathBuilder.cpp:
+ (WebCore::SVGPathBuilder::moveTo):
+
+2010-08-24 Marcus Bulach <bulach@chromium.org>
+
+ Reviewed by Jeremy Orlow.
+
+ Hooks IDBKeyPath with IDBObjectStorage::put.
+ https://bugs.webkit.org/show_bug.cgi?id=44275
+
+ Adds a mechanism to extract an IDBKey from SerializedScriptValue using IDBKeyPath
+ during IDBObjectStorage::put.
+
+ * WebCore.gyp/WebCore.gyp:
+ * WebCore.gypi:
+ * platform/chromium/ChromiumBridge.h:
+ * storage/IDBKeyPathBackendImpl.cpp: Added.
+ (IDBKeyPathBackendImpl::createIDBKeysFromSerializedValuesAndKeyPath):
+ * storage/IDBKeyPathBackendImpl.h: Added.
+ * storage/IDBObjectStoreBackendImpl.cpp:
+ (WebCore::IDBObjectStoreBackendImpl::put):
+ * storage/chromium/IDBKeyPathBackendImpl.cpp: Added.
+ (WebCore::IDBKeyPathBackendImpl::createIDBKeysFromSerializedValuesAndKeyPath):
+
+2010-08-24 Ilya Tikhonovsky <loislo@chromium.org>
+
+ Reviewed by Pavel Feldman.
+
+ WebInspector: RemoteInspectorFrontend can be renamed to InspectorFrontend.
+ The old version of InspectorFrontend was removed some time ago and now
+ it is possible to rename the new version of inspector frontend class to its
+ original name.
+ https://bugs.webkit.org/show_bug.cgi?id=44499
+
+ * GNUmakefile.am:
+ * WebCore.gyp/WebCore.gyp:
+ * WebCore.pri:
+ * WebCore.vcproj/WebCore.vcproj:
+ * WebCore.xcodeproj/project.pbxproj:
+ * inspector/CodeGeneratorInspector.pm:
+ * inspector/ConsoleMessage.cpp:
+ (WebCore::ConsoleMessage::addToFrontend):
+ (WebCore::ConsoleMessage::updateRepeatCountInConsole):
+ * inspector/ConsoleMessage.h:
+ * inspector/InjectedScriptHost.cpp:
+ (WebCore::InjectedScriptHost::pushNodePathToFrontend):
+ (WebCore::InjectedScriptHost::frontend):
+ * inspector/InjectedScriptHost.h:
+ * inspector/InspectorApplicationCacheAgent.cpp:
+ (WebCore::InspectorApplicationCacheAgent::InspectorApplicationCacheAgent):
+ * inspector/InspectorApplicationCacheAgent.h:
+ * inspector/InspectorBackend.cpp:
+ (WebCore::InspectorBackend::dispatchOnInjectedScript):
+ (WebCore::InspectorBackend::frontend):
+ * inspector/InspectorBackend.h:
+ * inspector/InspectorCSSStore.cpp:
+ * inspector/InspectorCSSStore.h:
+ * inspector/InspectorController.cpp:
+ (WebCore::InspectorController::inspectedPageDestroyed):
+ (WebCore::InspectorController::inspect):
+ (WebCore::InspectorController::focusNode):
+ (WebCore::InspectorController::windowVisible):
+ (WebCore::InspectorController::addConsoleMessage):
+ (WebCore::InspectorController::clearConsoleMessages):
+ (WebCore::InspectorController::inspectedWindowScriptObjectCleared):
+ (WebCore::InspectorController::setSearchingForNode):
+ (WebCore::InspectorController::setMonitoringXHR):
+ (WebCore::InspectorController::connectFrontend):
+ (WebCore::InspectorController::show):
+ (WebCore::InspectorController::showPanel):
+ (WebCore::InspectorController::close):
+ (WebCore::InspectorController::disconnectFrontend):
+ (WebCore::InspectorController::populateScriptObjects):
+ (WebCore::InspectorController::pruneResources):
+ (WebCore::InspectorController::didCommitLoad):
+ (WebCore::InspectorController::didLoadResourceFromMemoryCache):
+ (WebCore::InspectorController::identifierForInitialRequest):
+ (WebCore::InspectorController::mainResourceFiredDOMContentEvent):
+ (WebCore::InspectorController::mainResourceFiredLoadEvent):
+ (WebCore::InspectorController::willSendRequest):
+ (WebCore::InspectorController::didReceiveResponse):
+ (WebCore::InspectorController::didReceiveContentLength):
+ (WebCore::InspectorController::didFinishLoading):
+ (WebCore::InspectorController::didFailLoading):
+ (WebCore::InspectorController::resourceRetrievedByXMLHttpRequest):
+ (WebCore::InspectorController::scriptImported):
+ (WebCore::InspectorController::enableResourceTracking):
+ (WebCore::InspectorController::disableResourceTracking):
+ (WebCore::InspectorController::startTimelineProfiler):
+ (WebCore::InspectorController::stopTimelineProfiler):
+ (WebCore::InspectorController::postWorkerNotificationToFrontend):
+ (WebCore::InspectorController::didCreateWorker):
+ (WebCore::InspectorController::didDestroyWorker):
+ (WebCore::InspectorController::selectDatabase):
+ (WebCore::InspectorController::didOpenDatabase):
+ (WebCore::InspectorController::didUseDOMStorage):
+ (WebCore::InspectorController::selectDOMStorage):
+ (WebCore::InspectorController::enableDebuggerFromFrontend):
+ (WebCore::InspectorController::enableDebugger):
+ (WebCore::InspectorController::disableDebugger):
+ (WebCore::InspectorController::evaluateForTestInFrontend):
+ * inspector/InspectorController.h:
+ (WebCore::InspectorController::hasFrontend):
+ * inspector/InspectorDOMAgent.cpp:
+ (WebCore::InspectorDOMAgent::InspectorDOMAgent):
+ * inspector/InspectorDOMAgent.h:
+ (WebCore::InspectorDOMAgent::create):
+ * inspector/InspectorDOMStorageResource.cpp:
+ (WebCore::InspectorDOMStorageResource::bind):
+ * inspector/InspectorDOMStorageResource.h:
+ * inspector/InspectorDatabaseResource.cpp:
+ (WebCore::InspectorDatabaseResource::bind):
+ * inspector/InspectorDatabaseResource.h:
+ * inspector/InspectorDebuggerAgent.cpp:
+ (WebCore::InspectorDebuggerAgent::create):
+ (WebCore::InspectorDebuggerAgent::InspectorDebuggerAgent):
+ (WebCore::InspectorDebuggerAgent::setPauseOnExceptionsState):
+ (WebCore::InspectorDebuggerAgent::didParseSource):
+ (WebCore::InspectorDebuggerAgent::failedToParseSource):
+ (WebCore::InspectorDebuggerAgent::didPause):
+ (WebCore::InspectorDebuggerAgent::didContinue):
+ * inspector/InspectorDebuggerAgent.h:
+ * inspector/InspectorProfilerAgent.cpp:
+ (WebCore::InspectorProfilerAgent::InspectorProfilerAgent):
+ (WebCore::InspectorProfilerAgent::addProfile):
+ (WebCore::InspectorProfilerAgent::disable):
+ (WebCore::InspectorProfilerAgent::enable):
+ (WebCore::InspectorProfilerAgent::resetState):
+ (WebCore::InspectorProfilerAgent::toggleRecordButton):
+ * inspector/InspectorProfilerAgent.h:
+ (WebCore::InspectorProfilerAgent::setFrontend):
+ * inspector/InspectorResource.cpp:
+ (WebCore::InspectorResource::updateScriptObject):
+ (WebCore::InspectorResource::releaseScriptObject):
+ * inspector/InspectorResource.h:
+ * inspector/InspectorStorageAgent.cpp:
+ (WebCore::InspectorStorageAgent::InspectorStorageAgent):
+ * inspector/InspectorStorageAgent.h:
+ (WebCore::InspectorStorageAgent::create):
+ (WebCore::InspectorStorageAgent::frontend):
+ * inspector/InspectorTimelineAgent.cpp:
+ (WebCore::InspectorTimelineAgent::InspectorTimelineAgent):
+ (WebCore::InspectorTimelineAgent::resetFrontendProxyObject):
+ * inspector/InspectorTimelineAgent.h:
+
+2010-08-24 Nikolas Zimmermann <nzimmermann@rim.com>
+
+ Reviewed by Dirk Schulze.
+
+ Markers don't render, when applied to a target using vector-effect="non-scaling-stroke"
+ https://bugs.webkit.org/show_bug.cgi?id=44511
+
+ Make fillAndStrokePath a member function of RenderPath, to avoid having to pass the const Path& and this paramters.
+ Don't leave the GraphicsContext mutated after applying non-scaling-stroke transformation, otherwhise markers will be renderer
+ in the wrong coordinate space, and thus don't show up anymore.
+
+ Test: svg/custom/non-scaling-stroke-markers.svg
+
+ * rendering/RenderPath.cpp:
+ (WebCore::RenderPath::fillAndStrokePath):
+ (WebCore::RenderPath::paint):
+ * rendering/RenderPath.h:
+
+2010-08-24 Adam Barth <abarth@webkit.org>
+
+ Reviewed by Kenneth Rohde Christiansen.
+
+ Remove wrong code from Qt that's dumping extra markup into the clipboard
+ https://bugs.webkit.org/show_bug.cgi?id=44506
+
+ I have no way of testing this patch, but hopefully it should fix a
+ bunch of newly failing tests. This code seems very confused.
+
+ * platform/qt/PasteboardQt.cpp:
+ (WebCore::Pasteboard::writeSelection):
+
+2010-08-24 Pavel Podivilov <podivilov@chromium.org>
+
+ Reviewed by Yury Semikhatsky.
+
+ Web Inspector: fix gcc warnings introduced in 65731
+ https://bugs.webkit.org/show_bug.cgi?id=44468
+
+ * inspector/InspectorDOMAgent.cpp:
+ (WebCore::InspectorDOMAgent::didInsertDOMNode):
+ (WebCore::InspectorDOMAgent::pauseOnBreakpoint):
+
+2010-08-24 Ariya Hidayat <ariya@sencha.com>
+
+ Reviewed by Simon Hausmann.
+
+ [Qt] Blur shadow for rectangle fill
+ https://bugs.webkit.org/show_bug.cgi?id=44488
+
+ Refactor fillRect() function to support blur radius in the shadow.
+
+ * platform/graphics/qt/GraphicsContextQt.cpp:
+ (WebCore::GraphicsContext::fillRect):
+
+2010-08-24 Nikolas Zimmermann <nzimmermann@rim.com>
+
+ Reviewed by Dirk Schulze
+
+ clip-path does not work inside mask element
+ https://bugs.webkit.org/show_bug.cgi?id=41428
+
+ Add new tests covering nesting of clippers and maskers, with different unitTypes for the content coordinate system.
+ Scale all ImageBuffer content to take into account that ImageBuffers use integer based sizes, where the content
+ is floating-point sized. This compensates rounded errors, when scaling the document.
+
+ Tests: svg/clip-path/clip-in-mask-objectBoundingBox.svg
+ svg/clip-path/clip-in-mask-userSpaceOnUse.svg
+ svg/clip-path/clip-in-mask.svg
+ svg/clip-path/deep-nested-clip-in-mask-different-unitTypes.svg
+ svg/clip-path/deep-nested-clip-in-mask-panning.svg
+ svg/clip-path/deep-nested-clip-in-mask.svg
+ svg/clip-path/nested-clip-in-mask-image-based-clipping.svg
+ svg/clip-path/nested-clip-in-mask-path-and-image-based-clipping.svg
+ svg/clip-path/nested-clip-in-mask-path-based-clipping.svg
+
+ * rendering/RenderSVGResourceClipper.cpp:
+ (WebCore::RenderSVGResourceClipper::applyResource): Return the value of applyClippingToContext, instead of always true.
+ (WebCore::RenderSVGResourceClipper::applyClippingToContext): Moved some code from createClipData, to avoid having to pass 5 arguments to createClipData.
+ (WebCore::RenderSVGResourceClipper::drawContentIntoMaskImage): Renamed from createClipData.
+ * rendering/RenderSVGResourceClipper.h:
+ * rendering/RenderSVGResourceGradient.cpp:
+ (WebCore::createMaskAndSwapContextForTextGradient): Pass absoluteTargetRect to createImageBuffer.
+ (WebCore::clipToTextMask): Ditto.
+ * rendering/RenderSVGResourceMasker.cpp:
+ (WebCore::RenderSVGResourceMasker::applyResource): Ditto.
+ (WebCore::RenderSVGResourceMasker::drawContentIntoMaskImage): Pass content transformation to renderSubtreeToImageBuffer, to support nesting objectBoundingBox resources.
+ * rendering/RenderSVGResourcePattern.cpp:
+ (WebCore::RenderSVGResourcePattern::applyResource): Adapt to calculateTransformationToOutermostSVGCoordinateSystem changes. AffineTransform is now passed as reference.
+ (WebCore::RenderSVGResourcePattern::createTileImage): ImageBuffer content scaling is now handled by createImageBuffer.
+ * rendering/SVGImageBufferTools.cpp:
+ (WebCore::SVGImageBufferTools::calculateTransformationToOutermostSVGCoordinateSystem): Renamed. Don't return an AffineTransform copy, but instead pass it as reference.
+ (WebCore::SVGImageBufferTools::createImageBuffer): Always scale the ImageBuffer content, to compensate rounding effects (code was only present in patterns so far).
+ Now also needs the 'absoluteTargetRect' parameter, not only 'clampedAbsoluteTargetRect'.
+ (WebCore::SVGImageBufferTools::renderSubtreeToImageBuffer): Moved from SVGRenderSupport.
+ (WebCore::SVGImageBufferTools::clipToImageBuffer): Pass ImageBuffer as OwnPtr reference, to allow to clear it under certain circumstances (see comment).
+ (WebCore::SVGImageBufferTools::clampedAbsoluteTargetRectForRenderer): Remove AffineTransform parameter, absoluteTargetRect is calculated before passing into this function.
+ * rendering/SVGImageBufferTools.h:
+ * rendering/SVGRenderSupport.cpp:
+ (WebCore::SVGRenderSupport::prepareToRenderSVGContent): Important change, respect the RenderSVGResourceClipper::applyResource() return value!
+ * rendering/SVGRenderSupport.h:
+ * svg/SVGFEImageElement.cpp:
+ (WebCore::SVGFEImageElement::build): renderSubtreeToImage now lives in SVGImageBufferTools, adapt code.
+
+2010-08-24 Andrei Popescu <andreip@dhcp-172-16-14-12.lon.corp.google.com>
+
+ Reviewed by Jeremy Orlow.
+
+ [IndexedDB] IDBTransaction is missing the implementation for objectStore method
+ https://bugs.webkit.org/show_bug.cgi?id=44446
+
+ * storage/IDBDatabaseBackendImpl.cpp:
+ (WebCore::IDBDatabaseBackendImpl::transaction):
+ * storage/IDBTransactionBackendImpl.cpp:
+ (WebCore::IDBTransactionBackendImpl::create):
+ (WebCore::IDBTransactionBackendImpl::IDBTransactionBackendImpl):
+ (WebCore::IDBTransactionBackendImpl::objectStore):
+ * storage/IDBTransactionBackendImpl.h:
+ * storage/IDBTransactionCoordinator.cpp:
+ (WebCore::IDBTransactionCoordinator::createTransaction):
+ * storage/IDBTransactionCoordinator.h:
+
+2010-08-24 Andreas Kling <andreas.kling@nokia.com>
+
+ Reviewed by Tor Arne Vestbø.
+
+ Disallow setting Document.xmlVersion to unsupported versions
+ https://bugs.webkit.org/show_bug.cgi?id=44494
+
+ Added XMLDocumentParser::supportsXMLVersion() - only returns true for "1.0"
+ in both implementations.
+
+ * dom/Document.cpp:
+ (WebCore::Document::setXMLVersion): Throw NOT_SUPPORTED_ERR
+ if XMLDocumentParser::supportsXMLVersion() returns false for the version.
+ * dom/XMLDocumentParser.h:
+ * dom/XMLDocumentParserLibxml2.cpp:
+ (WebCore::XMLDocumentParser::supportsXMLVersion):
+ * dom/XMLDocumentParserQt.cpp:
+ (WebCore::XMLDocumentParser::supportsXMLVersion):
+
+2010-08-24 Laszlo Gombos <laszlo.1.gombos@nokia.com>
+
+ Reviewed by Simon Hausmann.
+
+ [Qt][Symbian] Make sure WebKit headers are included before platform headers on Symbian
+ https://bugs.webkit.org/show_bug.cgi?id=31273
+
+ On Symbian PREPEND_INCLUDEPATH is the best way to make sure that
+ WebKit headers are included before platform headers. On all other
+ platforms continue to use INCLUDEPATH (as before).
+
+ This patch also removed the workarounds that are put in place
+ now that we have a better solution.
+
+ No new tests as there is no new functionality.
+
+ * WebCore.pro:
+
+2010-08-24 Ariya Hidayat <ariya@sencha.com>
+
+ Reviewed by Kenneth Rohde Christiansen.
+
+ [Qt] Support text-shadow blur
+ https://bugs.webkit.org/show_bug.cgi?id=19728
+
+ Implement blur for text shadow using the shadow layer in r65782.
+
+ * platform/graphics/qt/ContextShadow.cpp:
+ (WebCore::ContextShadow::beginShadowLayer):
+ * platform/graphics/qt/FontQt.cpp:
+ (WebCore::drawTextCommon):
+
+2010-08-23 Andreas Kling <andreas.kling@nokia.com>
+
+ Reviewed by Tor Arne Vestbø.
+
+ setAttributeNS() should throw NAMESPACE_ERR for prefixed qualifiedName with null namespace
+ https://bugs.webkit.org/show_bug.cgi?id=44432
+
+ Test: fast/dom/setAttributeNS-prefix-and-null-namespace.html
+
+ * dom/Element.cpp:
+ (WebCore::Element::setAttributeNS): Throw NAMESPACE_ERR if namespace is null
+ and the qualifiedName has a prefix.
+
+2010-08-24 Adam Barth <abarth@webkit.org>
+
+ Build fix. leakPtr doesn't exist, contrary to my dreams.
+
+ * storage/IDBKeyTree.h:
+ (WebCore::::put):
+ * storage/IDBPendingTransactionMonitor.cpp:
+ (WebCore::IDBPendingTransactionMonitor::addPendingTransaction):
+
+2010-08-24 Adam Barth <abarth@webkit.org>
+
+ Reviewed by Eric Seidel.
+
+ Deploy adoptPtr in WebCore/storage
+ https://bugs.webkit.org/show_bug.cgi?id=44491
+
+ There are still some naked news for a future patch. The next step is
+ to make create methods.
+
+ * storage/Database.cpp:
+ (WebCore::DatabaseCreationCallbackTask::create):
+ (WebCore::DerefContextTask::create):
+ (WebCore::DeliverPendingCallbackTask::create):
+ * storage/DatabaseSync.cpp:
+ (WebCore::CloseSyncDatabaseOnContextThreadTask::create):
+ * storage/DatabaseTask.h:
+ (WebCore::Database::DatabaseOpenTask::create):
+ (WebCore::Database::DatabaseCloseTask::create):
+ (WebCore::Database::DatabaseTransactionTask::create):
+ (WebCore::Database::DatabaseTableNamesTask::create):
+ * storage/DatabaseThread.cpp:
+ (WebCore::DatabaseThread::DatabaseThread):
+ * storage/DatabaseTracker.cpp:
+ (WebCore::DatabaseTracker::populateOrigins):
+ (WebCore::DatabaseTracker::addOpenDatabase):
+ * storage/IDBKeyTree.h:
+ (WebCore::::put):
+ * storage/IDBPendingTransactionMonitor.cpp:
+ (WebCore::IDBPendingTransactionMonitor::addPendingTransaction):
+ * storage/LocalStorageTask.h:
+ (WebCore::LocalStorageTask::createImport):
+ (WebCore::LocalStorageTask::createSync):
+ (WebCore::LocalStorageTask::createDeleteEmptyDatabase):
+ (WebCore::LocalStorageTask::createTerminate):
+ * storage/LocalStorageThread.cpp:
+ (WebCore::LocalStorageThread::create):
+ * storage/SQLTransaction.cpp:
+ (WebCore::SQLTransaction::openTransactionAndPreflight):
+ * storage/SQLTransactionSync.cpp:
+ (WebCore::SQLTransactionSync::SQLTransactionSync):
+ (WebCore::SQLTransactionSync::begin):
+ * storage/StorageNamespaceImpl.cpp:
+ (WebCore::StorageNamespaceImpl::copy):
+
+2010-08-24 Ilya Tikhonovsky <loislo@chromium.org>
+
+ Reviewed by Yury Semikhatsky.
+
+ WebInspector: setAttachedWindow was modified at r65809 but it should be implemented another way.
+ https://bugs.webkit.org/show_bug.cgi?id=44493
+
+ * inspector/Inspector.idl:
+ * inspector/InspectorController.cpp:
+ * inspector/InspectorController.h:
+ * inspector/InspectorFrontendClientLocal.cpp:
+ (WebCore::InspectorFrontendClientLocal::setAttachedWindow):
+
+2010-08-23 Eric Seidel <eric@webkit.org>
+
+ Reviewed by Adam Barth.
+
+ Use new HTML5 TreeBuilder for fragment parsing
+ https://bugs.webkit.org/show_bug.cgi?id=44475
+
+ The HTML5 TreeBuilder is ready to be used for all parsing
+ including fragments! This is the last change to move trunk
+ off of the LegacyHTMLTreeBuilder. We'll go through and
+ delete the thousands of lines of code supporting the old
+ parser in a separate patch.
+
+ This is covered by many layout tests.
+
+ * html/HTMLTreeBuilder.cpp:
+
+2010-08-23 Adam Barth <abarth@webkit.org>
+
+ Reviewed by Eric Seidel.
+
+ HTMLScriptRunner::create
+ https://bugs.webkit.org/show_bug.cgi?id=44474
+
+ * html/HTMLDocumentParser.cpp:
+ (WebCore::HTMLDocumentParser::HTMLDocumentParser):
+ * html/HTMLScriptRunner.h:
+ (WebCore::HTMLScriptRunner::create):
+
+2010-08-23 Adam Barth <abarth@webkit.org>
+
+ Reviewed by Eric Seidel.
+
+ HTMLTreeBuilder should use adoptPtr
+ https://bugs.webkit.org/show_bug.cgi?id=44473
+
+ We should really use this pattern everywhere.
+
+ * html/HTMLDocumentParser.cpp:
+ (WebCore::HTMLDocumentParser::HTMLDocumentParser):
+ * html/HTMLTreeBuilder.h:
+ (WebCore::HTMLTreeBuilder::create):
+
+2010-08-23 Patrick Gansterer <paroga@paroga.com>
+
+ Reviewed by Adam Roben.
+
+ Set the ResourceResponse HTTP headers in RessourceHandleWin
+ https://bugs.webkit.org/show_bug.cgi?id=44444
+
+ * platform/network/win/ResourceHandleWin.cpp:
+ (WebCore::queryHTTPHeader):
+ (WebCore::ResourceHandle::onRequestComplete):
+
+2010-08-23 Patrick Gansterer <paroga@paroga.com>
+
+ Reviewed by Adam Roben.
+
+ Support all available biBitCount values in BitmapInfo
+ https://bugs.webkit.org/show_bug.cgi?id=43724
+
+ Add an enum with all possible values for biBitCount.
+ Also remove explicit initialization of bmiHeader members,
+ because that is already done in the constructor.
+
+ * platform/win/BitmapInfo.cpp: Added property svn:eol-style.
+ (WebCore::bitmapInfoForSize):
+ (WebCore::BitmapInfo::create):
+ (WebCore::BitmapInfo::createBottomUp):
+ * platform/win/BitmapInfo.h: Added property svn:eol-style.
+ (WebCore::BitmapInfo::):
+ (WebCore::BitmapInfo::bytesPerLine):
+ (WebCore::BitmapInfo::paddedBytesPerLine):
+ (WebCore::BitmapInfo::paddedWidth):
+ * platform/win/PopupMenuWin.cpp:
+ (WebCore::PopupMenuWin::paint):
+
+2010-08-23 Kent Tamura <tkent@chromium.org>
+
+ Unreviewed, build fix for r65852.
+
+ * rendering/RenderTextControlSingleLine.cpp:
+ (WebCore::RenderTextControlSingleLine::createSubtreeIfNeeded):
+ * rendering/TextControlInnerElements.cpp:
+ (WebCore::InputFieldSpeechButtonElement::InputFieldSpeechButtonElement):
+ (WebCore::InputFieldSpeechButtonElement::create):
+ * rendering/TextControlInnerElements.h:
+
+2010-08-23 Ryosuke Niwa <rniwa@webkit.org>
+
+ Reviewed by Eric Seidel.
+
+ MarkupAccumulator::appendStartMarkup should be broken down into pieces
+ https://bugs.webkit.org/show_bug.cgi?id=44288
+
+ Extracted appendText, appendComment, appendProcessingInstruction, appendElement and appendCDATASection.
+ Also simplified the conditionals in appendText.
+
+ No new tests are added since this is a cleanup.
+
+ * editing/markup.cpp:
+ (WebCore::MarkupAccumulator::appendText):
+ (WebCore::MarkupAccumulator::appendComment):
+ (WebCore::MarkupAccumulator::appendProcessingInstruction):
+ (WebCore::MarkupAccumulator::appendElement):
+ (WebCore::MarkupAccumulator::appendCDATASection):
+ (WebCore::MarkupAccumulator::appendStartMarkup):
+
+2010-08-23 Simon Fraser <simon.fraser@apple.com>
+
+ Reviewed by Alexey Proskuryakov.
+
+ TreeWalker is not calling acceptNode function in filter object
+ https://bugs.webkit.org/show_bug.cgi?id=35296
+
+ Fix incorrect shadowing of the 'function' variable, which could result
+ in badness when asking for arguments.callee.
+
+ * bindings/js/JSNodeFilterCondition.cpp:
+ (WebCore::JSNodeFilterCondition::acceptNode):
+
+2010-08-23 Darin Adler <darin@apple.com>
+
+ Reviewed by Geoff Garen.
+
+ Changed type of Node::parentNode to ContainerNode so we don't have to cast,
+ since parent are all containers.
+
+ * css/CSSStyleSelector.h: Changed m_parentNode to ContainerNode*.
+
+ * dom/Document.h: Fixed the type of TreeShared in the Node constructor.
+ Yes, it's here.
+
+ * dom/Node.cpp:
+ (WebCore::Node::eventParentNode): Removed now-unneeded typecast dance.
+ (WebCore::eventTargetAsSVGElementInstance):Changed type to ContainerNode*.
+
+ * dom/Node.h: Made Node inherit from TreeShared<ContainerNode> instead of
+ from TreeShared<Node>. Removed bogus comment. Changed return type of parentNode
+ and shadowParentNode functions to ContainerNode*. Fixed using to use
+ TreeShared<ContainerNode>.
+
+ * dom/Position.h: Include ContainerNode.h instead of Node.h.
+
+ * html/HTMLConstructionSite.cpp:
+ (WebCore::HTMLConstructionSite::findFosterSite): Removed now-unneeded typecast.
+
+ * rendering/MediaControlElements.h:
+ * rendering/SVGShadowTreeElements.h:
+ * rendering/TextControlInnerElements.h:
+ Changed return type of shadowParentNode functions to ContainerNode.
+
+ * rendering/RenderMeter.cpp:
+ (WebCore::RenderMeter::updatePartsState): Cast the node to HTMLElement* before
+ passing it to the function that creates the shadow element. We know the node is
+ a HTMLMeterElement, but the node function doesn't know that.
+ * rendering/RenderProgress.cpp:
+ (WebCore::RenderProgress::updatePartsState): Ditto.
+ * rendering/RenderSlider.cpp:
+ (WebCore::SliderThumbElement::SliderThumbElement): More of the same.
+ (WebCore::SliderThumbElement::create): Ditto.
+ (WebCore::RenderSlider::updateFromElement): Ditto.
+ * rendering/RenderTextControl.cpp:
+ (WebCore::RenderTextControl::createSubtreeIfNeeded): Ditto.
+ * rendering/RenderTextControlSingleLine.cpp:
+ (WebCore::RenderTextControlSingleLine::createSubtreeIfNeeded): Ditto.
+ * rendering/SVGShadowTreeElements.cpp:
+ (WebCore::SVGShadowTreeRootElement::SVGShadowTreeRootElement): Ditto.
+ (WebCore::SVGShadowTreeRootElement::shadowParentNode): Ditto.
+ * rendering/ShadowElement.cpp:
+ (WebCore::ShadowBlockElement::create): Ditto.
+ (WebCore::ShadowBlockElement::ShadowBlockElement): Ditto.
+ (WebCore::ShadowBlockElement::createForPart): Ditto.
+ (WebCore::ShadowInputElement::create): Ditto.
+ (WebCore::ShadowInputElement::ShadowInputElement): Ditto.
+ * rendering/ShadowElement.h:
+ (WebCore::ShadowElement::ShadowElement): Ditto.
+ (WebCore::ShadowElement::shadowParent): Ditto.
+ (WebCore::ShadowElement::shadowParentNode): Ditto.
+ * rendering/TextControlInnerElements.cpp:
+ (WebCore::TextControlInnerElement::TextControlInnerElement): Ditto.
+ (WebCore::TextControlInnerElement::create): Ditto.
+ (WebCore::TextControlInnerTextElement::TextControlInnerTextElement): Ditto.
+ (WebCore::TextControlInnerTextElement::create): Ditto.
+ (WebCore::SpinButtonElement::SpinButtonElement): Ditto.
+ (WebCore::SpinButtonElement::create): Ditto.
+
+ * svg/SVGElement.cpp:
+ (WebCore::SVGElement::eventParentNode): Removed now-unneeded typecast.
+
+ * svg/SVGStyledElement.cpp:
+ (WebCore::SVGStyledElement::title): Changed type to ContainerNode*.
+
+2010-08-23 Martin Robinson <mrobinson@igalia.com>
+
+ Reviewed by Gustavo Noronha Silva.
+
+ [GTK] The Mozilla theme drawing code incorrectly renders scrollbar backgrounds
+ https://bugs.webkit.org/show_bug.cgi?id=44388
+
+ No new tests as this functionality is currently unused. When the
+ the new scrollbar theme code lands for GTK+, this will be tested
+ by scrollbar pixel tests.
+
+ * platform/gtk/gtk2drawing.c: Expose a method to paint scrolled window
+ backgrounds and disable incorrect rendering of scrollbar trough backgrounds.
+ (moz_gtk_scrolled_window_paint): Added.
+ (moz_gtk_scrollbar_trough_paint): Disable incorrect background render.
+ * platform/gtk/gtkdrawing.h: Add scrolled window widget type in the enum.
+
+2010-08-23 Martin Robinson <mrobinson@igalia.com>
+
+ Reviewed by Gustavo Noronha Silva.
+
+ [GTK] The Mozilla theme drawing API should expose extra information about scrollbar geometry
+ https://bugs.webkit.org/show_bug.cgi?id=44385
+
+ Expose the trough_under_steppers property in MozGtkScrollbarMetrics.
+
+ No new tests as this does not change functionality.
+
+ * platform/gtk/gtk2drawing.c: Set the trough_under_steppers member when accessing theme data.
+ * platform/gtk/gtkdrawing.h: Add the trough_under_steppers member.
+
+2010-08-23 Darin Adler <darin@apple.com>
+
+ Reviewed by Geoff Garen.
+
+ Parser DOM tree manipulation functions do not need to be virtual.
+
+ * dom/ContainerNode.h: Made parserAddChild, parserRemoveChild, and
+ parserInsertBefore non-virtual.
+
+ * dom/Node.cpp: Removed the parserAddChild, parserRemoveChild, and
+ parserInsertBefore functions, which should never have been in the Node class.
+ * dom/Node.h: Ditto.
+
+ * html/HTMLConstructionSite.cpp:
+ (WebCore::HTMLConstructionSite::attach): Changed argument type to ContainerNode*
+ because we never need to attach a child to a non-container node.
+ (WebCore::HTMLConstructionSite::findFosterSite): Cast the result of the parent
+ function to ContainerNode*. A parent is always guaranteed to be a container, but
+ the parent function returns a Node* so that callers can use it without including
+ ContainerNode's header. That seems like something we can easily fix later.
+
+ * html/HTMLConstructionSite.h: Changed AttachmentSite::parent and the
+ attach function to ContainerNode* instead of Node*.
+
+2010-08-23 Adam Barth <abarth@webkit.org>
+
+ Reviewed by Eric Seidel.
+
+ editing/pasteboard/bad-placeholder.html fails with --html5-treebuilder
+ https://bugs.webkit.org/show_bug.cgi?id=44463
+
+ The problem here is that using the documentElement as the context puts
+ the tree builder into the BeforeHead insertion mode, which strips
+ leading spaces. This code is confused about what it wants, but it
+ certainly doesn't want to be in that insertion mode. Looking through
+ the callers, they'd much rather be in the InBody insertion mode. We
+ can get them there by creating a fake body element as the context
+ element.
+
+ In the long term, all this code needs to be changed to move away from
+ deprecatedCreateContextualFragment, which does a bunch of nasty stuff
+ like removing certain kinds of elements. However, that's a battle for
+ another day.
+
+ * editing/markup.cpp:
+ (WebCore::createFragmentFromMarkup):
+
+2010-08-23 Adam Barth <abarth@webkit.org>
+
+ Reviewed by Eric Seidel.
+
+ fast/xsl/default-html.html fails with HTML5 fragment parsing
+ https://bugs.webkit.org/show_bug.cgi?id=44450
+
+ This patch is a step down a trail of tears. As far as I can tell,
+ there's no spec for XSLTProcessor.transformToFragment. This patch
+ attempts to infer the proper behavior from test cases and the Mozilla
+ wiki.
+
+ * xml/XSLTProcessor.cpp:
+ (WebCore::createFragmentFromSource):
+
+2010-08-23 Adam Barth <abarth@webkit.org>
+
+ Reviewed by Eric Seidel.
+
+ editing/pasteboard/paste-visible-script.html is broken with --html5-treebuilder
+ https://bugs.webkit.org/show_bug.cgi?id=44457
+
+ Turns out there are two more checks we need for fragment scripting
+ permission. Not the most beautiful design, but it seems work.
+
+ * html/HTMLConstructionSite.cpp:
+ (WebCore::HTMLConstructionSite::insertScriptElement):
+ * html/HTMLTreeBuilder.cpp:
+ (WebCore::HTMLTreeBuilder::processEndTag):
+
+2010-08-23 Eric Seidel <eric@webkit.org>
+
+ Reviewed by Adam Barth.
+
+ fast/dom/script-innerHTML-x.xhtml fails when run with the HTML5 TreeBuilder in fragment mode
+ https://bugs.webkit.org/show_bug.cgi?id=44447
+
+ This special handling for script/style used to exist in
+ setInnerHTML. HTML5 moves this logic into the HTML and XML
+ parsers instead of in setInnerHTML.
+
+ In order to share this logic between WebKit's two XML parsers
+ I had to clean up a bit of the libxml2 parser and add a
+ new appendFragmentSource method.
+
+ Covered by fast/dom/script-innerHTML-x.xhtml.
+
+ * dom/XMLDocumentParser.cpp:
+ (WebCore::XMLDocumentParser::end):
+ - Now that libxml2 is calling finish() for fragments (Qt already was)
+ I went through and removed this unneeded style update after fragment parsing.
+ (WebCore::XMLDocumentParser::parseDocumentFragment):
+ - Yay for shared code!
+ - This is where I added the style/script hack moved from setInnerHTML.
+ * dom/XMLDocumentParser.h:
+ - Fix indent.
+ * dom/XMLDocumentParserLibxml2.cpp:
+ - Removed parseDocumentFragment and moved necessary libxml-specific
+ logic into appendFragmentSource.
+ (WebCore::XMLDocumentParser::appendFragmentSource):
+ * dom/XMLDocumentParserQt.cpp:
+ (WebCore::XMLDocumentParser::appendFragmentSource):
+
+2010-08-23 Kenneth Russell <kbr@google.com>
+
+ Reviewed by Dimitri Glazkov.
+
+ Remove references to ArrayBuffer and ArrayBufferView from GraphicsContext3D
+ https://bugs.webkit.org/show_bug.cgi?id=44455
+
+ Updated Safari, Qt and Chromium WebGL ports to avoid referencing
+ ArrayBuffer and ArrayBufferView types from GraphicsContext3D.
+
+ Ran all WebGL layout tests; no new regressions. Built and tested
+ WebKit on Mac OS X; built Chromium on Mac OS X and Linux.
+
+ * html/canvas/WebGLBuffer.cpp:
+ * html/canvas/WebGLBuffer.h:
+ * html/canvas/WebGLRenderingContext.cpp:
+ (WebCore::WebGLRenderingContext::bufferData):
+ (WebCore::WebGLRenderingContext::bufferSubData):
+ (WebCore::WebGLRenderingContext::texImage2D):
+ (WebCore::WebGLRenderingContext::texSubImage2D):
+ (WebCore::WebGLRenderingContext::simulateVertexAttrib0):
+ * platform/graphics/GraphicsContext3D.cpp:
+ (WebCore::GraphicsContext3D::extractTextureData):
+ * platform/graphics/GraphicsContext3D.h:
+ * platform/graphics/chromium/GLES2Canvas.cpp:
+ (WebCore::GLES2Canvas::getQuadVertices):
+ * platform/graphics/mac/GraphicsContext3DMac.mm:
+ (WebCore::GraphicsContext3D::bufferData):
+ (WebCore::GraphicsContext3D::bufferSubData):
+ * platform/graphics/qt/GraphicsContext3DQt.cpp:
+ (WebCore::GraphicsContext3D::bufferData):
+ (WebCore::GraphicsContext3D::bufferSubData):
+
+2010-08-20 Stephen White <senorblanco@chromium.org>
+
+ Reviewed by Kenneth Russell.
+
+ [CHROMIUM] Fix some failing layout tests w/ACCELERATED_2D_CANVAS
+ https://bugs.webkit.org/show_bug.cgi?id=44346
+
+ LayoutTests/fast/canvas/canvas-incremental-repaint.html (top middle
+ pane).
+ Failing because we were not applying the CTM in clearRect(). Now using
+ the fast path when the CTM is identity, and a fillRect() for the rest.
+ LayoutTests/fast/canvas/canvas-strokeRect.html
+ LayoutTests/fast/canvas/shadow-offset-[1-7].html
+ Failing because we weren't switching to the software path when a
+ shadow is present.
+ Also refactor the two versions of fillRect(), and use TRIANGLE_STRIP
+ strip instead of TRIANGLES, which lets us get rid of the element array
+ and use drawArrays() instead of drawElements().
+
+ Covered by the above layout tests.
+
+ * platform/graphics/chromium/GLES2Canvas.cpp:
+ (WebCore::GLES2Canvas::GLES2Canvas):
+ (WebCore::GLES2Canvas::~GLES2Canvas):
+ Remove m_quadIndices (now unused).
+ (WebCore::GLES2Canvas::clearRect):
+ Use a glClear() fast path for the identity-CTM clear, and fillRect()
+ for the rest.
+ (WebCore::GLES2Canvas::fillRect):
+ Refactor the two versions of fillRect().
+ (WebCore::GLES2Canvas::drawTexturedRect):
+ (WebCore::GLES2Canvas::drawTexturedRectTile):
+ Get rid of the ELEMENT_ARRAY_BUFFER bind. Use drawArrays() instead of
+ drawElements().
+ (WebCore::GLES2Canvas::getQuadVertices):
+ Re-order the vertices so they form a triangle strip.
+ * platform/graphics/chromium/GLES2Canvas.h:
+ Remove m_quadIndices (now unused).
+ * platform/graphics/skia/GraphicsContextSkia.cpp:
+ (WebCore::GraphicsContext::fillRect):
+ Check for a draw looper (shadow), and drop to the software path.
+
+2010-08-23 Patrick Gansterer <paroga@paroga.com>
+
+ Reviewed by Adam Roben.
+
+ Move filehandling into fileLoadTimer callback
+ https://bugs.webkit.org/show_bug.cgi?id=43714
+
+ Also add mimetype detection for local files.
+
+ * platform/network/ResourceHandleInternal.h:
+ (WebCore::ResourceHandleInternal::ResourceHandleInternal):
+ * platform/network/win/ResourceHandleWin.cpp:
+ (WebCore::ResourceHandle::start):
+ (WebCore::ResourceHandle::fileLoadTimer):
+
+2010-08-23 Iain Merrick <husky@google.com>
+
+ Reviewed by Steve Block.
+
+ Update JNI bridge for V8 after renaming of JavaString::utf8().
+ https://bugs.webkit.org/show_bug.cgi?id=44419
+
+ This fixes the build on Android. No new functionality, so no new tests.
+
+ * bridge/jni/v8/JNIBridgeV8.cpp:
+ (JavaField::JavaField):
+ * bridge/jni/v8/JNIBridgeV8.h:
+ (JSC::Bindings::JavaField::type):
+ * bridge/jni/v8/JavaClassV8.cpp:
+ (JavaClass::JavaClass):
+ * bridge/jni/v8/JavaNPObjectV8.cpp:
+ (JSC::Bindings::JavaNPObjectGetProperty):
+ * bridge/jni/v8/JavaStringV8.h:
+ (JSC::Bindings::JavaStringImpl::utf8):
+
+2010-08-23 Mihai Parparita <mihaip@chromium.org>
+
+ Reviewed by David Hyatt.
+
+ Assertion failure in FrameView::layout when modifying the DOM during
+ pagehide with PageCache enabled
+ https://bugs.webkit.org/show_bug.cgi?id=43152
+
+ Always unschedule any pending relayouts when changing the view, not just
+ when we're not using the page cache. Otherwise touching the DOM during
+ the pagehide handler can lead to layouts that will be done by the time
+ the view has changed, which triggers an assert.
+
+ Test: fast/loader/unschedule-relayout-after-unload.html
+
+ * page/Frame.cpp:
+ (WebCore::Frame::setView): move unscheduleRelayout outside page cache
+ check.
+ * page/FrameView.cpp:
+ (WebCore::FrameView::layout): remove early return now that assert
+ should be correct (and the referenced rdar:// got fixed).
+
+2010-08-23 Abhishek Arya <inferno@chromium.org>
+
+ Reviewed by Dimitri Glazkov.
+
+ Fix security origin calculation in createPattern. Need to use
+ cachedImage->response().url() instead of cachedImage->url().
+ https://bugs.webkit.org/show_bug.cgi?id=44399.
+
+ Test: http/tests/security/canvas-remote-read-remote-image-redirect.html
+
+ * html/canvas/CanvasRenderingContext2D.cpp:
+ (WebCore::CanvasRenderingContext2D::createPattern):
+
+2010-08-23 Simon Fraser <simon.fraser@apple.com>
+
+ Reviewed by Alexey Proskuryakov.
+
+ TreeWalker is not calling acceptNode function in filter object
+ https://bugs.webkit.org/show_bug.cgi?id=35296
+
+ We only accepted raw functions as the NodeFilter on TreeWalker. Fix this to
+ look for an 'acceptNode' function on the filter object, and use that if present.
+ Also throw an exception if the filter object does not have an acceptNode function.
+
+ Test: fast/dom/TreeWalker/acceptNode-filter.html
+
+ * bindings/js/JSNodeFilterCondition.cpp:
+ (WebCore::JSNodeFilterCondition::acceptNode):
+
+2010-08-23 Sheriff Bot <webkit.review.bot@gmail.com>
+
+ Unreviewed, rolling out r65814.
+ http://trac.webkit.org/changeset/65814
+ https://bugs.webkit.org/show_bug.cgi?id=44443
+
+ broke svg/custom/missing-xlink.svg (Requested by kling on
+ #webkit).
+
+ * dom/Element.cpp:
+ (WebCore::Element::setAttributeNS):
+
+2010-08-23 Jian Li <jianli@chromium.org>
+
+ Reviewed by Darin Fisher.
+
+ Handle blob resource.
+ https://bugs.webkit.org/show_bug.cgi?id=43941
+
+ To provide lower level blob reosurce handling for all possible ports,
+ BlobResourceHandle derived from ResourceHandle is implemented. It provides
+ both synchronous and asynchronous resource loading for blob URL.
+
+ BlobResourceHandle needs to create a FileStreamProxy instance in order to
+ asynchronous file stream operation. To achive this, a hook createAsyncFileStream
+ is added to ResourceHandleClient interface. When ResourceLoader implements
+ ths hook, it creates and returns FileStreamProxy.
+
+ BlobResourceHandle.* is not added to chromium port since it will implement
+ its own blob resource handling.
+
+ * Android.mk:
+ * CMakeLists.txt:
+ * GNUmakefile.am:
+ * WebCore.pro:
+ * WebCore.vcproj/WebCore.vcproj:
+ * WebCore.xcodeproj/project.pbxproj:
+ * loader/ResourceLoader.cpp:
+ (WebCore::ResourceLoader::createAsyncFileStream): Create and return FileStreamProxy.
+ * loader/ResourceLoader.h:
+ * page/SecurityOrigin.cpp: Add the support to get and validate the origin of blob URL.
+ (WebCore::SecurityOrigin::create):
+ (WebCore::SecurityOrigin::canLoad):
+ * platform/network/BlobRegistryImpl.cpp:
+ (WebCore::BlobRegistryImpl::appendStorageItems): Fix a bug that the length is not subtracted.
+ * platform/network/BlobResourceHandle.cpp: Added.
+ * platform/network/BlobResourceHandle.h: Added.
+ * platform/network/HTTPParsers.cpp:
+ (WebCore::parseRange):
+ * platform/network/HTTPParsers.h:
+ * platform/network/ResourceHandle.cpp: Hook up with asynchronous blob resource handling.
+ (WebCore::ResourceHandle::create):
+ * platform/network/ResourceHandle.h:
+ * platform/network/ResourceHandleClient.h:
+ (WebCore::ResourceHandleClient::createAsyncFileStream): Add a hook.
+ * platform/network/mac/ResourceHandleMac.mm:
+ (WebCore::ResourceHandle::loadResourceSynchronously): Hook up with synchronous blob resource handling.
+
+2010-08-23 Jian Li <jianli@chromium.org>
+
+ Reviewed by David Levin.
+
+ Remove unneeded BlobRegistryImpl.* and WebBlobRegistryImpl.* from
+ chromium project files.
+ https://bugs.webkit.org/show_bug.cgi?id=44442
+
+ * WebCore.gypi:
+
+2010-08-23 Adam Barth <abarth@webkit.org>
+
+ Reviewed by Eric Seidel.
+
+ Many LayoutTests crash when run with --html5-treebuilder
+ https://bugs.webkit.org/show_bug.cgi?id=44440
+
+ Our list of special tags is out of sync with the HTML5 spec. This
+ patch adds HTML to the list, which fixs a ton of crashers when parsing
+ fragments. We neet to sync up the list at some point, but we want to
+ make sure we have test coverage for all those changes, so I've left
+ that for a future patch.
+
+ * html/HTMLTreeBuilder.cpp:
+
+2010-08-23 Ilya Tikhonovsky <loislo@chromium.org>
+
+ Reviewed by Pavel Feldman.
+
+ WebInspector: Context menu in Scripts panel was broken.
+ https://bugs.webkit.org/show_bug.cgi?id=44431
+
+ * inspector/InspectorFrontendHost.cpp:
+ (WebCore::FrontendMenuProvider::contextMenuItemSelected):
+ (WebCore::FrontendMenuProvider::contextMenuCleared):
+
+2010-08-23 Andreas Kling <andreas.kling@nokia.com>
+
+ Reviewed by Tor Arne Vestbø.
+
+ setAttributeNS() should throw NAMESPACE_ERR for prefixed qualifiedName with null namespace
+ https://bugs.webkit.org/show_bug.cgi?id=44432
+
+ Test: fast/dom/setAttributeNS-prefix-and-null-namespace.html
+
+ * dom/Element.cpp:
+ (WebCore::Element::setAttributeNS): Throw NAMESPACE_ERR if namespace is null
+ and the qualifiedName has a prefix.
+
+2010-08-23 Ryuan Choi <ryuan.choi@samsung.com>
+
+ Reviewed by Antonio Gomes.
+
+ [EFL] rendering was broken when missing plugin.
+ https://bugs.webkit.org/show_bug.cgi?id=43395
+
+ Implement RenderThemeEfl::systemFont to render "Missing plugin" when we
+ don't have proper plugin.
+ In this case, RenderEmbeddedObject::paintReplaced call systemFont and
+ pass returned font to GraphicsContext.
+
+ * platform/efl/RenderThemeEfl.cpp:
+ (WebCore::RenderThemeEfl::setDefaultFontSize):
+ (WebCore::RenderThemeEfl::systemFont):
+ * platform/efl/RenderThemeEfl.h:
+
+2010-08-23 Pavel Podivilov <podivilov@chromium.org>
+
+ Reviewed by Pavel Feldman.
+
+ Web Inspector: remove javascript breakpoint specific code from BreakpointSidebarPane
+ https://bugs.webkit.org/show_bug.cgi?id=44327
+
+ * inspector/front-end/BreakpointManager.js:
+ (WebInspector.BreakpointManager.prototype.setBreakpoint):
+ (WebInspector.BreakpointManager.prototype.restoredBreakpoint):
+ (WebInspector.BreakpointManager.prototype._setBreakpoint):
+ (WebInspector.BreakpointManager.prototype._removeBreakpoint):
+ (WebInspector.BreakpointManager.prototype._setBreakpointOnBackend):
+ (WebInspector.Breakpoint):
+ * inspector/front-end/BreakpointsSidebarPane.js:
+ (WebInspector.BreakpointsSidebarPane):
+ (WebInspector.BreakpointsSidebarPane.prototype.addBreakpoint):
+ (WebInspector.BreakpointsSidebarPane.prototype._breakpointRemoved):
+ (WebInspector.JSBreakpointItem):
+ (WebInspector.JSBreakpointItem.prototype.compareTo):
+ (WebInspector.JSBreakpointItem.prototype.element):
+ (WebInspector.JSBreakpointItem.prototype._breakpointClicked):
+ (WebInspector.JSBreakpointItem.prototype._checkboxClicked):
+ (WebInspector.JSBreakpointItem.prototype._enableChanged):
+ (WebInspector.JSBreakpointItem.prototype._textChanged):
+ (WebInspector.JSBreakpointItem.prototype._removed):
+ * inspector/front-end/ScriptsPanel.js:
+ (WebInspector.ScriptsPanel):
+ (WebInspector.ScriptsPanel.prototype._breakpointAdded):
+ (WebInspector.ScriptsPanel.prototype._breakpointRemoved):
+ * inspector/front-end/SourceFrame.js:
+ (WebInspector.SourceFrame.prototype.addBreakpoint):
+ (WebInspector.SourceFrame.prototype._addBreakpointToSource):
+
+2010-08-23 Ilya Tikhonovsky <loislo@chromium.org>
+
+ Reviewed by Yury Semikhatsky.
+
+ WebInspector: inspector protocol should be switched from array based
+ message format to object based message format.
+ Almost all the protocol related things is generated by CodeGeneratorInspector.pm
+ It was changed a bit. As result InspectorBackendStub.js wraps the
+ calls into Request objects. InspectorBackendDispatcher.cpp unwraps
+ these objects and calls corresponding agents. These two files and
+ RemoteInspectorFrontend are generated by CodeGeneratorInspector.pm
+ Dispatching part of WebInspector also was adjusted for handling Event
+ objects produced by RemoteInspectorFrontend.cpp and Response objects
+ produced by InspectorBackendDispatcher.cpp
+ https://bugs.webkit.org/show_bug.cgi?id=44338
+
+ * inspector/CodeGeneratorInspector.pm:
+ * inspector/Inspector.idl:
+ * inspector/InspectorController.cpp:
+ (WebCore::InspectorController::setAttachedWindow):
+ * inspector/InspectorController.h:
+ * inspector/InspectorFrontendClientLocal.cpp:
+ (WebCore::InspectorFrontendClientLocal::setAttachedWindow):
+ * inspector/InspectorValues.h:
+ (WebCore::InspectorObject::find):
+ * inspector/front-end/Callback.js:
+ (WebInspector.Callback.prototype.processResponse):
+ * inspector/front-end/inspector.js:
+ (WebInspector.dispatch):
+ (WebInspector_syncDispatch):
+ (WebInspector.dispatchMessageFromBackend):
+ (WebInspector.reportProtocolError):
+
+2010-08-19 Jeremy Orlow <jorlow@chromium.org>
+
+ Reviewed by Steve Block.
+
+ Remove IDBDatabase.description per spec changes
+ https://bugs.webkit.org/show_bug.cgi?id=44264
+
+ There's now no longer any way to access the description from JS.
+ The main premise of the manual test is now obsolete. Over time we'll
+ be able to add to it again. While I'm at it, I cleaned up the format
+ of the manual test to be easier to follow (code and usage wise).
+
+ * manual-tests/indexed-database.html:
+ * storage/IDBDatabase.cpp:
+ (WebCore::IDBDatabase::IDBDatabase):
+ * storage/IDBDatabase.h:
+ * storage/IDBDatabase.idl:
+
+2010-08-23 Pavel Feldman <pfeldman@chromium.org>
+
+ Reviewed by Yury Semikhatsky.
+
+ Web Inspector: element's css: pseudo-class locations
+ https://bugs.webkit.org/show_bug.cgi?id=44344
+
+ Also contains a drive-by fix for 44301 (gray out read-only).
+
+ * inspector/front-end/StylesSidebarPane.js:
+ (WebInspector.StylesSidebarPane.prototype.update.computedStyleCallback):
+ (WebInspector.StylesSidebarPane.prototype.update):
+ (WebInspector.StylesSidebarPane.prototype._rebuildUpdate):
+ (WebInspector.StylesSidebarPane.prototype._rebuildSectionsForStyleRules):
+ (WebInspector.StylePropertiesSection):
+
+2010-08-23 Sheriff Bot <webkit.review.bot@gmail.com>
+
+ Unreviewed, rolling out r65803.
+ http://trac.webkit.org/changeset/65803
+ https://bugs.webkit.org/show_bug.cgi?id=44416
+
+ windows build failed (Requested by loislo on #webkit).
+
+ * inspector/CodeGeneratorInspector.pm:
+ * inspector/Inspector.idl:
+ * inspector/InspectorController.cpp:
+ * inspector/InspectorController.h:
+ * inspector/InspectorFrontendClientLocal.cpp:
+ (WebCore::InspectorFrontendClientLocal::setAttachedWindow):
+ * inspector/InspectorValues.h:
+ * inspector/front-end/Callback.js:
+ (WebInspector.Callback.prototype.processResponse):
+ * inspector/front-end/inspector.js:
+ (WebInspector.dispatch.delayDispatch):
+ (WebInspector.dispatch):
+ (WebInspector_syncDispatch):
+ (WebInspector.dispatchMessageFromBackend):
+ (WebInspector.reportProtocolError):
+
+2010-08-23 Ilya Tikhonovsky <loislo@chromium.org>
+
+ Reviewed by Yury Semikhatsky.
+
+ WebInspector: inspector protocol should be switched from array based
+ message format to object based message format.
+ Almost all the protocol related things is generated by CodeGeneratorInspector.pm
+ It was changed a bit. As result InspectorBackendStub.js wraps the
+ calls into Request objects. InspectorBackendDispatcher.cpp unwraps
+ these objects and calls corresponding agents. These two files and
+ RemoteInspectorFrontend are generated by CodeGeneratorInspector.pm
+ Dispatching part of WebInspector also was adjusted for handling Event
+ objects produced by RemoteInspectorFrontend.cpp and Response objects
+ produced by InspectorBackendDispatcher.cpp
+ https://bugs.webkit.org/show_bug.cgi?id=44338
+
+ * inspector/CodeGeneratorInspector.pm:
+ * inspector/Inspector.idl:
+ * inspector/InspectorController.cpp:
+ (WebCore::InspectorController::setAttachedWindow):
+ * inspector/InspectorController.h:
+ * inspector/InspectorFrontendClientLocal.cpp:
+ (WebCore::InspectorFrontendClientLocal::setAttachedWindow):
+ * inspector/InspectorValues.h:
+ (WebCore::InspectorObject::find):
+ * inspector/front-end/Callback.js:
+ (WebInspector.Callback.prototype.processResponse):
+ * inspector/front-end/inspector.js:
+ (WebInspector.dispatch):
+ (WebInspector_syncDispatch):
+ (WebInspector.dispatchMessageFromBackend):
+ (WebInspector.reportProtocolError):
+
+2010-08-23 Alejandro G. Castro <alex@igalia.com>
+
+ Reviewed by Xan Lopez.
+
+ Make the copy of the inspector files silent.
+
+ * GNUmakefile.am:
+
+2010-08-23 Andreas Kling <andreas.kling@nokia.com>
+
+ Reviewed by Kenneth Rohde Christiansen.
+
+ [Qt] -webkit-text-stroke is broken due to Qt::TextBypassShaping
+ https://bugs.webkit.org/show_bug.cgi?id=44403
+
+ Don't bypass the Harfbuzz shaping if we're drawing text with a stroke.
+ For canvas, always use complex text shaping since stroke and fill are decoupled.
+
+ * html/canvas/CanvasRenderingContext2D.cpp:
+ (WebCore::CanvasRenderingContext2D::measureText):
+ (WebCore::CanvasRenderingContext2D::drawTextInternal):
+ * platform/graphics/qt/FontQt.cpp:
+ (WebCore::drawTextCommon):
+
+2010-08-23 Mikhail Naganov <mnaganov@chromium.org>
+
+ Reviewed by Pavel Feldman.
+
+ Extract profiler-related code and data from InspectorController into
+ InspectorProfilerAgent.
+
+ https://bugs.webkit.org/show_bug.cgi?id=44174
+
+ * CMakeLists.txt:
+ * GNUmakefile.am:
+ * WebCore.exp.in:
+ * WebCore.gypi:
+ * WebCore.pro:
+ * WebCore.vcproj/WebCore.vcproj:
+ * WebCore.xcodeproj/project.pbxproj:
+ * bindings/js/ScriptProfiler.cpp:
+ (WebCore::ScriptProfiler::isProfilerAlwaysEnabled):
+ * bindings/js/ScriptProfiler.h:
+ * bindings/v8/ScriptProfiler.cpp:
+ (WebCore::ScriptProfiler::isProfilerAlwaysEnabled):
+ * bindings/v8/ScriptProfiler.h:
+ * inspector/CodeGeneratorInspector.pm:
+ * inspector/Inspector.idl:
+ * inspector/InspectorController.cpp:
+ (WebCore::InspectorController::InspectorController):
+ (WebCore::InspectorController::connectFrontend):
+ (WebCore::InspectorController::disconnectFrontend):
+ (WebCore::InspectorController::populateScriptObjects):
+ (WebCore::InspectorController::didCommitLoad):
+ (WebCore::InspectorController::addProfile):
+ (WebCore::InspectorController::addProfileFinishedMessageToConsole):
+ (WebCore::InspectorController::addStartProfilingMessageToConsole):
+ (WebCore::InspectorController::isRecordingUserInitiatedProfile):
+ (WebCore::InspectorController::getCurrentUserInitiatedProfileName):
+ (WebCore::InspectorController::startUserInitiatedProfiling):
+ (WebCore::InspectorController::stopUserInitiatedProfiling):
+ (WebCore::InspectorController::profilerEnabled):
+ (WebCore::InspectorController::enableProfiler):
+ (WebCore::InspectorController::disableProfiler):
+ * inspector/InspectorController.h:
+ (WebCore::InspectorController::profilerAgent):
+ * inspector/InspectorProfilerAgent.cpp: Added.
+ (WebCore::InspectorProfilerAgent::create):
+ (WebCore::InspectorProfilerAgent::InspectorProfilerAgent):
+ (WebCore::InspectorProfilerAgent::~InspectorProfilerAgent):
+ (WebCore::InspectorProfilerAgent::addProfile):
+ (WebCore::InspectorProfilerAgent::addProfileFinishedMessageToConsole):
+ (WebCore::InspectorProfilerAgent::addStartProfilingMessageToConsole):
+ (WebCore::InspectorProfilerAgent::createProfileHeader):
+ (WebCore::InspectorProfilerAgent::disable):
+ (WebCore::InspectorProfilerAgent::enable):
+ (WebCore::InspectorProfilerAgent::getCurrentUserInitiatedProfileName):
+ (WebCore::InspectorProfilerAgent::getProfileHeaders):
+ (WebCore::InspectorProfilerAgent::getProfile):
+ (WebCore::InspectorProfilerAgent::removeProfile):
+ (WebCore::InspectorProfilerAgent::resetState):
+ (WebCore::InspectorProfilerAgent::startUserInitiatedProfiling):
+ (WebCore::InspectorProfilerAgent::stopUserInitiatedProfiling):
+ (WebCore::InspectorProfilerAgent::toggleRecordButton):
+ * inspector/InspectorProfilerAgent.h: Added.
+ (WebCore::InspectorProfilerAgent::clearProfiles):
+ (WebCore::InspectorProfilerAgent::enabled):
+ (WebCore::InspectorProfilerAgent::isRecordingUserInitiatedProfile):
+ (WebCore::InspectorProfilerAgent::setRemoteFrontend):
+ (WebCore::InspectorProfilerAgent::startProfiling):
+ (WebCore::InspectorProfilerAgent::stopProfiling):
+
+2010-08-23 Ariya Hidayat <ariya@sencha.com>
+
+ Reviewed by Kenneth Rohde Christiansen.
+
+ [Qt] Crash when purging the scratch buffer for the shadow
+ https://bugs.webkit.org/show_bug.cgi?id=44384
+
+ WebCore::Timer can't be used in a static object bcause it relies on
+ thread global data, which is invalid once the application instance is
+ destroyed. To overcome the problem, use QObject's timer support for
+ the ShadowBuffer class.
+
+ * platform/graphics/qt/ContextShadow.cpp:
+ (WebCore::):
+ (WebCore::ShadowBuffer::ShadowBuffer):
+ (WebCore::ShadowBuffer::schedulePurge):
+ (WebCore::ShadowBuffer::timerEvent):
+
+2010-08-23 Philippe Normand <pnormand@igalia.com>
+
+ Reviewed by Xan Lopez.
+
+ [GStreamer] don't expose the private player in GStreamerGWorld
+ https://bugs.webkit.org/show_bug.cgi?id=44332
+
+ Only a pointer to our playbin2 element instance is required
+ instead of the whole MediaPlayerPrivateGStreamer instance.
+
+ * platform/graphics/gstreamer/GStreamerGWorld.cpp:
+ (WebCore::GStreamerGWorld::createGWorld):
+ (WebCore::GStreamerGWorld::GStreamerGWorld):
+ (WebCore::GStreamerGWorld::~GStreamerGWorld):
+ (WebCore::GStreamerGWorld::enterFullscreen):
+ (WebCore::GStreamerGWorld::exitFullscreen):
+ * platform/graphics/gstreamer/GStreamerGWorld.h:
+ (WebCore::GStreamerGWorld::pipeline):
+ * platform/graphics/gstreamer/MediaPlayerPrivateGStreamer.cpp:
+ (WebCore::MediaPlayerPrivateGStreamer::createGSTPlayBin):
+
+2010-08-22 Andreas Kling <andreas.kling@nokia.com>
+
+ Reviewed by Kenneth Rohde Christiansen.
+
+ [Qt] GraphicsContext: Simplify getting the clip bounding rect
+ https://bugs.webkit.org/show_bug.cgi?id=44396
+
+ Move the Qt 4.8 version check for QPainter::clipBoundingRect()
+ into a GraphicsContextPlatformPrivate method.
+
+ * platform/graphics/qt/GraphicsContextQt.cpp:
+ (WebCore::GraphicsContextPlatformPrivate::clipBoundingRect):
+ (WebCore::GraphicsContext::beginTransparencyLayer):
+ (WebCore::GraphicsContext::clipOut):
+ (WebCore::GraphicsContext::clipOutEllipseInRect):
+
+2010-08-22 Juha Savolainen <juha.savolainen@weego.fi>
+
+ Reviewed by Kenneth Rohde Christiansen.
+
+ [Qt] Add QTouchEvents support for WebKit2
+ https://bugs.webkit.org/show_bug.cgi?id=44330
+
+ This patch adds support for QTouchEvents in WebKit2. A new WebEvent-class
+ is created for touchevents, WebTouchEvent. Also touchpoints needed a new
+ class, WebPlatformTouchPoint. This is similar solution like in other
+ events(like MouseEvent) on WebKit2. These classes are introduced in WebEvent.h
+ Also there was a need to create an empty constructor to PlatformTouchPoint-class.
+
+ * platform/PlatformTouchPoint.h:
+ (WebCore::PlatformTouchPoint::PlatformTouchPoint):
+
+2010-08-22 Daniel Bates <dbates@rim.com>
+
+ Reviewed by Eric Seidel.
+
+ Encapsulate document marker management into DocumentMarkerController
+ https://bugs.webkit.org/show_bug.cgi?id=44383
+
+ Moves the document marker management code in Document.cpp into its own
+ class called DocumentMarkerController.
+
+ No functionality was changed, so no new tests.
+
+ * Android.mk: Added DocumentMarkerController.cpp
+ * CMakeLists.txt: Ditto.
+ * GNUmakefile.am: Added DocumentMarkerController.cpp and DocumentMarkerController.h.
+ * WebCore.exp.in: Substituted symbols __ZN7WebCore24DocumentMarkerController13removeMarkersENS_14DocumentMarker10MarkerTypeE
+ and __ZN7WebCore24DocumentMarkerController23renderedRectsForMarkersENS_14DocumentMarker10MarkerTypeE for
+ __ZN7WebCore8Document13removeMarkersENS_14DocumentMarker10MarkerTypeE and
+ __ZN7WebCore8Document23renderedRectsForMarkersENS_14DocumentMarker10MarkerTypeE, respectively.
+ * WebCore.gypi: Added DocumentMarkerController.cpp and DocumentMarkerController.h.
+ * WebCore.pro: Ditto.
+ * WebCore.vcproj/WebCore.vcproj: Ditto.
+ * WebCore.xcodeproj/project.pbxproj: Ditto.
+ * dom/Document.cpp:
+ (WebCore::Document::removedLastRef): Modified to call DocumentMarkerController::detach().
+ (WebCore::Document::~Document): Removed "deleteAllValues(m_markers)" as DocumentMarkerController
+ is stored in OwnPtr; so it will be destroyed automatically on Document destruction.
+ (WebCore::Document::textInserted): Modified to use marker controller.
+ (WebCore::Document::textRemoved): Ditto.
+ * dom/Document.h:
+ (WebCore::Document::markers): Added.
+ * dom/DocumentMarkerController.cpp: Added.
+ (WebCore::placeholderRectForMarker):
+ (WebCore::DocumentMarkerController::detach):
+ (WebCore::DocumentMarkerController::addMarker):
+ (WebCore::DocumentMarkerController::removeMarkers):
+ (WebCore::DocumentMarkerController::copyMarkers):
+ (WebCore::DocumentMarkerController::markerContainingPoint):
+ (WebCore::DocumentMarkerController::markersForNode):
+ (WebCore::DocumentMarkerController::renderedRectsForMarkers):
+ (WebCore::DocumentMarkerController::repaintMarkers):
+ (WebCore::DocumentMarkerController::setRenderedRectForMarker):
+ (WebCore::DocumentMarkerController::invalidateRenderedRectsForMarkersInRect):
+ (WebCore::DocumentMarkerController::shiftMarkers):
+ (WebCore::DocumentMarkerController::setMarkersActive):
+ * dom/DocumentMarkerController.h: Added.
+ (WebCore::DocumentMarkerController::~DocumentMarkerController):
+ * editing/Editor.cpp:
+ (WebCore::Editor::ignoreSpelling): Modified to use marker controller.
+ (WebCore::findFirstMisspellingInRange): Ditto.
+ (WebCore::findFirstGrammarDetailInRange): Ditto.
+ (WebCore::Editor::advanceToNextMisspelling): Ditto.
+ (WebCore::Editor::markAllMisspellingsAndBadGrammarInRanges): Ditto.
+ (WebCore::Editor::changeBackToReplacedString): Ditto.
+ * editing/SplitTextNodeCommand.cpp:
+ (WebCore::SplitTextNodeCommand::doApply): Ditto.
+ (WebCore::SplitTextNodeCommand::doUnapply): Ditto.
+ * page/Frame.cpp:
+ (WebCore::Frame::markAllMatchesForText): Ditto.
+ (WebCore::Frame::setMarkedTextMatchesAreHighlighted): Ditto.
+ (WebCore::Frame::respondToChangedSelection): Ditto.
+ * page/FrameView.cpp:
+ (WebCore::FrameView::getTickmarks): Ditto.
+ (WebCore::FrameView::paintContents): Ditto.
+ * page/Page.cpp:
+ (WebCore::Page::unmarkAllTextMatches): Ditto.
+ * rendering/HitTestResult.cpp:
+ (WebCore::HitTestResult::spellingToolTip): Ditto.
+ (WebCore::HitTestResult::replacedString): Ditto.
+ * rendering/InlineTextBox.cpp:
+ (WebCore::InlineTextBox::paintSpellingOrGrammarMarker): Ditto.
+ (WebCore::InlineTextBox::paintTextMatchMarker): Ditto.
+ (WebCore::InlineTextBox::computeRectForReplacementMarker): Ditto.
+ (WebCore::InlineTextBox::paintDocumentMarkers): Ditto.
+ * rendering/SVGInlineTextBox.cpp:
+ (WebCore::SVGInlineTextBox::computeTextMatchMarkerRect): Ditto.
+
+2010-08-22 Jian Li <jianli@chromium.org>
+
+ Reviewed by Darin Fisher.
+
+ Add the blob URL member to FormData.
+ https://bugs.webkit.org/show_bug.cgi?id=44387
+
+ This is in preparation to switch blob implementation to using BlobData
+ model. When a blob is added to a FormData, it is represented as a blob
+ URL in the list.
+
+ * platform/network/FormData.cpp:
+ (WebCore::FormData::appendBlob):
+ * platform/network/FormData.h:
+ (WebCore::FormDataElement::FormDataElement):
+ (WebCore::FormDataElement::):
+ (WebCore::operator==):
+
+2010-08-22 Eric Seidel <eric@webkit.org>
+
+ Reviewed by Adam Barth.
+
+ HTML5 TreeBuilder builds wrong DOM for <a><svg><tr><input></a>
+ https://bugs.webkit.org/show_bug.cgi?id=44390
+
+ The HTML5 spec has changed since Adam and I original wrote
+ the HTMLTreeBuilder. Most important for this change was resolution of:
+ http://www.w3.org/Bugs/Public/show_bug.cgi?id=9580
+
+ I also removed our "phrasing" tag support since that was also removed
+ from the spec as part of other bug fixes.
+
+ This is tested by tonyg's <a><svg><tr><input></a> test in adoption01.dat.
+
+ * html/HTMLTreeBuilder.cpp:
+ (WebCore::HTMLTreeBuilder::processCloseWhenNestedTag):
+ (WebCore::HTMLTreeBuilder::processAnyOtherEndTagForInBody):
+ (WebCore::HTMLTreeBuilder::furthestBlockForFormattingElement):
+ (WebCore::HTMLTreeBuilder::processEndTag):
+
+2010-08-22 Andreas Kling <andreas.kling@nokia.com>
+
+ Reviewed by Ariya Hidayat.
+
+ [Qt] TransparencyLayer: Always use anti-aliasing and smooth pixmap transform
+ https://bugs.webkit.org/show_bug.cgi?id=44394
+
+ * platform/graphics/qt/TransparencyLayer.h:
+ (WebCore::TransparencyLayer::TransparencyLayer): Set the Antialiasing
+ and SmoothPixmapTransforms render hints for all TransparencyLayers.
+
+2010-08-22 Andreas Kling <andreas.kling@nokia.com>
+
+ Reviewed by Ariya Hidayat.
+
+ [Qt] Gradient: Support inner radius larger than outer radius
+ https://bugs.webkit.org/show_bug.cgi?id=44392
+
+ * platform/graphics/qt/GradientQt.cpp:
+ (WebCore::Gradient::platformGradient): Reverse the (radial) gradient if r0 > r1.
+
+2010-08-22 Ariya Hidayat <ariya@sencha.com>
+
+ Reviewed by Dirk Schulze.
+
+ [Qt] Layer approach to support generic shadow handling
+ https://bugs.webkit.org/show_bug.cgi?id=44380
+
+ The pair beginShadowLayer and endShadowLayer creates a temporary image
+ where the caller can draw onto, using the returned QPainter. When
+ endShadowLayer is called, the temporary image will be filtered, using
+ the specified shadow color and blur radius, and drawn to the graphics
+ context.
+
+ * platform/graphics/GraphicsContext.h:
+ * platform/graphics/qt/ContextShadow.cpp:
+ (WebCore::ContextShadow::beginShadowLayer):
+ (WebCore::ContextShadow::endShadowLayer):
+ * platform/graphics/qt/ContextShadow.h:
+ * platform/graphics/qt/GraphicsContextQt.cpp:
+ (WebCore::GraphicsContext::fillRect):
+ (WebCore::GraphicsContext::contextShadow):
+
+2010-08-21 Eric Carlson <eric.carlson@apple.com>
+
+ Reviewed by Dan Bernstein.
+
+ Media engine should not be asked to open all urls
+ https://bugs.webkit.org/show_bug.cgi?id=44370
+
+ * platform/graphics/MediaPlayer.cpp:
+ (WebCore::MediaPlayer::load): Do nothing with urls with a type attribute that would be
+ rejected by canPlayType().
+
+2010-08-21 Ariya Hidayat <ariya@sencha.com>
+
+ Reviewed by Kenneth Rohde Christiansen.
+
+ [Qt] Faster bounding rect for the shadow clip region
+ https://bugs.webkit.org/show_bug.cgi?id=44369
+
+ Like in r65650, we should use the faster QPainter::clipBoundingRect
+ when it is available.
+
+ * platform/graphics/qt/ContextShadow.cpp:
+ (WebCore::ContextShadow::drawShadowRect):
+
+2010-08-20 Girish Ramakrishnan <girish@forwardbias.in>
+
+ Reviewed by Ariya Hidayat.
+
+ [Qt] When using the raster graphics system on Maemo5, allow
+ Flash to render directly into the raster window surface.
+ wmode=transparent is now supported as a result of this change.
+
+ https://bugs.webkit.org/show_bug.cgi?id=44043
+
+ * plugins/qt/PluginViewQt.cpp:
+ (WebCore::PluginView::paintUsingImageSurfaceExtension):
+
+2010-08-20 Alexey Proskuryakov <ap@apple.com>
+
+ Reviewed by Brady Eidson.
+
+ https://bugs.webkit.org/show_bug.cgi?id=38428
+ HTTP code 500 (and other non-4xx codes) wrongfully treated as success for subresources
+
+ Test: http/tests/misc/script-500.html
+
+ * loader/loader.cpp: (WebCore::Loader::Host::didReceiveData): Treat all HTTP codes >= 400 as
+ error ones, since they are.
+
+2010-08-20 Tony Gentilcore <tonyg@chromium.org>
+
+ Reviewed by Adam Barth.
+
+ Crash in WebCore::Node::createRendererIfNeeded()
+ https://bugs.webkit.org/show_bug.cgi?id=44129
+
+ * dom/ContainerNode.cpp:
+ (WebCore::ContainerNode::insertBefore): Factor out core bit to insertBetween.
+ (WebCore::ContainerNode::insertBetween): Factored out of insertBefore.
+ (WebCore::ContainerNode::parserInsertBefore): Similar to insertBefore, but doesn't handle reparenting or dispatch DOM mutation events.
+ (WebCore::ContainerNode::removeChild): Factor out core bit to removeBetween.
+ (WebCore::ContainerNode::removeBetween): Facotred out of removeChild.
+ (WebCore::ContainerNode::parserRemoveChild): Similar to removeChild, but doesn't handle reparenting or dispatch DOM mutation events.
+ (WebCore::ContainerNode::addChildCommon):
+ (WebCore::ContainerNode::parserAddChild):
+ (WebCore::ContainerNode::legacyParserAddChild):
+ * dom/ContainerNode.h:
+ * dom/Node.cpp:
+ (WebCore::Node::parserRemoveChild):
+ (WebCore::Node::parserInsertBefore):
+ * dom/Node.h:
+ * html/HTMLConstructionSite.cpp:
+ (WebCore::HTMLConstructionSite::attach):
+ (WebCore::HTMLConstructionSite::attachAtSite): Use new parserInsertBefore.
+ * html/HTMLTreeBuilder.cpp:
+ (WebCore::HTMLTreeBuilder::passTokenToLegacyParser):
+ (WebCore::HTMLTreeBuilder::reparentChildren):
+ (WebCore::HTMLTreeBuilder::callTheAdoptionAgency): Was missing a key bit from the spec about removing the old parent if it exists.
+
+2010-08-20 Kinuko Yasuda <kinuko@chromium.org>
+
+ Unreviewed; build fix. Had included wrong version of build file.
+
+2010-08-20 Martin Robinson <mrobinson@igalia.com>
+
+ Reviewed by Joseph Pecoraro.
+
+ [GTK] Inspector extensions tests fail on GTK+ bots because onSelectionChanged is missing
+ https://bugs.webkit.org/show_bug.cgi?id=44342
+
+ * GNUmakefile.am: Fix dependency tracking for copied web inspector files.
+
+2010-08-20 Kinuko Yasuda <kinuko@chromium.org>
+
+ Reviewed by Darin Fisher.
+
+ Add Callback implementation for FileSystem API
+ https://bugs.webkit.org/show_bug.cgi?id=44349
+
+ No new tests; tests will be added later.
+
+ * CMakeLists.txt:
+ * GNUmakefile.am:
+ * WebCore.gypi:
+ * WebCore.pro:
+ * WebCore.vcproj/WebCore.vcproj:
+ * WebCore.xcodeproj/project.pbxproj:
+ * storage/FileSystemCallbacks.cpp: Added.
+ * storage/FileSystemCallbacks.h: Added.
+
+ * storage/EntryCallback.h: Nits fix
+ * storage/FileSystemCallback.h: Nits fix
+
+2010-08-20 Andreas Kling <andreas.kling@nokia.com>
+
+ Reviewed by Ariya Hidayat.
+
+ [Qt] WebKit does not compile with --3d-canvas
+ https://bugs.webkit.org/show_bug.cgi?id=44335
+
+ - PlatformGLObject => Platform3DObject
+ - Implemented getAttachedShaders()
+ - Implemented bufferData() and bufferSubData() for ArrayBuffer*
+ - Removed reference to nonexistent variable in getImageData()
+
+ * platform/graphics/qt/GraphicsContext3DQt.cpp:
+ (WebCore::GraphicsContext3DInternal::GraphicsContext3DInternal):
+ (WebCore::GraphicsContext3D::attachShader):
+ (WebCore::GraphicsContext3D::getAttachedShaders):
+ (WebCore::GraphicsContext3D::bindAttribLocation):
+ (WebCore::GraphicsContext3D::bindBuffer):
+ (WebCore::GraphicsContext3D::bindFramebuffer):
+ (WebCore::GraphicsContext3D::bindRenderbuffer):
+ (WebCore::GraphicsContext3D::bindTexture):
+ (WebCore::GraphicsContext3D::bufferData):
+ (WebCore::GraphicsContext3D::bufferSubData):
+ (WebCore::GraphicsContext3D::compileShader):
+ (WebCore::GraphicsContext3D::detachShader):
+ (WebCore::GraphicsContext3D::framebufferRenderbuffer):
+ (WebCore::GraphicsContext3D::framebufferTexture2D):
+ (WebCore::GraphicsContext3D::getActiveAttrib):
+ (WebCore::GraphicsContext3D::getActiveUniform):
+ (WebCore::GraphicsContext3D::getAttribLocation):
+ (WebCore::GraphicsContext3D::isBuffer):
+ (WebCore::GraphicsContext3D::isFramebuffer):
+ (WebCore::GraphicsContext3D::isProgram):
+ (WebCore::GraphicsContext3D::isRenderbuffer):
+ (WebCore::GraphicsContext3D::isShader):
+ (WebCore::GraphicsContext3D::isTexture):
+ (WebCore::GraphicsContext3D::linkProgram):
+ (WebCore::GraphicsContext3D::shaderSource):
+ (WebCore::GraphicsContext3D::useProgram):
+ (WebCore::GraphicsContext3D::validateProgram):
+ (WebCore::GraphicsContext3D::getProgramiv):
+ (WebCore::GraphicsContext3D::getProgramInfoLog):
+ (WebCore::GraphicsContext3D::getShaderiv):
+ (WebCore::GraphicsContext3D::getShaderInfoLog):
+ (WebCore::GraphicsContext3D::getShaderSource):
+ (WebCore::GraphicsContext3D::getUniformfv):
+ (WebCore::GraphicsContext3D::getUniformiv):
+ (WebCore::GraphicsContext3D::getUniformLocation):
+ (WebCore::GraphicsContext3D::getImageData):
+ * platform/graphics/qt/GraphicsLayerQt.h:
+
+2010-08-20 Dan Bernstein <mitz@apple.com>
+
+ Reviewed by Dave Kilzer.
+
+ #ifdef-out some Leopard-and-earlier code.
+
+ * platform/graphics/mac/FontCustomPlatformData.cpp:
+ (WebCore::FontCustomPlatformData::~FontCustomPlatformData):
+
+2010-08-20 Kenneth Russell <kbr@google.com>
+
+ Unreviewed, speculative Chromium build fix. Forward declare
+ IntSize in WebGLRenderingContext.h and include IntSize.h in .cpp.
+
+ * html/canvas/WebGLRenderingContext.cpp:
+ * html/canvas/WebGLRenderingContext.h:
+
+2010-08-20 Eric Carlson <eric.carlson@apple.com>
+
+ Reviewed by Dan Bernstein.
+
+ Media element canPlayType("application/octet-stream") not handled correctly
+ https://bugs.webkit.org/show_bug.cgi?id=44343
+
+ Test: media/media-can-play-octet-stream.html
+
+ * platform/graphics/MediaPlayer.cpp:
+ (WebCore::applicationOctetStream): New, accessor for static string used more than once.
+ (WebCore::textPlain): Ditto.
+ (WebCore::codecs): Ditto.
+ (WebCore::chooseBestEngineForTypeAndCodecs): Special case "application/octet-stream".
+ (WebCore::MediaPlayer::load): Use static static string methods.
+ (WebCore::MediaPlayer::supportsType): Special case "application/octet-stream".
+
+2010-08-20 Adrienne Walker <enne@google.com>
+
+ Reviewed by Kenneth Russell.
+
+ Implement HTMLVideoElement support for texImage2D and texSubImage2D
+ https://bugs.webkit.org/show_bug.cgi?id=33852
+
+ Test: fast/canvas/webgl/tex-image-and-sub-image-2d-with-video.html
+
+ * html/canvas/WebGLRenderingContext.cpp:
+ (WebCore::WebGLRenderingContext::WebGLRenderingContext):
+ (WebCore::WebGLRenderingContext::videoFrameToImage):
+ (WebCore::WebGLRenderingContext::texImage2D):
+ (WebCore::WebGLRenderingContext::texSubImage2D):
+ (WebCore::WebGLRenderingContext::LRUImageBufferCache::LRUImageBufferCache):
+ (WebCore::WebGLRenderingContext::LRUImageBufferCache::imageBuffer):
+ (WebCore::WebGLRenderingContext::LRUImageBufferCache::bubbleToFront):
+ * html/canvas/WebGLRenderingContext.h:
+
+2010-08-20 Dumitru Daniliuc <dumi@chromium.org>
+
+ Reviewed by Adam Barth.
+
+ Removing an incorrect ASSERT.
+ https://bugs.webkit.org/show_bug.cgi?id=44151
+
+ A failure in the preflight step of a transaction wrapper does not
+ guarantee that the transaction is rolled back (and it shouldn't).
+
+ Test: storage/change-version-no-crash-on-preflight-failure.html
+
+ * storage/SQLTransaction.cpp:
+ (WebCore::SQLTransaction::openTransactionAndPreflight):
+
+2010-08-20 David Leong <david.leong@nokia.com>
+
+ Reviewed by Laszlo Gombos.
+
+ [Qt] Update Symbian capabilities to remove AllFiles and DRM
+
+ Add CONFIG(production) variation for set of DLL capabilities.
+ DRM and AllFiles capabilities need to be audited for the sis
+ package to be signed.
+
+ No new tests.
+
+ * WebCore.pro: Updated Symbian Capabilities.
+
+2010-08-20 Joseph Pecoraro <joepeck@webkit.org>
+
+ Reviewed by David Kilzer.
+
+ Do Not Copy Subversion Related Files in Inspector Build Phase
+ https://bugs.webkit.org/show_bug.cgi?id=44353
+
+ * WebCore.xcodeproj/project.pbxproj: remove .svn directories in the "Copy Inspector Resources" build phase.
+
+2010-08-19 Ryosuke Niwa <rniwa@webkit.org>
+
+ Reviewed by Adam Barth.
+
+ style correction in markup.cpp
+ https://bugs.webkit.org/show_bug.cgi?id=44318
+
+ Make markup.cpp pass check-webkit-style.
+
+ No new tests are added since this is a cleanup.
+
+ * editing/markup.cpp:
+ (WebCore::MarkupAccumulator::appendAttributeValue):
+ (WebCore::appendEscapedContent):
+ (WebCore::MarkupAccumulator::appendStartMarkup):
+ (WebCore::completeURLs):
+ (WebCore::isElementPresentational):
+ (WebCore::isSpecialAncestorBlock):
+ (WebCore::shouldIncludeWrapperForFullySelectedRoot):
+ (WebCore::createMarkup):
+ (WebCore::fillContainerFromString):
+ (WebCore::createFragmentFromText):
+ (WebCore::createFragmentFromNodes):
+
+2010-08-20 Tony Chang <tony@chromium.org>
+
+ Reviewed by Adam Barth.
+
+ crash when trying to access a stale Node pointer in FocusController::setFocusedNode
+ https://bugs.webkit.org/show_bug.cgi?id=44226
+
+ Test: fast/events/focus-change-crash2.html
+
+ * page/FocusController.cpp:
+ (WebCore::FocusController::setFocusedNode): add a ref to prevent the focused node from being deleted
+
+2010-08-20 Simon Fraser <simon.fraser@apple.com>
+
+ Reviewed by Dan Bernstein.
+
+ <rdar://problem/8245719> backface-visibility and reflections don't play nicely together.
+
+ On elements with a reflection and backface-visibility: hidden, set the doubleSided property on the
+ reflection flattening layer so that backface-visibility works in all configurations.
+
+ Test: compositing/reflections/backface-hidden-reflection.html
+
+ * platform/graphics/mac/GraphicsLayerCA.mm:
+ (WebCore::GraphicsLayerCA::updateBackfaceVisibility): Call setDoubleSided: on the structural
+ layer for reflections.
+ (WebCore::GraphicsLayerCA::ensureStructuralLayer): Fix a comment typo, and call updateBackfaceVisibility()
+ when we gain a structural layer.
+
+2010-08-20 Simon Fraser <simon.fraser@apple.com>
+
+ Reviewed by Dan Bernstein.
+
+ Slider labels do not update as you move the sliders on this page
+ https://bugs.webkit.org/show_bug.cgi?id=41020
+
+ When repainting after layout in a multicol element, we need to adjust the
+ repaint rect for the columns.
+
+ Test: fast/repaint/multicol-repaint.html
+
+ * rendering/RenderBlock.cpp:
+ (WebCore::RenderBlock::layoutBlock):
+
+2010-08-20 Jian Li <jianli@chromium.org>
+
+ Reviewed by David Levin.
+
+ Move FileStreamClient to platform and add AsyncFileStream interface.
+ https://bugs.webkit.org/show_bug.cgi?id=44224
+
+ * GNUmakefile.am:
+ * WebCore.gypi:
+ * WebCore.pro:
+ * WebCore.vcproj/WebCore.vcproj:
+ * WebCore.xcodeproj/project.pbxproj:
+ * html/FileStreamProxy.cpp: Account for the change.
+ (WebCore::FileStreamProxy::FileStreamProxy):
+ (WebCore::FileStreamProxy::stop):
+ * html/FileStreamProxy.h: Make it derive from AsyncFileStream.h.
+ * platform/AsyncFileStream.h: Added.
+ * platform/FileStreamClient.h: Renamed from WebCore/html/FileStreamClient.h.
+
+2010-08-20 Abhishek Arya <inferno@chromium.org>
+
+ Reviewed by Darin Fisher.
+
+ Prevent use of stale notification presenter pointer in notifications by instead using
+ a notification center pointer and deriving the presenter from it. Notification presenter
+ gets properly destroyed using disconnectFrame function inside notification center. Add
+ null checks for notification presenter.
+ https://bugs.webkit.org/show_bug.cgi?id=43645
+
+ Test: fast/notifications/notifications-window-close-crash.html
+
+ * notifications/Notification.cpp:
+ (WebCore::Notification::Notification):
+ (WebCore::Notification::create):
+ (WebCore::Notification::show):
+ (WebCore::Notification::cancel):
+ (WebCore::Notification::contextDestroyed):
+ (WebCore::Notification::finishLoading):
+ * notifications/Notification.h:
+ (WebCore::Notification::detachPresenter):
+ * notifications/NotificationCenter.h:
+ (WebCore::NotificationCenter::createHTMLNotification):
+ (WebCore::NotificationCenter::createNotification):
+
+2010-08-20 Martin Robinson <mrobinson@igalia.com>
+
+ Reviewed by Xan Lopez.
+
+ r64526 broke the GTK+-3 build
+ https://bugs.webkit.org/show_bug.cgi?id=44254
+
+ No new tests, as this is covered by manual-tests/cursor.html.
+
+ * platform/gtk/CursorGtk.cpp:
+ (WebCore::createPixmapFromBits): Added this method which turns the inline data
+ structures into GdkPixmaps using Cairo and GDK-Cairo.
+ (WebCore::createNamedCursor): Modified this method to use the new helper.
+ * platform/gtk/CursorGtk.h: Changed all inline data structures to be unsigned
+ char arrays (which Cairo requires). The progress cursor is known in X11 icon themes
+ as "left_ptr_watch." This change to the name preserves the old behavior of taking this
+ icon from the theme when available. It seems that this worked in the past due to a fluke
+ or failure of the previous code.
+
+2010-08-20 Martin Robinson <mrobinson@igalia.com>
+
+ Reviewed by Dirk Schulze.
+
+ [Cairo] Eliminate full-surface copy from canvas.drawImage(...)
+ https://bugs.webkit.org/show_bug.cgi?id=44190
+
+ Covered by canvas layout tests.
+
+ * platform/graphics/cairo/ImageBufferCairo.cpp:
+ (WebCore::ImageBuffer::drawsUsingCopy): Return false now.
+ (WebCore::ImageBuffer::clip): Add a link to the bug which tracks this feature.
+ (WebCore::ImageBuffer::draw): Construct the bitmap image without the full-surface copy.
+ (WebCore::ImageBuffer::drawPattern): Ditto.
+
+2010-08-20 Alejandro G. Castro <alex@igalia.com>
+
+ Reviewed by Xan Lopez.
+
+ [REGRESSION] r65608 broke gtk distcheck
+ https://bugs.webkit.org/show_bug.cgi?id=44333
+
+ Define the inspector.html as a noinst_DATA intead of using the dir
+ suffix, which is used for installation.
+
+ * GNUmakefile.am:
+
+2010-08-19 Pavel Podivilov <podivilov@chromium.org>
+
+ Reviewed by Yury Semikhatsky.
+
+ Web Inspector: implement breaking on DOM node subtree mutations.
+ https://bugs.webkit.org/show_bug.cgi?id=42886
+
+ Add two entries to Web Inspector DOM element context menu:
+ 1. "Stop on subtree modifications": will break on adding/removing of any element which is a child of the DOM element
+ 2. "Remove breakpoints": will remove all breakpoints associated with the DOM element
+
+ * English.lproj/localizedStrings.js:
+ * bindings/js/ScriptDebugServer.cpp:
+ (WebCore::ScriptDebugServer::breakProgram):
+ * bindings/js/ScriptDebugServer.h:
+ * bindings/v8/ScriptDebugServer.cpp:
+ (WebCore::ScriptDebugServer::breakProgram):
+ (WebCore::ScriptDebugServer::breakProgramCallback):
+ (WebCore::ScriptDebugServer::handleV8DebugEvent):
+ * bindings/v8/ScriptDebugServer.h:
+ * inspector/Inspector.idl:
+ * inspector/InspectorDOMAgent.cpp:
+ (WebCore::InspectorDOMAgent::~InspectorDOMAgent):
+ (WebCore::InspectorDOMAgent::discardBindings):
+ (WebCore::InspectorDOMAgent::setDOMBreakpoint):
+ (WebCore::InspectorDOMAgent::removeDOMBreakpoint):
+ (WebCore::InspectorDOMAgent::didInsertDOMNode):
+ (WebCore::InspectorDOMAgent::didRemoveDOMNode):
+ (WebCore::InspectorDOMAgent::hasBreakpoint):
+ (WebCore::InspectorDOMAgent::pauseOnBreakpoint):
+ (WebCore::InspectorDOMAgent::updateSubtreeBreakpoints):
+ * inspector/InspectorDOMAgent.h:
+ * inspector/front-end/ElementsTreeOutline.js:
+ (WebInspector.ElementsTreeElement.prototype._populateTagContextMenu):
+ * inspector/front-end/Settings.js:
+
+2010-08-20 Yury Semikhatsky <yurys@chromium.org>
+
+ Reviewed by Pavel Feldman.
+
+ Web Inspector: discard InjectedScript reference on ScriptState when clearing injected scripts
+ https://bugs.webkit.org/show_bug.cgi?id=44328
+
+ Otherwise if the reference is not cleared we may remove InjectedScript from the
+ map on InjectedScriptHost but keep it on ScriptState and try to reuse it later.
+
+ * bindings/js/JSInjectedScriptHostCustom.cpp:
+ (WebCore::InjectedScriptHost::discardInjectedScript):
+ * bindings/v8/V8HiddenPropertyName.h:
+ * bindings/v8/custom/V8InjectedScriptHostCustom.cpp:
+ (WebCore::InjectedScriptHost::discardInjectedScript):
+ (WebCore::InjectedScriptHost::injectedScriptFor):
+ * inspector/InjectedScript.h:
+ (WebCore::InjectedScript::scriptState):
+ * inspector/InjectedScriptHost.cpp:
+ (WebCore::InjectedScriptHost::discardInjectedScripts):
+ * inspector/InjectedScriptHost.h:
+
+2010-08-20 Nikolas Zimmermann <nzimmermann@rim.com>
+
+ Reviewed by Dirk Schulze.
+
+ Clippers are rasterized, when applied to scaled target object
+ https://bugs.webkit.org/show_bug.cgi?id=44325
+
+ Use SVGImageBufferTools logic for RenderSVGResourceClipper, just like RenderSVGResourceMasker/Gradient,
+ to avoid pixelation, when the clipper is applied to a scaled target object, or when the document is scaled.
+
+ Test: svg/clip-path/clip-path-pixelation.svg
+
+ * rendering/RenderSVGResourceClipper.cpp:
+ (WebCore::RenderSVGResourceClipper::applyClippingToContext):
+ (WebCore::RenderSVGResourceClipper::createClipData):
+ * rendering/RenderSVGResourceClipper.h:
+
+2010-08-20 Andreas Kling <andreas.kling@nokia.com>
+
+ Reviewed by Kenneth Rohde Christiansen.
+
+ [Qt] Initialize GDK before loading plugins
+ https://bugs.webkit.org/show_bug.cgi?id=44324
+
+ Attempt to call gdk_init_check() before loading any plugins.
+ This prevents various crashes and freezes in Adobe's Flash plugin.
+
+ * plugins/qt/PluginPackageQt.cpp:
+ (WebCore::initializeGdkIfPossible):
+ (WebCore::PluginPackage::load):
+
+2010-08-20 Dan Bernstein <mitz@apple.com>
+
+ Reviewed by Mark Rowe.
+
+ Follow-up to r41020.
+
+ No change in behavior, thus no new tests.
+
+ * platform/graphics/mac/FontPlatformDataMac.mm:
+ (WebCore::FontPlatformData::FontPlatformData): Asserted that the NSFont parameter is not nil,
+ and removed nil check.
+ (WebCore::FontPlatformData::setFont): Asserted that the NSFont parameter is not nil and that
+ this is not the deleted value, and removed code to handle those cases.
+
+2010-08-19 Vincent Scheib <scheib@chromium.org>
+
+ Reviewed by David Levin.
+
+ [chromium] TilingData::tilePositionY has typo of X where Y should be used
+ https://bugs.webkit.org/show_bug.cgi?id=44195
+
+ Corrected error, and rewrote functions to use for loop instead of recursion.
+
+ Unit Tests added to WebKit/chromium/tests/TilingDataTest.cpp
+
+ * platform/graphics/chromium/TilingData.cpp:
+ (WebCore::TilingData::tilePositionX):
+ (WebCore::TilingData::tilePositionY):
+
+2010-08-19 Mihai Parparita <mihaip@chromium.org>
+
+ Reviewed by Brady Eidson.
+
+ Assertion failure when going back inside frame during onload
+ https://bugs.webkit.org/show_bug.cgi?id=44217
+
+ Fix assertion failure when doing a history.back() within the main frame
+ during onload of a child frame. This would happen when
+ HISTORY_ALWAYS_ASYNC was set to 0, because we would only compare the
+ current frame document sequence numbers when determining if we're in the
+ same document, instead of also recursing over child frames.
+
+ Test: fast/history/history-back-within-subframe-hash.html
+
+ * history/HistoryItem.cpp:
+ (WebCore::HistoryItem::hasSameDocuments):
+ * history/HistoryItem.h:
+ * loader/RedirectScheduler.cpp:
+ (WebCore::RedirectScheduler::scheduleHistoryNavigation):
+
+2010-08-19 Balazs Kelemen <kb@inf.u-szeged.hu>
+
+ Reviewed by Antonio Gomes.
+
+ [Qt] Fix cursor change propagation
+ https://bugs.webkit.org/show_bug.cgi?id=44250
+
+ No functional change so new tests.
+
+ Propagate the setCursor callback to the PageClient via the HostWindow instead of preassuming
+ the concrete type of the ChromeClient (what was generally wrong and actually incompatible with WebKit2).
+ * platform/qt/WidgetQt.cpp:
+ (WebCore::Widget::setCursor):
+
+2010-08-19 Vangelis Kokkevis <vangelis@chromium.org>
+
+ Reviewed by Kenneth Russell.
+
+ [chromium] Rearranging the accelerated compositing code such that the
+ layer rendering logic now lives in the layer classes rather than the
+ compositor. This lifts the restriction of having one texture per layer
+ and significantly cleans up the compositor code. This change mostly
+ resulted in a lot of code moving around files. Noteworthy changes
+ include:
+ * Made LayerChromium a proper based class for layers that mostly handles
+ the updates to the layer properties and superlayer / sublayer updates.
+ * Introduced a new layer type, ContentLayerChromium, which handles
+ layers that require a GraphicsContext to render their content.
+ * ImageLayerChromium and VideoLayerChromium now derive from
+ ContentLayerChromium as they share the same shader and draw function.
+ * Removed TransformLayerChromium as its functionality is now replaced by
+ the base LayerChromium class.
+ * Re-arranged the order in which the members of LayerChromium are defined
+ in the header file to form a more reasonable logical grouping.
+ * Changed LayerRendererChromium to use the shader creation and drawing
+ methods defined in the layer classes. As a result, a lot of GL code was
+ removed from the implementation file.
+ * Eliminated randomly dispersed calls to check for GL errors by a macro (GLC)
+ which allows turning error testing on/off with a single define (DEBUG_GL_CALLS
+ defined in LayerRendererChromium.h)
+ * Replaced the previous layer render loop with two traversals of the layer
+ hierarchy, the first to update transforms and opacity values and the
+ second to render the layers. Eliminated global Z sorting of all layers as
+ it was wrong.
+ https://bugs.webkit.org/show_bug.cgi?id=44148
+
+ Test: Verified that pages using the compositor and compositor
+ layout tests have not regressed.
+
+ * WebCore.gypi:
+ * platform/graphics/chromium/CanvasLayerChromium.cpp:
+ (WebCore::CanvasLayerChromium::SharedValues::SharedValues):
+ (WebCore::CanvasLayerChromium::SharedValues::~SharedValues):
+ (WebCore::CanvasLayerChromium::updateContents):
+ (WebCore::CanvasLayerChromium::draw):
+ * platform/graphics/chromium/CanvasLayerChromium.h:
+ (WebCore::CanvasLayerChromium::SharedValues::canvasShaderProgram):
+ (WebCore::CanvasLayerChromium::SharedValues::shaderSamplerLocation):
+ (WebCore::CanvasLayerChromium::SharedValues::shaderMatrixLocation):
+ (WebCore::CanvasLayerChromium::SharedValues::shaderAlphaLocation):
+ (WebCore::CanvasLayerChromium::SharedValues::initialized):
+ * platform/graphics/chromium/ContentLayerChromium.cpp: Added.
+ (WebCore::ContentLayerChromium::SharedValues::SharedValues):
+ (WebCore::ContentLayerChromium::SharedValues::~SharedValues):
+ (WebCore::ContentLayerChromium::create):
+ (WebCore::ContentLayerChromium::ContentLayerChromium):
+ (WebCore::ContentLayerChromium::~ContentLayerChromium):
+ (WebCore::ContentLayerChromium::updateContents):
+ (WebCore::ContentLayerChromium::updateTextureRect):
+ (WebCore::ContentLayerChromium::draw):
+ * platform/graphics/chromium/ContentLayerChromium.h: Added.
+ (WebCore::ContentLayerChromium::drawsContent):
+ (WebCore::ContentLayerChromium::SharedValues::contentShaderProgram):
+ (WebCore::ContentLayerChromium::SharedValues::shaderSamplerLocation):
+ (WebCore::ContentLayerChromium::SharedValues::shaderMatrixLocation):
+ (WebCore::ContentLayerChromium::SharedValues::shaderAlphaLocation):
+ (WebCore::ContentLayerChromium::SharedValues::initialized):
+ * platform/graphics/chromium/GraphicsLayerChromium.cpp:
+ (WebCore::GraphicsLayerChromium::GraphicsLayerChromium):
+ (WebCore::GraphicsLayerChromium::updateLayerPreserves3D):
+ * platform/graphics/chromium/ImageLayerChromium.cpp:
+ (WebCore::ImageLayerChromium::ImageLayerChromium):
+ (WebCore::ImageLayerChromium::updateContents):
+ * platform/graphics/chromium/ImageLayerChromium.h:
+ * platform/graphics/chromium/LayerChromium.cpp:
+ (WebCore::loadShader):
+ (WebCore::LayerChromium::SharedValues::SharedValues):
+ (WebCore::LayerChromium::SharedValues::~SharedValues):
+ (WebCore::LayerChromium::LayerChromium):
+ (WebCore::LayerChromium::~LayerChromium):
+ (WebCore::LayerChromium::createShaderProgram):
+ (WebCore::LayerChromium::toGLMatrix):
+ (WebCore::LayerChromium::drawTexturedQuad):
+ (WebCore::LayerChromium::drawDebugBorder):
+ (WebCore::LayerChromium::prepareForDraw):
+ * platform/graphics/chromium/LayerChromium.h:
+ (WebCore::LayerChromium::getSublayers):
+ (WebCore::LayerChromium::setPosition):
+ (WebCore::LayerChromium::contentsDirty):
+ (WebCore::LayerChromium::drawsContent):
+ (WebCore::LayerChromium::updateContents):
+ (WebCore::LayerChromium::draw):
+ (WebCore::LayerChromium::SharedValues::quadVerticesVbo):
+ (WebCore::LayerChromium::SharedValues::quadElementsVbo):
+ (WebCore::LayerChromium::SharedValues::maxTextureSize):
+ (WebCore::LayerChromium::SharedValues::borderShaderProgram):
+ (WebCore::LayerChromium::SharedValues::borderShaderMatrixLocation):
+ (WebCore::LayerChromium::SharedValues::borderShaderColorLocation):
+ (WebCore::LayerChromium::SharedValues::initialized):
+ (WebCore::LayerChromium::layerRenderer):
+ * platform/graphics/chromium/LayerRendererChromium.cpp:
+ (WebCore::LayerRendererChromium::LayerRendererChromium):
+ (WebCore::LayerRendererChromium::~LayerRendererChromium):
+ (WebCore::LayerRendererChromium::debugGLCall):
+ (WebCore::LayerRendererChromium::useShader):
+ (WebCore::LayerRendererChromium::drawLayers):
+ (WebCore::LayerRendererChromium::createLayerTexture):
+ (WebCore::LayerRendererChromium::updateLayersRecursive):
+ (WebCore::LayerRendererChromium::drawLayersRecursive):
+ (WebCore::LayerRendererChromium::drawLayer):
+ (WebCore::LayerRendererChromium::checkTextureSize):
+ (WebCore::LayerRendererChromium::initializeSharedObjects):
+ (WebCore::LayerRendererChromium::cleanupSharedObjects):
+ * platform/graphics/chromium/LayerRendererChromium.h:
+ (WebCore::LayerRendererChromium::projectionMatrix):
+ (WebCore::LayerRendererChromium::layerSharedValues):
+ (WebCore::LayerRendererChromium::contentLayerSharedValues):
+ (WebCore::LayerRendererChromium::canvasLayerSharedValues):
+ * platform/graphics/chromium/TransformLayerChromium.cpp: Removed.
+ * platform/graphics/chromium/TransformLayerChromium.h: Removed.
+ * platform/graphics/chromium/VideoLayerChromium.cpp:
+ (WebCore::VideoLayerChromium::VideoLayerChromium):
+ (WebCore::VideoLayerChromium::updateContents):
+ (WebCore::VideoLayerChromium::createTextureRect):
+ * platform/graphics/chromium/VideoLayerChromium.h:
+
+2010-08-19 David Kilzer <ddkilzer@apple.com>
+
+ BUILD FIX: Fix Mac build after Windows WebKit2 changes for Netscape Plug-ins
+
+ * WebCore.exp.in:
+ (WebCore::ScrollView::contentsToWindow): Added export.
+
+2010-08-19 David Kilzer <ddkilzer@apple.com>
+
+ BUILD FIX #3: <http://webkit.org/b/44285> Fix compilation with NETSCAPE_PLUGIN_API disabled
+
+ Still trying to make Qt Linux Release minimal buildbot happy.
+
+ * plugins/PluginViewNone.cpp: Compile missing methods for Qt.
+
+2010-08-19 David Kilzer <ddkilzer@apple.com>
+
+ BUILD FIX: <http://webkit.org/b/44285> Fix compilation with NETSCAPE_PLUGIN_API disabled
+
+ Reviewed by Joseph Pecoraro.
+
+ * plugins/PluginView.cpp: Added #if ENABLE(NETSCAPE_PLUGIN_API)
+ and #endif macros around the source to fix the Qt Linux Release
+ Minimal build.
+
+2010-08-19 Stephen White <senorblanco@chromium.org>
+
+ Reviewed by Kenneth Russell.
+
+ [CHROMIUM] Assert w/canvas image draw
+ https://bugs.webkit.org/show_bug.cgi?id=44279
+
+ Don't use bitmap->pixelRef()->getPixels() directly; prefer
+ bitmap->pixels() and an SkAutoLockPixels. Also, make sure to set
+ the backing store state to Software when it was None. This handles
+ missing draws when the first call is software. Finally, remove some
+ spurious prepareForSoftwareDraw() calls in addPath() and beginPath().
+ It's really the fillPath() or strokePath() that matters.
+
+ Covered by LayoutTests/fast/canvas/arc360.html and others.
+
+ * platform/graphics/skia/GraphicsContextSkia.cpp:
+ (WebCore::GraphicsContext::addPath):
+ (WebCore::GraphicsContext::beginPath):
+ Remove spurious prepareForSoftwareDraw() calls.
+ * platform/graphics/skia/ImageSkia.cpp:
+ (WebCore::drawBitmapGLES2):
+ Lock SkBitmap's pixels, and use ->getPixels().
+ * platform/graphics/skia/PlatformContextSkia.cpp:
+ (WebCore::PlatformContextSkia::prepareForSoftwareDraw):
+ Switch backing store state to Software when it was None.
+
+2010-08-19 David Kilzer <ddkilzer@apple.com>
+
+ <http://webkit.org/b/44285> Fix compilation with NETSCAPE_PLUGIN_API disabled
+
+ Reviewed by Joseph Pecoraro.
+
+ * WebCore.exp.in:
+ (WebCore::HTMLPlugInElement::getNPObject): Moved from general
+ section into ENABLE(NETSCAPE_PLUGIN_API) section.
+ (WebCore::FrameView::windowClipRectForLayer): Moved from
+ ENABLE(NETSCAPE_PLUGIN_API) section to general section since
+ it's used by WebKit2.
+ * plugins/PluginView.h: Added #if ENABLE(NETSCAPE_PLUGIN_API)
+ and #endif macros as needed to make iOS WebKit build with
+ NETSCAPE_PLUGIN_API disabled.
+ * plugins/PluginViewNone.cpp: Ditto.
+ (WebCore::PluginView::platformGetValueStatic):
+
+2010-08-17 Eric Seidel <eric@webkit.org>
+
+ Reviewed by Adam Barth.
+
+ Make DocumentParser safer to use
+ https://bugs.webkit.org/show_bug.cgi?id=43055
+
+ Make DocumentParser and its subclasses RefCounted, and protect
+ HTMLDocumentParser during parsing. It's possible for a parser to
+ get deleted if certain actions (e.g., a document.write()) occur
+ synchronously.
+
+ The original version of this patch was written by Nate Chapin.
+
+ DocumentParser doesn't actually have to be fully RefCounted, since
+ the only two things which should ever hold a reference to it are
+ Document and DocumentParser itself. However using RefCounted and
+ RefPtr was easier/cleaner than inventing a custom ref() scheme.
+
+ This deploys a new "detach()" method throughout the parsing
+ framework. detach() causes the parser to disconnect from the
+ document so that no further modifications will be made to the
+ document while any possible DocumentParser stacks are unwound.
+
+ The irony of this patch is that the new detach() system is never
+ used, since Document always outlives the DocumentParser in all of
+ our layout tests. There is an ASSERT in ~Document() to verify
+ that the DocumentParser will not outlive the Document.
+
+ However I expect that we will soon either find new test cases, or change
+ the architecture in such a way that DocumentParser will outlive
+ Document. At which point, the detach() plumbing will be crucial.
+ Right now detach() serves as a safe-guard against use-after-free bugs
+ for any case where DocumentParser does outlive the Document.
+
+ This also fixes test cases attached to:
+ https://bugs.webkit.org/show_bug.cgi?id=42099
+
+ Tests: fast/frames/document-write-in-iframe-onload.html
+ fast/frames/set-parent-src-synchronously.html
+ fast/parser/document-close-iframe-load.html
+ fast/parser/document-close-nested-iframe-load.html
+ fast/parser/iframe-sets-parent-to-javascript-url.html
+
+ * dom/Document.cpp:
+ - Added a new detachParser() call to be used anywhere we
+ used to call m_parser.clear().
+ There is an ASSERT in ~DocumentParser which ensures that
+ we get this right.
+ (WebCore::Document::removedLastRef):
+ (WebCore::Document::~Document):
+ (WebCore::Document::createParser):
+ (WebCore::Document::detachParser):
+ (WebCore::Document::cancelParsing):
+ (WebCore::Document::implicitOpen):
+ - removed redundant m_parser.clear()
+ (WebCore::Document::implicitClose):
+ * dom/Document.h:
+ * dom/DocumentParser.cpp:
+ (WebCore::DocumentParser::~DocumentParser):
+ - ASSERT that callers always call detach() before destruction.
+ - This ASSERT might prove too cumbersome, but for now it's useful.
+ (WebCore::DocumentParser::detach):
+ * dom/DocumentParser.h:
+ * dom/RawDataDocumentParser.h:
+ * dom/XMLDocumentParser.cpp:
+ (WebCore::XMLDocumentParser::finish):
+ - Add a FIXME explaining part of the reason why
+ stopParsing() and detach() are separate concepts.
+ * dom/XMLDocumentParser.h:
+ (WebCore::XMLDocumentParser::create):
+ * dom/XMLDocumentParserLibxml2.cpp:
+ (WebCore::XMLDocumentParser::parseDocumentFragment):
+ * dom/XMLDocumentParserQt.cpp:
+ (WebCore::XMLDocumentParser::parseDocumentFragment):
+ * html/HTMLConstructionSite.cpp:
+ (WebCore::HTMLConstructionSite::detach):
+ (WebCore::HTMLConstructionSite::dispatchDocumentElementAvailableIfNeeded):
+ * html/HTMLConstructionSite.h:
+ * html/HTMLDocument.cpp:
+ (WebCore::HTMLDocument::createParser):
+ * html/HTMLDocument.h:
+ * html/HTMLDocumentParser.cpp:
+ - We need to protect(this) before calling into any code
+ which might cause the parser to be destroyed.
+ (WebCore::HTMLDocumentParser::~HTMLDocumentParser):
+ (WebCore::HTMLDocumentParser::detach):
+ (WebCore::HTMLDocumentParser::resumeParsingAfterYield):
+ (WebCore::HTMLDocumentParser::pumpTokenizer):
+ (WebCore::HTMLDocumentParser::insert):
+ (WebCore::HTMLDocumentParser::append):
+ (WebCore::HTMLDocumentParser::end):
+ (WebCore::HTMLDocumentParser::finish):
+ (WebCore::HTMLDocumentParser::notifyFinished):
+ (WebCore::HTMLDocumentParser::executeScriptsWaitingForStylesheets):
+ (WebCore::HTMLDocumentParser::parseDocumentFragment):
+ * html/HTMLDocumentParser.h:
+ (WebCore::HTMLDocumentParser::create):
+ * html/HTMLScriptRunner.cpp:
+ (WebCore::HTMLScriptRunner::detach):
+ (WebCore::HTMLScriptRunner::executeParsingBlockingScript):
+ (WebCore::HTMLScriptRunner::executeScript):
+ (WebCore::HTMLScriptRunner::executeScriptsWaitingForStylesheets):
+ (WebCore::HTMLScriptRunner::runScript):
+ * html/HTMLScriptRunner.h:
+ * html/HTMLTreeBuilder.cpp:
+ (WebCore::HTMLTreeBuilder::detach):
+ (WebCore::HTMLTreeBuilder::passTokenToLegacyParser):
+ (WebCore::HTMLTreeBuilder::finished):
+ * html/HTMLTreeBuilder.h:
+ * html/HTMLViewSourceDocument.cpp:
+ (WebCore::HTMLViewSourceDocument::createParser):
+ * html/HTMLViewSourceDocument.h:
+ * html/HTMLViewSourceParser.cpp:
+ (WebCore::HTMLViewSourceParser::HTMLViewSourceParser):
+ * html/HTMLViewSourceParser.h:
+ (WebCore::HTMLViewSourceParser::create):
+ * loader/FTPDirectoryDocument.cpp:
+ (WebCore::FTPDirectoryDocumentParser::create):
+ (WebCore::FTPDirectoryDocument::createParser):
+ * loader/FTPDirectoryDocument.h:
+ * loader/ImageDocument.cpp:
+ (WebCore::ImageDocumentParser::create):
+ (WebCore::ImageDocumentParser::ImageDocumentParser):
+ (WebCore::ImageDocument::createParser):
+ * loader/ImageDocument.h:
+ * loader/MediaDocument.cpp:
+ (WebCore::MediaDocumentParser::create):
+ (WebCore::MediaDocument::createParser):
+ * loader/MediaDocument.h:
+ * loader/PluginDocument.cpp:
+ (WebCore::PluginDocumentParser::create):
+ (WebCore::PluginDocument::createParser):
+ * loader/PluginDocument.h:
+ * loader/SinkDocument.cpp:
+ (WebCore::SinkDocumentParser::create):
+ (WebCore::SinkDocument::createParser):
+ * loader/SinkDocument.h:
+ * loader/TextDocument.cpp:
+ (WebCore::TextDocumentParser::create):
+ (WebCore::TextDocument::createParser):
+ (WebCore::createTextDocumentParser):
+ * loader/TextDocument.h:
+
+2010-08-19 David Kilzer <ddkilzer@apple.com>
+
+ Fix compilation of SelectElement.cpp with ARROW_KEYS_POP_MENU == 0
+
+ Reviewed by Simon Fraser.
+
+ * dom/SelectElement.cpp:
+ (WebCore::SelectElement::menuListDefaultEventHandler): Added
+ UNUSED_PARAM() macro for htmlForm argument when
+ ARROW_KEYS_POP_MENU defined as zero.
+
+2010-08-19 Laszlo Gombos <laszlo.1.gombos@nokia.com>
+
+ Reviewed by Simon Hausmann.
+
+ [Qt] Disable XSLT for production configuration
+ https://bugs.webkit.org/show_bug.cgi?id=37445
+
+ Introduce a new CONFIG option to maintain stable configuration for
+ the QtWebKit port and disable XSLT for the stable configuration
+ because of bug 37445.
+
+ No new tests as there is no new functionality.
+
+ * features.pri:
+
+2010-08-18 Zhenyao Mo <zmo@google.com>
+
+ Reviewed by Kenneth Russell.
+
+ Implement strict type checking in js bindings for WebGL functions
+ https://bugs.webkit.org/show_bug.cgi?id=44202
+
+ Test: fast/canvas/webgl/bad-arguments-test.html
+
+ * bindings/js/JSWebGLRenderingContextCustom.cpp: Add type check for wrapper types and DOMString and throw error in case of mismatch.
+ (WebCore::JSWebGLRenderingContext::getAttachedShaders):
+ (WebCore::JSWebGLRenderingContext::getProgramParameter):
+ (WebCore::JSWebGLRenderingContext::getShaderParameter):
+ (WebCore::JSWebGLRenderingContext::getUniform):
+ (WebCore::dataFunctionf):
+ (WebCore::dataFunctioni):
+ (WebCore::dataFunctionMatrix):
+ * bindings/scripts/CodeGeneratorJS.pm: Ditto.
+ * bindings/scripts/CodeGeneratorV8.pm: Ditto.
+ * bindings/v8/custom/V8WebGLRenderingContextCustom.cpp: Ditto.
+ (WebCore::V8WebGLRenderingContext::getAttachedShadersCallback):
+ (WebCore::V8WebGLRenderingContext::getProgramParameterCallback):
+ (WebCore::V8WebGLRenderingContext::getShaderParameterCallback):
+ (WebCore::V8WebGLRenderingContext::getUniformCallback):
+ (WebCore::vertexAttribAndUniformHelperf):
+ (WebCore::uniformHelperi):
+ (WebCore::uniformMatrixHelper):
+ * html/canvas/WebGLRenderingContext.idl: Add attribute StrictTypeChecking for WebGL functions.
+
+2010-08-19 Simon Fraser <simon.fraser@apple.com>
+
+ Reviewed by Sam Weinig.
+
+ Clean up some selection code
+ https://bugs.webkit.org/show_bug.cgi?id=44314
+
+ Change the concept of "layout" in SelectionController to "updateCaretRect", renaming
+ methods accordingly.
+
+ Move selection and printing methods in RenderView.h into groups.
+
+ No behavioral changes.
+
+ * editing/SelectionController.cpp:
+ (WebCore::SelectionController::SelectionController):
+ (WebCore::SelectionController::setSelection):
+ (WebCore::SelectionController::modify):
+ (WebCore::SelectionController::setCaretRectNeedsUpdate):
+ (WebCore::SelectionController::updateCaretRect):
+ (WebCore::SelectionController::localCaretRect):
+ (WebCore::SelectionController::recomputeCaretRect): Test m_caretRectNeedsUpdate first.
+ (WebCore::SelectionController::invalidateCaretRect):
+ * editing/SelectionController.h:
+ * page/FrameView.cpp:
+ (WebCore::FrameView::layout):
+ * rendering/RenderLayer.cpp:
+ (WebCore::RenderLayer::scrollToOffset):
+ * rendering/RenderView.h:
+ (WebCore::RenderView::selectionStart):
+ (WebCore::RenderView::selectionEnd):
+ (WebCore::RenderView::printRect):
+ (WebCore::RenderView::setPrintRect):
+
+2010-08-19 Simon Fraser <simon.fraser@apple.com>
+
+ Fix Chromium build.
+
+ * svg/SVGElement.cpp:
+ (WebCore::SVGElement::attributeChanged):
+
+2010-08-19 Simon Fraser <simon.fraser@apple.com>
+
+ Reviewed by Nikolas Zimmermann.
+
+ HTMLElement::isContentEditable() can cause an updateStyleIfNeeded() to happen in the middle of layout
+ https://bugs.webkit.org/show_bug.cgi?id=21834
+ <rdar://problem/8093653&8261394>
+
+ If we're in the middle of layout, or painting, and something causes updateStyleIfNeeded() to
+ get called, then we can end up entering recalcStyle() during layout or painting. This is bad
+ because it can create/destry the renderers and RenderLayers which are in use by layout/painting.
+ This is the cause of a number of random crashers, some of which show up more frequently
+ in content which uses accelerated compositing.
+
+ The changes here:
+ 1. Add an assertion in Document::updateStyleIfNeeded() that we are not laying out or painting.
+ 2. Remove calls to updateStyleIfNeeded() in editing and caret painting code
+ 3. Pass along information to CTM and BBox-related SVG methods to indicate whether it's safe
+ to update style.
+
+ Tested by new assertions and existing tests.
+
+ * dom/Document.cpp:
+ (WebCore::Document::updateStyleIfNeeded): New assertion that we are not mid-layout or painting.
+ (WebCore::command): Call updateStyleIfNeeded() to ensure that subsequent calls to isContentEditable()
+ return the correct result.
+
+ * dom/Element.cpp:
+ (WebCore::Element::focus): Move the supportsFocus() call to after style has been updated.
+
+ * editing/SelectionController.cpp:
+ (WebCore::SelectionController::localCaretRect):
+ (WebCore::SelectionController::caretRepaintRect):
+ (WebCore::SelectionController::paintCaret):
+ * editing/SelectionController.h:
+ (WebCore::SelectionController::localCaretRectForPainting): When painting, use localCaretRectForPainting()
+ which does not update style. Make localCaretRect() non-const so allowing it to update style without ugly casts.
+
+ * html/HTMLElement.cpp:
+ (WebCore::HTMLElement::isContentEditable): Don't call updateStyleIfNeeded() here.
+ (WebCore::HTMLElement::isContentRichlyEditable): Ditto.
+ (WebCore::HTMLElement::contentEditable): Ditto.
+
+ * page/FrameView.h:
+ (WebCore::FrameView::isMidLayout): New accessor, used for asserting.
+
+ * rendering/RenderPath.cpp:
+ (WebCore::fillAndStrokePath): Pass DisallowStyleUpdate to getScreenCTM since we are painting.
+ * rendering/RenderSVGResourceContainer.cpp:
+ (WebCore::RenderSVGResourceContainer::transformOnNonScalingStroke): This is only called when
+ painting, so use DisallowStyleUpdate.
+
+ * svg/SVGElement.cpp:
+ (WebCore::SVGElement::attributeChanged): Changes to the style attribute should not have
+ side effects, since a call to Element::getAttribute() is allowed to result in a call to
+ setAttribute() for the style attribute. To avoid updateStyleIfNeeded() during painting,
+ this must not cause SVG to do extra work.
+
+ * svg/SVGLocatable.cpp: Pass StyleUpdateStrategy down to these methods to indicate
+ whether it's OK to update style.
+ (WebCore::SVGLocatable::getBBox):
+ (WebCore::SVGLocatable::computeCTM):
+ (WebCore::SVGLocatable::getTransformToElement):
+ * svg/SVGLocatable.h:
+ (WebCore::SVGLocatable::):
+ * svg/SVGStyledLocatableElement.cpp:
+ (WebCore::SVGStyledLocatableElement::getBBox):
+ (WebCore::SVGStyledLocatableElement::getCTM):
+ (WebCore::SVGStyledLocatableElement::getScreenCTM):
+ * svg/SVGStyledLocatableElement.h:
+ * svg/SVGStyledTransformableElement.cpp:
+ (WebCore::SVGStyledTransformableElement::getCTM):
+ (WebCore::SVGStyledTransformableElement::getScreenCTM):
+ (WebCore::SVGStyledTransformableElement::getBBox):
+ * svg/SVGStyledTransformableElement.h:
+ * svg/SVGTextElement.cpp:
+ (WebCore::SVGTextElement::getBBox):
+ (WebCore::SVGTextElement::getCTM):
+ (WebCore::SVGTextElement::getScreenCTM):
+ * svg/SVGTextElement.h:
+
+2010-08-19 Ryosuke Niwa <rniwa@webkit.org>
+
+ Reviewed by Darin Adler.
+
+ Range, EAnnotateForInterchange, and EAbsoluteURLs should be member variables of MarkupAccumulator
+ https://bugs.webkit.org/show_bug.cgi?id=44229
+
+ No new tests are added since this is a clean up.
+
+ * editing/markup.cpp:
+ (WebCore::MarkupAccumulator::MarkupAccumulator): Added shouldResolveURLs, shouldAnnotate, and range.
+ (WebCore::MarkupAccumulator::shouldResolveURLs): Private inline accessor for m_shouldResolveURLs.
+ (WebCore::MarkupAccumulator::shouldAnnotate): Private inline accessor for m_shouldAnnotate.
+ (WebCore::MarkupAccumulator::appendEndTag): Renamed local variable result to markup.
+ (WebCore::MarkupAccumulator::appendStartTag): Removed range, annotate, shouldResolveURLs from the function arguments.
+ (WebCore::MarkupAccumulator::wrapWithNode): Ditto.
+ (WebCore::MarkupAccumulator::appendStartMarkup): Ditto.
+ (WebCore::serializeNodes): Ditto and uses MarkupAccumulator.
+ (WebCore::createMarkup): Uses MarkupAccumulator.
+ (WebCore::serializeNodesWithNamespaces): Ditto.
+
+2010-08-19 Pavel Feldman <pfeldman@chromium.org>
+
+ Reviewed by Yury Semikhatsky.
+
+ Web Inspector: do not dump inspector errors into the inspected window console.
+ https://bugs.webkit.org/show_bug.cgi?id=44272
+
+ * inspector/front-end/inspector.js:
+ (WebInspector.reportProtocolError):
+
+2010-08-19 Jeremy Orlow <jorlow@chromium.org>
+
+ Chromium build fix.
+
+ Use ASSERT_UNUSED on variables that aren't used besides by the ASSERT.
+
+ * storage/IDBDatabaseBackendImpl.cpp:
+ (WebCore::IDBDatabaseBackendImpl::createObjectStore):
+ (WebCore::IDBDatabaseBackendImpl::removeObjectStore):
+ (WebCore::IDBDatabaseBackendImpl::loadObjectStores):
+ * storage/IDBObjectStoreBackendImpl.cpp:
+ (WebCore::IDBObjectStoreBackendImpl::get):
+ (WebCore::IDBObjectStoreBackendImpl::put):
+ (WebCore::IDBObjectStoreBackendImpl::remove):
+ (WebCore::IDBObjectStoreBackendImpl::createIndex):
+ (WebCore::IDBObjectStoreBackendImpl::removeIndex):
+ (WebCore::IDBObjectStoreBackendImpl::openCursor):
+ (WebCore::IDBObjectStoreBackendImpl::loadIndexes):
+
+2010-08-19 Andrey Kosyakov <caseq@chromium.org>
+
+ Reviewed by Pavel Feldman.
+
+ Web Inspector: expose Panel.onSelectionChanged in extension API
+ https://bugs.webkit.org/show_bug.cgi?id=44171
+
+ * inspector/front-end/ExtensionAPI.js:
+ (injectedExtensionAPI.PanelImpl):
+ (injectedExtensionAPI):
+
+2010-08-19 Andrei Popescu <andreip@google.com>
+
+ Reviewed by Jeremy Orlow.
+
+ [IndexedDB] Abort idle IDBTransactions when the JS context they were created in finishes execution.
+ https://bugs.webkit.org/show_bug.cgi?id=44101
+
+ This change also introduces the TransactionCoordinator, which will be used
+ to schedule transactions for execution.
+
+ Test: storage/indexeddb/transaction-basics.html
+
+ * WebCore.gypi:
+ * bindings/v8/V8DOMWrapper.cpp:
+ (WebCore::V8DOMWrapper::convertEventTargetToV8Object):
+ * bindings/v8/V8Proxy.cpp:
+ (WebCore::V8Proxy::runScript):
+ (WebCore::V8Proxy::callFunction):
+ (WebCore::V8Proxy::didLeaveScriptContext):
+ * bindings/v8/V8Proxy.h:
+ * dom/EventTarget.cpp:
+ (WebCore::EventTarget::toIDBTransaction):
+ * dom/EventTarget.h:
+ * page/PageGroup.h:
+ (WebCore::PageGroup::hasIDBFactory):
+ * storage/IDBAbortEvent.cpp: Added.
+ (WebCore::IDBAbortEvent::create):
+ (WebCore::IDBAbortEvent::IDBAbortEvent):
+ (WebCore::IDBAbortEvent::~IDBAbortEvent):
+ * storage/IDBAbortEvent.h: Added.
+ (WebCore::IDBAbortEvent::isIDBAbortEvent):
+ * storage/IDBDatabase.cpp:
+ (WebCore::IDBDatabase::transaction):
+ * storage/IDBDatabaseBackendImpl.cpp:
+ (WebCore::IDBDatabaseBackendImpl::IDBDatabaseBackendImpl):
+ (WebCore::IDBDatabaseBackendImpl::transaction):
+ * storage/IDBDatabaseBackendImpl.h:
+ (WebCore::IDBDatabaseBackendImpl::create):
+ * storage/IDBDatabaseBackendInterface.h:
+ * storage/IDBFactoryBackendImpl.cpp:
+ (WebCore::IDBFactoryBackendImpl::IDBFactoryBackendImpl):
+ (WebCore::IDBFactoryBackendImpl::open):
+ (WebCore::IDBFactoryBackendImpl::abortPendingTransactions):
+ * storage/IDBFactoryBackendImpl.h:
+ * storage/IDBFactoryBackendInterface.h:
+ * storage/IDBPendingTransactionMonitor.cpp: Added.
+ (WebCore::IDBPendingTransactionMonitor::addPendingTransaction):
+ (WebCore::IDBPendingTransactionMonitor::removePendingTransaction):
+ (WebCore::IDBPendingTransactionMonitor::clearPendingTransactions):
+ (WebCore::IDBPendingTransactionMonitor::pendingTransactions):
+ * storage/IDBPendingTransactionMonitor.h: Added.
+ * storage/IDBTransaction.cpp:
+ (WebCore::IDBTransaction::IDBTransaction):
+ (WebCore::IDBTransaction::onAbort):
+ (WebCore::IDBTransaction::id):
+ (WebCore::IDBTransaction::stop):
+ (WebCore::IDBTransaction::timerFired):
+ * storage/IDBTransaction.h:
+ * storage/IDBTransactionBackendInterface.h:
+ * storage/IDBTransactionCallbacks.h: Added.
+ (WebCore::IDBTransactionCallbacks::~IDBTransactionCallbacks):
+ * storage/IDBTransactionCoordinator.cpp: Added.
+ (WebCore::IDBTransactionBackendImpl::~IDBTransactionBackendImpl):
+ (WebCore::IDBTransactionBackendImpl::create):
+ (WebCore::IDBTransactionBackendImpl::IDBTransactionBackendImpl):
+ (WebCore::IDBTransactionBackendImpl::objectStore):
+ (WebCore::IDBTransactionBackendImpl::mode):
+ (WebCore::IDBTransactionBackendImpl::scheduleTask):
+ (WebCore::IDBTransactionBackendImpl::abort):
+ (WebCore::IDBTransactionBackendImpl::sqliteDatabase):
+ (WebCore::IDBTransactionBackendImpl::id):
+ (WebCore::IDBTransactionBackendImpl::setCallbacks):
+ (WebCore::IDBTransactionCoordinator::IDBTransactionCoordinator):
+ (WebCore::IDBTransactionCoordinator::~IDBTransactionCoordinator):
+ (WebCore::IDBTransactionCoordinator::createTransaction):
+ (WebCore::IDBTransactionCoordinator::abort):
+ * storage/IDBTransactionCoordinator.h: Added.
+ (WebCore::IDBTransactionCoordinator::create):
+
+2010-08-19 Pavel Feldman <pfeldman@chromium.org>
+
+ Reviewed by Yury Semikhatsky.
+
+ Chromium DevTools: There is no need in resource-based InjectedScript.js source.
+ Now that we populate front-end after its onload handler, we don't need
+ to install injected script early. Exposing injected script source on the WebCore
+ level here.
+ https://bugs.webkit.org/show_bug.cgi?id=44029
+
+ * inspector/InjectedScriptHost.h:
+ (WebCore::InjectedScriptHost::injectedScriptSource):
+
+2010-08-18 Jeremy Orlow <jorlow@chromium.org>
+
+ Reviewed by Steve Block.
+
+ Implement persistance for IndexedDB ObjectStores
+ https://bugs.webkit.org/show_bug.cgi?id=44164
+
+ Get rid of the in-memory storage of ObjectStores and instead
+ use SQL backed memory.
+
+ Existing tests give most of the coverage. Will update the manual
+ test in the next patch (which will also re-work database.description).
+
+ * manual-tests/indexed-database.html: Get rid of race where you can click before the page loads.
+ * platform/sql/SQLiteStatement.cpp: Add two helper functions
+ (WebCore::SQLiteStatement::bindInt):
+ (WebCore::SQLiteStatement::isColumnNull):
+ * platform/sql/SQLiteStatement.h:
+ * storage/IDBCursorBackendImpl.cpp:
+ * storage/IDBDatabaseBackendImpl.cpp:
+ (WebCore::IDBDatabaseBackendImpl::IDBDatabaseBackendImpl):
+ (WebCore::IDBDatabaseBackendImpl::createObjectStore):
+ (WebCore::IDBDatabaseBackendImpl::removeObjectStore):
+ (WebCore::IDBDatabaseBackendImpl::importObjectStores):
+ * storage/IDBDatabaseBackendImpl.h:
+ (WebCore::IDBDatabaseBackendImpl::sqliteDatabase):
+ * storage/IDBFactoryBackendImpl.cpp:
+ (WebCore::createTables):
+ * storage/IDBIndexBackendImpl.cpp:
+ (WebCore::IDBIndexBackendImpl::IDBIndexBackendImpl):
+ (WebCore::IDBIndexBackendImpl::sqliteDatabase):
+ * storage/IDBIndexBackendImpl.h:
+ (WebCore::IDBIndexBackendImpl::create):
+ * storage/IDBObjectStoreBackendImpl.cpp:
+ (WebCore::IDBObjectStoreBackendImpl::IDBObjectStoreBackendImpl):
+ (WebCore::whereClause):
+ (WebCore::bindKey):
+ (WebCore::IDBObjectStoreBackendImpl::get):
+ (WebCore::IDBObjectStoreBackendImpl::put):
+ (WebCore::IDBObjectStoreBackendImpl::remove):
+ (WebCore::IDBObjectStoreBackendImpl::createIndex):
+ (WebCore::IDBObjectStoreBackendImpl::removeIndex):
+ (WebCore::IDBObjectStoreBackendImpl::openCursor):
+ (WebCore::IDBObjectStoreBackendImpl::importIndexes):
+ (WebCore::IDBObjectStoreBackendImpl::sqliteDatabase):
+ * storage/IDBObjectStoreBackendImpl.h:
+ (WebCore::IDBObjectStoreBackendImpl::create):
+ (WebCore::IDBObjectStoreBackendImpl::database):
+
+2010-08-19 Nikolas Zimmermann <nzimmermann@rim.com>
+
+ Reviewed by Dirk Schulze.
+
+ Pattern is rasterized
+ https://bugs.webkit.org/show_bug.cgi?id=41396
+
+ SVG pattern size changed when resizing browser
+ https://bugs.webkit.org/show_bug.cgi?id=38704
+
+ Incorrect pattern tilling
+ https://bugs.webkit.org/show_bug.cgi?id=41603
+
+ Apply same fixes to <pattern> that <mask> recently received. Build the tile image in absolute coordinates,
+ to avoid pixelation, when the target element is scaled. Also fixes problems when zooming into patterns.
+
+ Clamp ImageBuffer sizes to RenderSVGRoots viewport, now that gradient/pattern and mask buffers are created
+ in absolute coordinates -> no more huge image buffer allocations, that could fail.
+
+ Drop overflow="visible" support for <pattern>, which complicates the code a lot. Neither Opera nor Firefox
+ support this, and SVG 1.1 2nd Edition says that the rendering behaviour is "undefined".
+
+ Tests: svg/batik/paints/patternRegions-positioned-objects.svg
+ svg/custom/pattern-incorrect-tiling.svg
+ svg/custom/pattern-no-pixelation.svg
+ svg/transforms/text-with-mask-with-svg-transform.svg
+
+ * rendering/PaintInfo.h:
+ (WebCore::PaintInfo::applyTransform): Don't alter the repaint rect if it's infinite (only affects SVG).
+ (WebCore::PaintInfo::infiniteRect): Moved from RenderLayer into PaintInfo, as applyTransform() needs it.
+ * rendering/RenderLayer.cpp:
+ (WebCore::RenderLayer::calculateClipRects): s/ClipRects::infiniteRect/PaintInfo::infiniteRect/
+ * rendering/RenderLayer.h: Moved infiniteRect() to PaintInfo.
+ * rendering/RenderLayerBacking.cpp:
+ (WebCore::clipBox): s/ClipRects::infiniteRect/PaintInfo::infiniteRect/
+ * rendering/RenderLayerCompositor.cpp:
+ (WebCore::RenderLayerCompositor::clippedByAncestor): Ditto.
+ * rendering/RenderSVGResourceGradient.cpp:
+ (WebCore::createMaskAndSwapContextForTextGradient): Clamp image buffer size, use new SVGImageBufferTools helper methods for that.
+ (WebCore::clipToTextMask): Adapt to renames/code changes in SVGImageBufferTools.
+ (WebCore::RenderSVGResourceGradient::applyResource): Ditto.
+ * rendering/RenderSVGResourceMasker.cpp:
+ (WebCore::RenderSVGResourceMasker::applyResource): lamp image buffer size, use new SVGImageBufferTools helper methods for that.
+ (WebCore::RenderSVGResourceMasker::drawContentIntoMaskImage): Adapt to renames/code changes in SVGImageBufferTools.
+ * rendering/RenderSVGResourceMasker.h:
+ * rendering/RenderSVGResourcePattern.cpp:
+ (WebCore::RenderSVGResourcePattern::applyResource): Rewrite to create tile image buffers in absolute coordinates, avoids pixelation artefacts.
+ (WebCore::calculatePatternBoundaries):
+ (WebCore::RenderSVGResourcePattern::buildTileImageTransform):
+ (WebCore::RenderSVGResourcePattern::createTileImage):
+ * rendering/RenderSVGResourcePattern.h:
+ * rendering/SVGImageBufferTools.cpp:
+ (WebCore::SVGImageBufferTools::transformationToOutermostSVGCoordinateSystem): Helper method, concating all localToParentTransforms() up until RenderSVGRoot is reached.
+ (WebCore::SVGImageBufferTools::createImageBuffer): Simplified.
+ (WebCore::SVGImageBufferTools::clipToImageBuffer): Rename absoluteTargetRect to clampedAbsoluteTargetRect.
+ (WebCore::SVGImageBufferTools::roundedImageBufferSize): New helper method to centralize FloatSize -> IntSize rounding, when creating image buffers.
+ (WebCore::SVGImageBufferTools::clampedAbsoluteTargetRectForRenderer): New helper methods to clamp an image buffer rect against the viewport.
+ * rendering/SVGImageBufferTools.h:
+ * rendering/SVGRenderSupport.cpp:
+ (WebCore::SVGRenderSupport::renderSubtreeToImage): Use PaintInfo::infiniteRect() as repaint rect, to avoid any culling.
+ (WebCore::SVGRenderSupport::findTreeRootObject): Renamed from svgRootTreeObject, and expose it.
+ (WebCore::SVGRenderSupport::layoutChildren): s/svgRootTreeObject/findTreeRootObject/.
+ * rendering/SVGRenderSupport.h:
+ * svg/SVGSVGElement.cpp:
+ (WebCore::SVGSVGElement::setCurrentTranslate): Be sure to relayout on invalidation, otherwhise resources are not updated, and we have to update them, as they depend on the absolute transform.
+
+2010-08-19 Alejandro G. Castro <alex@igalia.com>
+
+ Reviewed by Dirk Schulze.
+
+ [GTK] The size of the shadow image uses the standard deviation
+ size instead of the blur radius
+ https://bugs.webkit.org/show_bug.cgi?id=40793
+
+ The kernelSize variable was renamed to radius and recalculated
+ considering the CSS3 specification
+ http://www.w3.org/TR/css3-background/#the-box-shadow, and the
+ visual result of other browsers. The HTML5 canvas shadow standard
+ deviation calculation that was used, was not appropiate for the
+ blur distance specified in the CSS3.
+
+ * platform/graphics/GraphicsContext.h:
+ * platform/graphics/cairo/FontCairo.cpp:
+ (WebCore::Font::drawGlyphs):
+ * platform/graphics/cairo/GraphicsContextCairo.cpp:
+ (WebCore::GraphicsContext::calculateShadowBufferDimensions):
+ Changed the calculation, now we use the parameter in the style
+ directly as recomended in the CSS3 standard.
+ (WebCore::drawPathShadow):
+ (WebCore::drawBorderlessRectShadow):
+ (WebCore::GraphicsContext::createPlatformShadow): We get the
+ standard deviation from the radius using the new function and we
+ create the filter with that deviation.
+ * platform/graphics/cairo/ImageCairo.cpp:
+ (WebCore::BitmapImage::draw):
+ * platform/graphics/filters/FEGaussianBlur.cpp:
+ (WebCore::FEGaussianBlur::calculateStdDeviation): Added this
+ function that gets the standard deviation from the blur
+ radius. Required in the CSS3 case where we have this radio and we
+ need the deviation to initialize the algorithm.
+ * platform/graphics/filters/FEGaussianBlur.h:
+
+2010-08-19 Andreas Kling <andreas.kling@nokia.com>
+
+ Reviewed by Kenneth Rohde Christiansen.
+
+ [Qt] Avoid unnecessary string copy in TextCodecQt::decode()
+ https://bugs.webkit.org/show_bug.cgi?id=44232
+
+ * platform/text/qt/TextCodecQt.cpp:
+ (WebCore::TextCodecQt::decode): Use String::append(const UChar*, int)
+ to avoid creating a temporary string.
+
+2010-08-19 Philippe Normand <pnormand@igalia.com>
+
+ Reviewed by Gustavo Noronha Silva.
+
+ [GStreamer] GTK XOverlay support in GStreamerGWorld
+ https://bugs.webkit.org/show_bug.cgi?id=39474
+
+ GStreamerGWorld now catches synchronous messages coming from the
+ sinks and creates a GTK window where the video can be overlayed if
+ fullscreen display is requested using enterFullscreen.
+
+ * GNUmakefile.am:
+ * platform/graphics/gstreamer/GStreamerGWorld.cpp:
+ (WebCore::gstGWorldSyncMessageCallback):
+ (WebCore::GStreamerGWorld::GStreamerGWorld):
+ (WebCore::GStreamerGWorld::~GStreamerGWorld):
+ (WebCore::GStreamerGWorld::enterFullscreen):
+ (WebCore::GStreamerGWorld::exitFullscreen):
+ (WebCore::GStreamerGWorld::setWindowOverlay):
+ * platform/graphics/gstreamer/GStreamerGWorld.h:
+ (WebCore::GStreamerGWorld::pipeline):
+ (WebCore::GStreamerGWorld::platformVideoWindow):
+ * platform/graphics/gstreamer/MediaPlayerPrivateGStreamer.cpp:
+ * platform/graphics/gstreamer/PlatformVideoWindow.h: Added.
+ (WebCore::PlatformVideoWindow::createWindow):
+ (WebCore::PlatformVideoWindow::window):
+ (WebCore::PlatformVideoWindow::videoWindowId):
+ * platform/graphics/gstreamer/PlatformVideoWindowGtk.cpp: Added.
+ (PlatformVideoWindow::PlatformVideoWindow):
+
+2010-08-19 Eric Uhrhane <ericu@chromium.org>
+
+ Reviewed by David Levin.
+
+ Add idl and mock classes for FileWriter.
+ https://bugs.webkit.org/show_bug.cgi?id=44075
+
+ No new tests, since there's no new functionality.
+
+ New do-nothing classes, but the real IDL:
+ * FileWriter.idl:
+ * FileWriter.h:
+ * FileWriter.cpp:
+
+ The build file changes to include the above:
+ * CMakeLists.txt:
+ * DerivedSources.cpp:
+ * DerivedSources.make:
+ * GNUmakefile.am:
+ * WebCore.gypi:
+ * WebCore.pri:
+ * WebCore.pro:
+ * WebCore.vcproj/WebCore.vcproj:
+ * WebCore.xcodeproj/project.pbxproj:
+
+ Added FileWriter event names and required EventTarget changes.
+ * dom/EventNames.h:
+ * dom/EventTarget.cpp:
+ (WebCore::EventTarget::toFileWriter):
+ * dom/EventTarget.h:
+
+2010-08-18 Andreas Kling <andreas.kling@nokia.com>
+
+ Rubber-stamped by Ariya Hidayat.
+
+ [Qt] Remove unused variable in GraphicsContext::fillRect()
+
+ * platform/graphics/qt/GraphicsContextQt.cpp:
+ (WebCore::GraphicsContext::fillRect):
+
+2010-08-18 Ariya Hidayat <ariya@sencha.com>
+
+ Reviewed by Kenneth Rohde Christiansen.
+
+ [Qt] Short lived shadow buffer for blur operation
+ https://bugs.webkit.org/show_bug.cgi?id=44094
+
+ ContextShadow needs a scratch image as the buffer for the blur filter.
+ Instead of creating and destroying the buffer for every operation,
+ we create a buffer which will be automatically purged via a timer.
+
+ * platform/graphics/qt/ContextShadow.cpp:
+ (WebCore::):
+ (WebCore::ShadowBuffer::ShadowBuffer):
+ (WebCore::ShadowBuffer::scratchImage):
+ (WebCore::ShadowBuffer::schedulePurge):
+ (WebCore::ShadowBuffer::purgeBuffer):
+ (WebCore::ContextShadow::drawShadowRect):
+
+2010-08-18 Alexey Marinichev <amarinichev@chromium.org>
+
+ Reviewed by Darin Fisher.
+
+ [chromium] scrolling issues when accelerated compositor is enabled
+ https://bugs.webkit.org/show_bug.cgi?id=43992
+
+ Corrected scroll position not being updated, and an off-by-half error.
+ Int cast and floorf are taken out because they produce incorrect
+ transformation matrix. The information lost there is not immediately
+ obvious because of rounding that happens when texture is mapped with
+ GL_NEAREST filtering mode. These errors accumulate, and after some
+ scrolling it becomes more apparent.
+
+ To test the former, follow instructions in the bug. To test the
+ latter, change GL_NEAREST to GL_LINEAR in LayerRendererChromium.cpp.
+ Scrolling should work properly for all window sizes, without blurring
+ images and shifting them to the left.
+
+ * platform/graphics/chromium/LayerRendererChromium.cpp:
+ (WebCore::LayerRendererChromium::drawLayers):
+
+2010-08-18 Simon Hausmann <simon.hausmann@nokia.com>
+
+ Reviewed by Ariya Hidayat.
+
+ [Qt] Implement GraphicsContext::clipOut more efficiently
+ https://bugs.webkit.org/show_bug.cgi?id=43416
+
+ The current implementation of clipOut uses QPainter::clipRegion().boundingRect(),
+ which is a very slow function because it converts the entire clip region - which
+ may potentially contain a complex path - into a set of QRegion rectangles, just
+ to throw away all that information and use the bounding rect.
+
+ QTBUG-12618 implements a faster function in QPainter: QPainter::clipBoundingRect().
+
+ * platform/graphics/qt/GraphicsContextQt.cpp:
+ (WebCore::GraphicsContext::clipOut): Use QPainter::clipBoundingRect() with Qt >= 4.8.
+ (WebCore::GraphicsContext::clipOutEllipseInRect): Ditto.
+
+2010-08-18 Martin Robinson <mrobinson@igalia.com>
+
+ Reviewed by Gustavo Noronha Silva.
+
+ [GTK] Since the GSEAL changes moz_gtk_scrollbar_button_paint fiddles the widget allocation but doesn't preserve it
+ https://bugs.webkit.org/show_bug.cgi?id=44211
+
+ No new tests as we do not currently use the scrollbar button painting
+ code. Tests for this issue will be enabled when we have pixel tests
+ for WebCore-drawn interior frame scrollbars.
+
+ * platform/gtk/GtkVersioning.h: Add backward-compatible functions for getting
+ and setting the widget allocation.
+ * platform/gtk/gtk2drawing.c:
+ (moz_gtk_scrollbar_button_paint): Use new backward-compatible functions for getting
+ and setting the widget allocation.
+
+2010-08-18 Ryosuke Niwa <rniwa@webkit.org>
+
+ Reviewed by Darin Adler.
+
+ Group functions in markup.cpp into MarkupAccumulatorWrapper
+ https://bugs.webkit.org/show_bug.cgi?id=43936
+
+ Renamed MarkupAccumulatorWrapper to MarkupAccumulator and moved the MarkupAccumulatorWrapper
+ to the top of markup.cpp. Made various functions private member functions of MarkupAccumulator.
+
+ No new tests are added since this is a cleanup.
+
+ * editing/markup.cpp:
+ (WebCore::MarkupAccumulator::):
+ (WebCore::MarkupAccumulator::MarkupAccumulator):
+ (WebCore::MarkupAccumulator::appendString):
+ (WebCore::MarkupAccumulator::appendStartTag):
+ (WebCore::MarkupAccumulator::appendEndTag):
+ (WebCore::MarkupAccumulator::wrapWithNode):
+ (WebCore::MarkupAccumulator::wrapWithStyleNode):
+ (WebCore::MarkupAccumulator::takeResults):
+ (WebCore::MarkupAccumulator::appendAttributeValue):
+ (WebCore::MarkupAccumulator::escapeContentText):
+ (WebCore::MarkupAccumulator::appendQuotedURLAttributeValue):
+ (WebCore::MarkupAccumulator::stringValueForRange):
+ (WebCore::MarkupAccumulator::ucharRange):
+ (WebCore::MarkupAccumulator::appendUCharRange):
+ (WebCore::MarkupAccumulator::renderedText):
+ (WebCore::MarkupAccumulator::shouldAddNamespaceElement):
+ (WebCore::MarkupAccumulator::shouldAddNamespaceAttribute):
+ (WebCore::MarkupAccumulator::appendNamespace):
+ (WebCore::MarkupAccumulator::appendDocumentType):
+ (WebCore::MarkupAccumulator::removeExteriorStyles):
+ (WebCore::MarkupAccumulator::appendStartMarkup):
+ (WebCore::MarkupAccumulator::shouldSelfClose):
+ (WebCore::MarkupAccumulator::appendEndMarkup):
+ (WebCore::serializeNodes):
+ (WebCore::createMarkup):
+ (WebCore::serializeNodesWithNamespaces):
+
+2010-08-18 Beth Dakin <bdakin@apple.com>
+
+ Reviewed by Sam Weinig.
+
+ Fix for https://bugs.webkit.org/show_bug.cgi?id=44207 Empty mfrac
+ and empty munderover cause crashes
+ -and corresponding-
+ <rdar://problem/8325160>
+
+ This is just a matter of adding null checks in the right places.
+ * mathml/RenderMathMLFraction.cpp:
+ (WebCore::RenderMathMLFraction::baselinePosition):
+ * mathml/RenderMathMLUnderOver.cpp:
+ (WebCore::RenderMathMLUnderOver::baselinePosition):
+
+2010-08-18 Jian Li <jianli@chromium.org>
+
+ Reviewed by David Levin.
+
+ Move FileStream to platform.
+ https://bugs.webkit.org/show_bug.cgi?id=44213
+
+ In addition to moving files over, FileStream has been changed to remove
+ ExceptionCode dependency. Also update FileStreamProxy and FileRead to
+ account for this change.
+
+ * Android.mk:
+ * GNUmakefile.am:
+ * WebCore.gypi:
+ * WebCore.pro:
+ * WebCore.vcproj/WebCore.vcproj:
+ * WebCore.xcodeproj/project.pbxproj:
+ * html/FileReader.cpp:
+ (WebCore::FileReader::didOpen):
+ * html/FileReader.h:
+ * html/FileStream.cpp: Removed.
+ * html/FileStream.h: Removed.
+ * html/FileStreamClient.h:
+ (WebCore::FileStreamClient::didTruncate):
+ (WebCore::FileStreamClient::didOpen):
+ * html/FileStreamProxy.cpp:
+ (WebCore::didOpen):
+ (WebCore::FileStreamProxy::openForReadOnFileThread):
+ (WebCore::FileStreamProxy::openForWriteOnFileThread):
+ (WebCore::FileStreamProxy::write):
+ (WebCore::FileStreamProxy::writeOnFileThread):
+ (WebCore::didTruncate):
+ (WebCore::FileStreamProxy::truncateOnFileThread):
+ * html/FileStreamProxy.h:
+ * platform/FileStream.cpp: Renamed from WebCore/FileStream.cpp and updated.
+ * platform/FileStream.h: Renamed from WebCore/FileStream.h and updated.
+
+2010-08-18 Jian Li <jianli@chromium.org>
+
+ Reviewed by Darin Fisher.
+
+ Chromium side implementation of blob data and blob registry.
+ https://bugs.webkit.org/show_bug.cgi?id=43871
+
+ Wrap !PLATFORM(CHROMIUM) around blobRegistry() so that chromium uses the
+ implementation in WebKit Chromium.
+
+ * platform/network/BlobRegistryImpl.cpp:
+
+2010-08-18 Martin Robinson <mrobinson@igalia.com>
+
+ Reviewed by Gustavo Noronha Silva.
+
+ [GTK] Bots are showing lots of GTK_IS_CONTAINER critical warnings
+ https://bugs.webkit.org/show_bug.cgi?id=40990
+
+ Instead of relying on the ScrollView's adjustment members to determine if a
+ Scrollbar should be native or just a shell of the parent's scrollbar (main frame
+ scrollbar), just check if this ScrollView has a parent. This will ensure the
+ correct behavior when main frame scrollbar's are created after the ScrollView's
+ containing adjustments go away.
+
+ Lack of warnings during tests are the test for this fix.
+
+ * platform/gtk/ScrollViewGtk.cpp:
+ (WebCore::ScrollView::createScrollbar): Decide what type of scrollbar to make based
+ on the result of the parent() method.
+ * platform/gtk/ScrollbarGtk.cpp:
+ (ScrollbarGtk::ScrollbarGtk): Allow for an m_adjustment which is null.
+ (ScrollbarGtk::attachAdjustment): Ditto.
+ (ScrollbarGtk::updateThumbPosition): Ditto.
+ (ScrollbarGtk::updateThumbProportion): Ditto.
+
+2010-08-18 Adam Barth <abarth@webkit.org>
+
+ Reviewed by David Levin.
+
+ NOT_REACHED is reachable in SVGLength
+ https://bugs.webkit.org/show_bug.cgi?id=44150
+
+ The author of this code was confused. This code is reachable. We just
+ haven't implemented it yet.
+
+ * svg/SVGLength.cpp:
+ (WebCore::SVGLength::setValue):
+
+2010-08-18 Balazs Kelemen <kb@inf.u-szeged.hu>
+
+ Reviewed by Antonio Gomes.
+
+ [Qt] Use LAZY_NATIVE_CURSOR
+ https://bugs.webkit.org/show_bug.cgi?id=44062
+
+ No functional change so new tests.
+
+ Change Cursor behaviour to match the LAZY_NATIVE_CURSOR policy.
+
+ * platform/Cursor.h: Typedef PlatformCursor to be a QCursor* to be able create it dynamically.
+ (WebCore::Cursor::Cursor): Remove the ifdef for Qt.
+ * platform/qt/CursorQt.cpp: Remove the Cursors class since we have the static cursor instances
+ for the common cursor types in Cursor.cpp. Move the logic that maps the cursor types to
+ QCursor instances into ensurePlatformCursor.
+ (WebCore::Cursor::Cursor):
+ (WebCore::Cursor::~Cursor):
+ (WebCore::Cursor::operator=):
+ (WebCore::createCustomCursor):
+ (WebCore::Cursor::ensurePlatformCursor):
+ * platform/qt/WidgetQt.cpp:
+ (WebCore::Widget::setCursor): Adjust to the PlatformCursor change.
+
+2010-08-18 Andreas Kling <andreas.kling@nokia.com>
+
+ Reviewed by Darin Adler.
+
+ CSS: Make rgb() and rgba() fast paths case-insensitive
+ https://bugs.webkit.org/show_bug.cgi?id=44107
+
+ Also inlined the string comparisons against "rgb(" and "rgba("
+ which is faster and avoids creating a temporary String object.
+
+ * css/CSSParser.cpp:
+ (WebCore::mightBeRGBA):
+ (WebCore::mightBeRGB):
+ (WebCore::CSSParser::parseColor):
+
+2010-08-18 Jian Li <jianli@chromium.org>
+
+ Reviewed by Darin Fisher.
+
+ Change BlobStorageData to reuse BlobData.
+ https://bugs.webkit.org/show_bug.cgi?id=44188
+
+ Also addressed Darin's feedbacks for bug 44116.
+
+ * html/ThreadableBlobRegistry.cpp:
+ (WebCore::registerBlobURLTask):
+ (WebCore::registerBlobURLFromTask):
+ (WebCore::unregisterBlobURLTask):
+ * platform/network/BlobData.cpp:
+ (WebCore::BlobData::appendData):
+ * platform/network/BlobData.h:
+ (WebCore::BlobDataItem::BlobDataItem):
+ * platform/network/BlobRegistry.h:
+ * platform/network/BlobRegistryImpl.cpp:
+ (WebCore::blobRegistry):
+ (WebCore::BlobRegistryImpl::appendStorageItems):
+ (WebCore::BlobRegistryImpl::registerBlobURL):
+ * platform/network/BlobRegistryImpl.h:
+ * platform/network/BlobStorageData.h:
+ (WebCore::BlobStorageData::create):
+ (WebCore::BlobStorageData::contentType):
+ (WebCore::BlobStorageData::contentDisposition):
+ (WebCore::BlobStorageData::items):
+ (WebCore::BlobStorageData::BlobStorageData):
+
+2010-08-18 David Hyatt <hyatt@apple.com>
+
+ Reviewed by Martin Robinson.
+
+ https://bugs.webkit.org/show_bug.cgi?id=44193
+
+ Fix a typo in my previous canvas checkin. m_in->resultImage() was originally m_in2->resultImage(),
+ and I accidentally changed it when swapping the order of the arguments.
+
+ * platform/graphics/filters/FEComposite.cpp:
+ (WebCore::FEComposite::apply):
+
+2010-08-18 Stephen White <senorblanco@chromium.org>
+
+ Reviewed by Darin Fisher.
+
+ [CHROMIUM] Eliminate a memcpy() from the canvas.drawImage(canvas, ...) path.
+ https://bugs.webkit.org/show_bug.cgi?id=44115
+
+ This is the Skia followup to Dave Hyatt's patch in r65449.
+ Covered by canvas layout tests.
+
+ * platform/graphics/skia/BitmapImageSingleFrameSkia.h:
+ Add a "copyPixels" argument to the create() static to indicate if
+ the caller wants the pixels to be copied or ref'ed.
+ * platform/graphics/skia/ImageBufferSkia.cpp:
+ (WebCore::ImageBuffer::drawsUsingCopy):
+ We don't use the always-copy path anymore, so return false.
+ (WebCore::ImageBuffer::copyImage):
+ Force a copy here.
+ (WebCore::ImageBuffer::draw):
+ (WebCore::ImageBuffer::drawPattern):
+ Create a temporary BitampImageSingleFrameSkia wrapped around the
+ canvas's bitmap, and draw with it immediately. If drawing to our own
+ canvas, copy the pixels, otherwise just shallow copy.
+ * platform/graphics/skia/ImageSkia.cpp:
+ (WebCore::BitmapImageSingleFrameSkia::BitmapImageSingleFrameSkia):
+ Make the constructor take an SkBitmap to be wrapped.
+ (WebCore::BitmapImageSingleFrameSkia::create):
+ Implement the "copyPixels" flag: if true, do a deep copy, otherwise
+ do a shallow copy.
+ * platform/graphics/skia/NativeImageSkia.cpp:
+ (WebCore::NativeImageSkia::NativeImageSkia):
+ * platform/graphics/skia/NativeImageSkia.h:
+ Implement a new constructor that shallow-copies the given SkBitmap.
+
+2010-08-18 Mahesh Kulkarni <mahesh.kulkarni@nokia.com>
+
+ Reviewed by Steve Block.
+
+ [Qt] Request for permission before starting Geolocation service
+ https://bugs.webkit.org/show_bug.cgi?id=42027
+
+ Handles starting location acquisition when request is granted for ports using
+ "!CLIENT_BASED_GEOLOCATION and PREEMPT_GEOLOCATION_PERMISSION" policy
+ Only Qt port as of today uses the above combination. Enable
+ PREEMPT_GEOLOCATION_PERMISSION for qt port.
+
+ Below tests cover these changes on platform using PREEMPT_GEOLOCATION_PERMISSION
+ - fast/dom/Geolocation/delayed-permission-allowed.html
+ - fast/dom/Geolocation/delayed-permission-denied.html
+ - fast/dom/Geolocation/delayed-permission-allowed-for-multiple-requests.html
+ - fast/dom/Geolocation/delayed-permission-denied-for-multiple-requests.html
+
+ * WebCore.pro:
+ * page/Geolocation.cpp:
+ (WebCore::Geolocation::handlePendingPermissionNotifiers):
+
2010-08-18 Andreas Kling <andreas.kling@nokia.com>
Reviewed by Darin Adler.
@@ -18746,11 +24068,11 @@
Set bmiHeader.biSize only at constructor.
- * platform/win/BitmapInfo.cpp: Added property svn:eol-style.
+ * platform/win/BitmapInfo.cpp:
(WebCore::bitmapInfoForSize):
(WebCore::BitmapInfo::create):
(WebCore::BitmapInfo::createBottomUp):
- * platform/win/BitmapInfo.h: Added property svn:eol-style.
+ * platform/win/BitmapInfo.h:
(WebCore::BitmapInfo::is16bit):
(WebCore::BitmapInfo::is32bit):
(WebCore::BitmapInfo::width):
diff --git a/WebCore/DerivedSources.cpp b/WebCore/DerivedSources.cpp
index 351db54..bbab64b 100644
--- a/WebCore/DerivedSources.cpp
+++ b/WebCore/DerivedSources.cpp
@@ -110,6 +110,7 @@
#include "JSFileList.cpp"
#include "JSFileReader.cpp"
#include "JSFileSystemCallback.cpp"
+#include "JSFileWriter.cpp"
#include "JSFlags.cpp"
#include "JSGeolocation.cpp"
#include "JSGeoposition.cpp"
diff --git a/WebCore/DerivedSources.make b/WebCore/DerivedSources.make
index 886c1f3..b9f6589 100644
--- a/WebCore/DerivedSources.make
+++ b/WebCore/DerivedSources.make
@@ -154,6 +154,7 @@ DOM_CLASSES = \
FileError \
FileList \
FileReader \
+ FileWriter \
FileSystemCallback \
Flags \
Geolocation \
@@ -487,11 +488,9 @@ DOM_CLASSES = \
XSLTProcessor \
#
-INSPECTOR_CLASSES = Inspector
-
.PHONY : all
-JS_DOM_HEADERS=$(filter-out JSEventListener.h JSEventTarget.h,$(DOM_CLASSES:%=JS%.h) $(INSPECTOR_CLASSES:%=Remote%Frontend.h))
+JS_DOM_HEADERS=$(filter-out JSEventListener.h JSEventTarget.h,$(DOM_CLASSES:%=JS%.h))
WEB_DOM_HEADERS :=
ifeq ($(findstring BUILDING_WX,$(FEATURE_DEFINES)), BUILDING_WX)
@@ -820,10 +819,12 @@ JS%.h : %.idl $(JS_BINDINGS_SCRIPTS)
# Inspector interfaces generator
+all : InspectorFrontend.h
+
INSPECTOR_GENERATOR_SCRIPTS = $(GENERATE_SCRIPTS) inspector/CodeGeneratorInspector.pm
-Remote%Frontend.h : %.idl $(INSPECTOR_GENERATOR_SCRIPTS)
- $(call generator_script, $(INSPECTOR_GENERATOR_SCRIPTS)) --outputDir . --defines "$(FEATURE_DEFINES) LANGUAGE_JAVASCRIPT" --generator Inspector $<
+InspectorFrontend.h : Inspector.idl $(INSPECTOR_GENERATOR_SCRIPTS)
+ $(call generator_script, $(INSPECTOR_GENERATOR_SCRIPTS)) --outputDir . --defines "$(FEATURE_DEFINES) LANGUAGE_JAVASCRIPT" --generator Inspector $<
-include $(JS_DOM_HEADERS:.h=.dep)
diff --git a/WebCore/English.lproj/localizedStrings.js b/WebCore/English.lproj/localizedStrings.js
index 010c28c..38d2557 100644
--- a/WebCore/English.lproj/localizedStrings.js
+++ b/WebCore/English.lproj/localizedStrings.js
Binary files differ
diff --git a/WebCore/ForwardingHeaders/wtf/DecimalNumber.h b/WebCore/ForwardingHeaders/wtf/DecimalNumber.h
new file mode 100644
index 0000000..333174d
--- /dev/null
+++ b/WebCore/ForwardingHeaders/wtf/DecimalNumber.h
@@ -0,0 +1,4 @@
+#ifndef WebCore_FWD_DecimalNumber_h
+#define WebCore_FWD_DecimalNumber_h
+#include <JavaScriptCore/DecimalNumber.h>
+#endif
diff --git a/WebCore/GNUmakefile.am b/WebCore/GNUmakefile.am
index c191573..dac604b 100644
--- a/WebCore/GNUmakefile.am
+++ b/WebCore/GNUmakefile.am
@@ -1,4 +1,3 @@
-FEATURE_DEFINES :=
SVG_FEATURES :=
HTML_FEATURES :=
@@ -98,6 +97,8 @@ webcore_built_sources += \
DerivedSources/WebCore/HTMLNames.h \
DerivedSources/WebCore/InspectorBackendDispatcher.cpp \
DerivedSources/WebCore/InspectorBackendDispatcher.h \
+ DerivedSources/WebCore/InspectorFrontend.cpp \
+ DerivedSources/WebCore/InspectorFrontend.h \
DerivedSources/WebCore/JSAbstractWorker.cpp \
DerivedSources/WebCore/JSAbstractWorker.h \
DerivedSources/WebCore/JSArrayBuffer.cpp \
@@ -238,6 +239,8 @@ webcore_built_sources += \
DerivedSources/WebCore/JSFileList.h \
DerivedSources/WebCore/JSFileReader.cpp \
DerivedSources/WebCore/JSFileReader.h \
+ DerivedSources/WebCore/JSFileWriter.cpp \
+ DerivedSources/WebCore/JSFileWriter.h \
DerivedSources/WebCore/JSFloat32Array.cpp \
DerivedSources/WebCore/JSFloat32Array.h \
DerivedSources/WebCore/JSGeolocation.cpp \
@@ -549,8 +552,6 @@ webcore_built_sources += \
DerivedSources/WebCore/JSXMLSerializer.h \
DerivedSources/WebCore/JSXSLTProcessor.cpp \
DerivedSources/WebCore/JSXSLTProcessor.h \
- DerivedSources/WebCore/RemoteInspectorFrontend.cpp \
- DerivedSources/WebCore/RemoteInspectorFrontend.h \
DerivedSources/WebCore/UserAgentStyleSheetsData.cpp \
DerivedSources/WebCore/UserAgentStyleSheets.h \
DerivedSources/WebCore/XMLNames.cpp \
@@ -1040,11 +1041,13 @@ webcore_sources += \
WebCore/dom/DeviceOrientationEvent.cpp \
WebCore/dom/DeviceOrientationEvent.h \
WebCore/dom/Document.cpp \
- WebCore/dom/DocumentParser.cpp \
WebCore/dom/Document.h \
WebCore/dom/DocumentFragment.cpp \
WebCore/dom/DocumentFragment.h \
WebCore/dom/DocumentMarker.h \
+ WebCore/dom/DocumentMarkerController.cpp \
+ WebCore/dom/DocumentMarkerController.h \
+ WebCore/dom/DocumentParser.cpp \
WebCore/dom/DocumentType.cpp \
WebCore/dom/DocumentType.h \
WebCore/dom/DynamicNodeList.cpp \
@@ -1353,9 +1356,8 @@ webcore_sources += \
WebCore/html/FileList.h \
WebCore/html/FileReader.cpp \
WebCore/html/FileReader.h \
- WebCore/html/FileStream.cpp \
- WebCore/html/FileStream.h \
- WebCore/html/FileStreamClient.h \
+ WebCore/html/FileWriter.cpp \
+ WebCore/html/FileWriter.h \
WebCore/html/FileStreamProxy.cpp \
WebCore/html/FileStreamProxy.h \
WebCore/html/FileThread.cpp \
@@ -1506,8 +1508,6 @@ webcore_sources += \
WebCore/html/HTMLParagraphElement.h \
WebCore/html/HTMLParamElement.cpp \
WebCore/html/HTMLParamElement.h \
- WebCore/html/LegacyHTMLTreeBuilder.cpp \
- WebCore/html/LegacyHTMLTreeBuilder.h \
WebCore/html/HTMLParserErrorCodes.cpp \
WebCore/html/HTMLParserErrorCodes.h \
WebCore/html/HTMLParserQuirks.h \
@@ -1625,6 +1625,8 @@ webcore_sources += \
WebCore/inspector/InspectorFrontendClientLocal.h \
WebCore/inspector/InspectorFrontendHost.cpp \
WebCore/inspector/InspectorFrontendHost.h \
+ WebCore/inspector/InspectorProfilerAgent.cpp \
+ WebCore/inspector/InspectorProfilerAgent.h \
WebCore/inspector/InspectorResource.cpp \
WebCore/inspector/InspectorResource.h \
WebCore/inspector/InspectorStorageAgent.cpp \
@@ -1659,7 +1661,6 @@ webcore_sources += \
WebCore/loader/CachedResourceHandle.h \
WebCore/loader/CachedScript.cpp \
WebCore/loader/CachedScript.h \
- WebCore/loader/CachedXBLDocument.h \
WebCore/loader/CachedXSLStyleSheet.cpp \
WebCore/loader/CachedXSLStyleSheet.h \
WebCore/loader/CrossOriginAccessControl.cpp \
@@ -1705,6 +1706,8 @@ webcore_sources += \
WebCore/loader/NavigationAction.h \
WebCore/loader/NetscapePlugInStreamLoader.cpp \
WebCore/loader/NetscapePlugInStreamLoader.h \
+ WebCore/loader/PingLoader.cpp \
+ WebCore/loader/PingLoader.h \
WebCore/loader/PlaceholderDocument.cpp \
WebCore/loader/PlaceholderDocument.h \
WebCore/loader/PluginDocument.cpp \
@@ -1877,6 +1880,7 @@ webcore_sources += \
WebCore/page/animation/KeyframeAnimation.h \
WebCore/platform/Arena.cpp \
WebCore/platform/Arena.h \
+ WebCore/platform/AsyncFileStream.h \
WebCore/platform/AutodrainedPool.h \
WebCore/platform/BlobItem.cpp \
WebCore/platform/BlobItem.h \
@@ -1901,6 +1905,9 @@ webcore_sources += \
WebCore/platform/EventLoop.h \
WebCore/platform/FileChooser.cpp \
WebCore/platform/FileChooser.h \
+ WebCore/platform/FileStream.cpp \
+ WebCore/platform/FileStream.h \
+ WebCore/platform/FileStreamClient.h \
WebCore/platform/FileSystem.cpp \
WebCore/platform/FileSystem.h \
WebCore/platform/FloatConversion.h \
@@ -2094,6 +2101,8 @@ webcore_sources += \
WebCore/platform/network/BlobRegistry.h \
WebCore/platform/network/BlobRegistryImpl.cpp \
WebCore/platform/network/BlobRegistryImpl.h \
+ WebCore/platform/network/BlobResourceHandle.cpp \
+ WebCore/platform/network/BlobResourceHandle.h \
WebCore/platform/network/BlobStorageData.h \
WebCore/platform/network/Credential.cpp \
WebCore/platform/network/Credential.h \
@@ -2362,8 +2371,6 @@ webcore_sources += \
WebCore/rendering/TransformState.h \
WebCore/rendering/break_lines.cpp \
WebCore/rendering/break_lines.h \
- WebCore/rendering/style/BindingURI.cpp \
- WebCore/rendering/style/BindingURI.h \
WebCore/rendering/style/BorderData.h \
WebCore/rendering/style/BorderValue.h \
WebCore/rendering/style/CollapsedBorderValue.h \
@@ -2446,8 +2453,6 @@ webcoregtk_sources += \
WebCore/platform/graphics/cairo/FontPlatformData.h \
WebCore/platform/graphics/cairo/GOwnPtrCairo.cpp \
WebCore/platform/graphics/cairo/GOwnPtrCairo.h \
- WebCore/platform/graphics/cairo/GRefPtrCairo.cpp \
- WebCore/platform/graphics/cairo/GRefPtrCairo.h \
WebCore/platform/graphics/cairo/GradientCairo.cpp \
WebCore/platform/graphics/cairo/GraphicsContextCairo.cpp \
WebCore/platform/graphics/cairo/GraphicsContextPlatformPrivateCairo.h \
@@ -2456,6 +2461,8 @@ webcoregtk_sources += \
WebCore/platform/graphics/cairo/ImageCairo.cpp \
WebCore/platform/graphics/cairo/PathCairo.cpp \
WebCore/platform/graphics/cairo/PatternCairo.cpp \
+ WebCore/platform/graphics/cairo/PlatformRefPtrCairo.cpp \
+ WebCore/platform/graphics/cairo/PlatformRefPtrCairo.h \
WebCore/platform/graphics/cairo/TransformationMatrixCairo.cpp \
WebCore/platform/graphics/gtk/ColorGtk.cpp \
WebCore/platform/graphics/gtk/CairoUtilities.cpp \
@@ -2567,15 +2574,6 @@ webcore_sources += \
endif
# ----
-# GTK+ 2.x/3.x support
-# ----
-
-if GTK_API_VERSION_2
-webcore_cppflags += \
- -DGTK_API_VERSION_2=1
-endif
-
-# ----
# icu unicode backend
# ----
if USE_ICU_UNICODE
@@ -2992,12 +2990,12 @@ webcore_sources += \
endif # END ENABLE_DOM_STORAGE
# ----
-# HTML5 FileSystem API support
+# FileSystem API support
# ----
if ENABLE_FILE_SYSTEM
+
FEATURE_DEFINES += ENABLE_FILE_SYSTEM=1
webcore_cppflags += -DENABLE_FILE_SYSTEM=1
-endif # END ENABLE_FILE_SYSTEM
webcore_built_sources += \
DerivedSources/WebCore/JSDirectoryEntry.cpp \
@@ -3032,6 +3030,8 @@ webcore_sources += \
WebCore/storage/DirectoryEntry.h \
WebCore/storage/DirectoryReader.cpp \
WebCore/storage/DirectoryReader.h \
+ WebCore/storage/DOMFilePath.cpp \
+ WebCore/storage/DOMFilePath.h \
WebCore/storage/DOMFileSystem.cpp \
WebCore/storage/DOMFileSystem.h \
WebCore/storage/EntriesCallback.h \
@@ -3044,10 +3044,14 @@ webcore_sources += \
WebCore/storage/FileEntry.cpp \
WebCore/storage/FileEntry.h \
WebCore/storage/FileSystemCallback.h \
+ WebCore/storage/FileSystemCallbacks.cpp \
+ WebCore/storage/FileSystemCallbacks.h \
WebCore/storage/Flags.h \
WebCore/storage/Metadata.h \
WebCore/storage/MetadataCallback.h
+endif # END ENABLE_FILE_SYSTEM
+
# ----
# Speech Input API support
# ----
@@ -3166,6 +3170,8 @@ webcoregtk_sources += \
WebCore/platform/graphics/gstreamer/GStreamerGWorld.h \
WebCore/platform/graphics/gstreamer/ImageGStreamer.h \
WebCore/platform/graphics/gstreamer/ImageGStreamerCairo.cpp \
+ WebCore/platform/graphics/gstreamer/PlatformVideoWindow.h \
+ WebCore/platform/graphics/gstreamer/PlatformVideoWindowGtk.cpp \
WebCore/platform/graphics/gstreamer/WebKitWebSourceGStreamer.cpp \
WebCore/platform/graphics/gstreamer/WebKitWebSourceGStreamer.h
@@ -4522,8 +4528,8 @@ DerivedSources/WebCore/XMLNSNames.cpp DerivedSources/WebCore/XMLNSNames.h: $(Web
DerivedSources/WebCore/XMLNames.cpp DerivedSources/WebCore/XMLNames.h: $(WebCore)/dom/make_names.pl $(WebCore)/xml/xmlattrs.in
$(AM_V_GEN)$(PERL) -I$(WebCore)/bindings/scripts $< --attrs $(WebCore)/xml/xmlattrs.in --outputDir "$(GENSOURCES_WEBCORE)"
-# RemoteInspectorFrontend and InspectorBackendDispatcher
-DerivedSources/WebCore/RemoteInspectorFrontend.cpp DerivedSources/WebCore/RemoteInspectorFrontend.h DerivedSources/WebCore/InspectorBackendDispatcher.cpp DerivedSources/WebCore/InspectorBackendDispatcher.h: $(WebCore)/inspector/Inspector.idl $(SCRIPTS_BINDINGS) $(WebCore)/inspector/CodeGeneratorInspector.pm
+# All Web Inspector generated files are created with this one call to CodeGeneratorInspector.pm
+DerivedSources/WebCore/InspectorFrontend.cpp DerivedSources/WebCore/InspectorFrontend.h DerivedSources/WebCore/InspectorBackendDispatcher.cpp DerivedSources/WebCore/InspectorBackendDispatcher.h DerivedSources/WebCore/InspectorBackendStub.js: $(WebCore)/inspector/Inspector.idl $(SCRIPTS_BINDINGS) $(WebCore)/inspector/CodeGeneratorInspector.pm
$(AM_V_GEN)$(PERL) -I$(WebCore)/bindings/scripts -I$(WebCore)/inspector $(WebCore)/bindings/scripts/generate-bindings.pl $(IDL_PATH:%=--include "%") --outputDir "$(GENSOURCES_WEBCORE)" --defines "LANGUAGE_JAVASCRIPT=1 $(FEATURE_DEFINES)" --generator Inspector $<
IDL_PATH := \
@@ -4630,12 +4636,18 @@ dist_webinspectorimages_DATA = \
$(shell ls $(WebCore)/inspector/front-end/Images/*.gif) \
$(shell ls $(WebCore)/inspector/front-end/Images/*.png)
-noinst_webinspectordir = ${GENSOURCES_INSPECTOR}
-noinst_webinspector_SCRIPTS = ${GENSOURCES_INSPECTOR}/inspector.html
-${GENSOURCES_INSPECTOR}/inspector.html :
- mkdir -p ${GENSOURCES_INSPECTOR}/images
- cp ${dist_webinspector_DATA} ${GENSOURCES_INSPECTOR}
- cp ${dist_webinspectorimages_DATA} ${GENSOURCES_INSPECTOR}/images
+# It seems that $(shell) does not expand when it is a rule dependency, so
+# we must redefine this list of copied files with traditional dependency wildcards.
+noinst_DATA = ${GENSOURCES_INSPECTOR}/inspector.html
+${GENSOURCES_INSPECTOR}/inspector.html: $(WebCore)/inspector/front-end/*.html \
+ $(WebCore)/inspector/front-end/*.js \
+ $(WebCore)/inspector/front-end/*.css \
+ $(WebCore)/inspector/front-end/Images/* \
+ DerivedSources/WebCore/InspectorBackendStub.js \
+ $(WebCore)/English.lproj/localizedStrings.js
+ $(AM_V_GEN)mkdir -p ${GENSOURCES_INSPECTOR}/images
+ $(AM_V_at)cp ${dist_webinspector_DATA} ${GENSOURCES_INSPECTOR}
+ $(AM_V_at)cp ${dist_webinspectorimages_DATA} ${GENSOURCES_INSPECTOR}/images
webresourcesdir = ${datadir}/webkitgtk-@WEBKITGTK_API_VERSION@/images
dist_webresources_DATA = \
diff --git a/WebCore/WebCore.exp.in b/WebCore/WebCore.exp.in
index 1369296..e1b7c22 100644
--- a/WebCore/WebCore.exp.in
+++ b/WebCore/WebCore.exp.in
@@ -361,6 +361,7 @@ __ZN7WebCore15VisiblePositionC1ERKNS_8PositionENS_9EAffinityE
__ZN7WebCore15reportExceptionEPN3JSC9ExecStateENS0_7JSValueE
__ZN7WebCore15visitedLinkHashEPKtj
__ZN7WebCore16AbstractDatabase14setIsAvailableEb
+__ZN7WebCore16DeviceMotionData6createEbdbdbdbdbdbdbd
__ZN7WebCore16FontFallbackList15releaseFontDataEv
__ZN7WebCore16FontPlatformDataC1EP6NSFontbb
__ZN7WebCore16FontPlatformDataD1Ev
@@ -401,10 +402,8 @@ __ZN7WebCore16isEndOfParagraphERKNS_15VisiblePositionE
__ZN7WebCore16jsStringSlowCaseEPN3JSC9ExecStateERNS0_9WeakGCMapIPN3WTF10StringImplEPNS0_8JSStringEEES6_
__ZN7WebCore17CredentialStorage3getERKNS_15ProtectionSpaceE
__ZN7WebCore17DOMImplementation14isTextMIMETypeERKN3WTF6StringE
-__ZN7WebCore16DeviceMotionData6createEbdbdbdbdbdbdbd
__ZN7WebCore17DeviceOrientation6createEbdbdbd
__ZN7WebCore17GlyphPageTreeNode18treeGlyphPageCountEv
-__ZN7WebCore17HTMLPlugInElement11getNPObjectEv
__ZN7WebCore17HistoryController26saveDocumentAndScrollStateEv
__ZN7WebCore17nameForCursorTypeENS_6Cursor4TypeE
__ZN7WebCore17openTemporaryFileEPKcRi
@@ -462,6 +461,8 @@ __ZN7WebCore22externalRepresentationEPNS_5FrameEj
__ZN7WebCore23ReplaceSelectionCommandC1EPNS_8DocumentEN3WTF10PassRefPtrINS_16DocumentFragmentEEEbbbbbNS_10EditActionE
__ZN7WebCore23createFragmentFromNodesEPNS_8DocumentERKN3WTF6VectorIPNS_4NodeELm0EEE
__ZN7WebCore24BinaryPropertyListWriter17writePropertyListEv
+__ZN7WebCore24DocumentMarkerController13removeMarkersENS_14DocumentMarker10MarkerTypeE
+__ZN7WebCore24DocumentMarkerController23renderedRectsForMarkersENS_14DocumentMarker10MarkerTypeE
__ZN7WebCore24contextMenuItemTagItalicEv
__ZN7WebCore24contextMenuItemTagStylesEv
__ZN7WebCore24createFragmentFromMarkupEPNS_8DocumentERKN3WTF6StringES5_NS_27FragmentScriptingPermissionE
@@ -589,6 +590,7 @@ __ZN7WebCore5Frame28searchForLabelsBeforeElementEP7NSArrayPNS_7ElementEPmPb
__ZN7WebCore5Frame34setMarkedTextMatchesAreHighlightedEb
__ZN7WebCore5Frame6createEPNS_4PageEPNS_21HTMLFrameOwnerElementEPNS_17FrameLoaderClientE
__ZN7WebCore5Frame7setViewEN3WTF10PassRefPtrINS_9FrameViewEEE
+__ZN7WebCore5Frame9nodeImageEPNS_4NodeE
__ZN7WebCore5FrameD1Ev
__ZN7WebCore5Image12supportsTypeERKN3WTF6StringE
__ZN7WebCore5Image20loadPlatformResourceEPKc
@@ -626,6 +628,7 @@ __ZN7WebCore6Editor29canDecreaseSelectionListLevelEv
__ZN7WebCore6Editor29canIncreaseSelectionListLevelEv
__ZN7WebCore6Editor30applyParagraphStyleToSelectionEPNS_19CSSStyleDeclarationENS_10EditActionE
__ZN7WebCore6Editor30deleteSelectionWithSmartDeleteEb
+__ZN7WebCore6Editor30pasteAsPlainTextBypassingDHTMLEv
__ZN7WebCore6Editor32guessesForUngrammaticalSelectionEv
__ZN7WebCore6Editor33increaseSelectionListLevelOrderedEv
__ZN7WebCore6Editor35increaseSelectionListLevelUnorderedEv
@@ -661,7 +664,6 @@ __ZN7WebCore7IntSizeC1ERK7_NSSize
__ZN7WebCore7cookiesEPKNS_8DocumentERKNS_4KURLE
__ZN7WebCore7nsColorERKNS_5ColorE
__ZN7WebCore8Document11createRangeEv
-__ZN7WebCore8Document13removeMarkersENS_14DocumentMarker10MarkerTypeE
__ZN7WebCore8Document13svgExtensionsEv
__ZN7WebCore8Document14setFocusedNodeEN3WTF10PassRefPtrINS_4NodeEEE
__ZN7WebCore8Document16isPageBoxVisibleEi
@@ -669,7 +671,6 @@ __ZN7WebCore8Document17getFocusableNodesERN3WTF6VectorINS1_6RefPtrINS_4NodeEEELm
__ZN7WebCore8Document18createWrapperCacheEPNS_15DOMWrapperWorldE
__ZN7WebCore8Document19accessSVGExtensionsEv
__ZN7WebCore8Document22createDocumentFragmentEv
-__ZN7WebCore8Document23renderedRectsForMarkersENS_14DocumentMarker10MarkerTypeE
__ZN7WebCore8Document24addMediaCanStartListenerEPNS_21MediaCanStartListenerE
__ZN7WebCore8Document24setShouldCreateRenderersEb
__ZN7WebCore8Document26pageSizeAndMarginsInPixelsEiRNS_7IntSizeERiS3_S3_S3_
@@ -996,7 +997,6 @@ __ZNK7WebCore5Frame31fontAttributesForSelectionStartEv
__ZNK7WebCore5Frame37baseWritingDirectionForSelectionStartEv
__ZNK7WebCore5Frame8settingsEv
__ZNK7WebCore5Frame9domWindowEv
-__ZNK7WebCore5Frame9nodeImageEPNS_4NodeE
__ZNK7WebCore5Range11startOffsetERi
__ZNK7WebCore5Range12endContainerERi
__ZNK7WebCore5Range12pastLastNodeEv
@@ -1058,6 +1058,7 @@ __ZNK7WebCore9FrameTree6parentEb
__ZNK7WebCore9FrameView11needsLayoutEv
__ZNK7WebCore9FrameView13paintBehaviorEv
__ZNK7WebCore9FrameView20isSoftwareRenderableEv
+__ZNK7WebCore9FrameView22windowClipRectForLayerEPKNS_11RenderLayerEb
__ZNK7WebCore9FrameView28isEnclosedInCompositingLayerEv
__ZNK7WebCore9PageCache10frameCountEv
__ZNK7WebCore9PageCache21autoreleasedPageCountEv
@@ -1189,10 +1190,12 @@ __ZN7WebCore19InspectorController20stopTimelineProfilerEv
__ZN7WebCore19InspectorController21startTimelineProfilerEv
__ZN7WebCore19InspectorController25evaluateForTestInFrontendElRKN3WTF6StringE
__ZN7WebCore19InspectorController26setInspectorFrontendClientEN3WTF10PassOwnPtrINS_23InspectorFrontendClientEEE
+__ZN7WebCore19InspectorController27startUserInitiatedProfilingEv
__ZN7WebCore19InspectorController26stopUserInitiatedProfilingEv
-__ZN7WebCore19InspectorController27startUserInitiatedProfilingEPNS_5TimerIS0_EE
__ZN7WebCore19InspectorController34inspectorStartsAttachedSettingNameEv
__ZN7WebCore19InspectorController34inspectorStartsAttachedSettingNameEv
+__ZNK7WebCore19InspectorController31isRecordingUserInitiatedProfileEv
+__ZNK7WebCore19InspectorController15profilerEnabledEv
__ZN7WebCore19InspectorController4showEv
__ZN7WebCore19InspectorController5closeEv
__ZN7WebCore19InspectorController7inspectEPNS_4NodeE
@@ -1250,11 +1253,11 @@ __NPN_SetProperty
__NPN_UTF8FromIdentifier
__ZN7WebCore16ScriptController20windowScriptNPObjectEv
__ZN7WebCore16ScriptController29cleanupScriptObjectsForPluginEPv
+__ZN7WebCore17HTMLPlugInElement11getNPObjectEv
__ZNK7WebCore12RenderObject4viewEv
__ZNK7WebCore14SecurityOrigin9canAccessEPKS0_
__ZNK7WebCore4KURL7hasPathEv
__ZNK7WebCore4KURL9prettyURLEv
-__ZNK7WebCore9FrameView22windowClipRectForLayerEPKNS_11RenderLayerEb
#endif
#if ENABLE(ORIENTATION_EVENTS)
@@ -1284,6 +1287,7 @@ __ZN3JSC8Bindings8InstanceD2Ev
__ZN7WebCore13IdentifierRep7isValidEPS0_
__ZN7WebCore16ScriptController16createRootObjectEPv
__ZNK3JSC8Bindings13RuntimeObject12defaultValueEPNS_9ExecStateENS_22PreferredPrimitiveTypeE
+__ZNK7WebCore10ScrollView16contentsToWindowERKNS_8IntPointE
__ZTVN3JSC13RuntimeMethodE
#endif
diff --git a/WebCore/WebCore.gyp/WebCore.gyp b/WebCore/WebCore.gyp/WebCore.gyp
index fed9c0d..c625f5f 100644
--- a/WebCore/WebCore.gyp/WebCore.gyp
+++ b/WebCore/WebCore.gyp/WebCore.gyp
@@ -287,8 +287,8 @@
'<(SHARED_INTERMEDIATE_DIR)/webcore/InspectorBackendDispatcher.cpp',
'<(SHARED_INTERMEDIATE_DIR)/webcore/InspectorBackendStub.js',
'<(SHARED_INTERMEDIATE_DIR)/webkit/InspectorBackendDispatcher.h',
- '<(SHARED_INTERMEDIATE_DIR)/webcore/RemoteInspectorFrontend.cpp',
- '<(SHARED_INTERMEDIATE_DIR)/webkit/RemoteInspectorFrontend.h',
+ '<(SHARED_INTERMEDIATE_DIR)/webcore/InspectorFrontend.cpp',
+ '<(SHARED_INTERMEDIATE_DIR)/webkit/InspectorFrontend.h',
],
'variables': {
'generator_include_dirs': [
@@ -757,7 +757,7 @@
'<(SHARED_INTERMEDIATE_DIR)/webkit/XPathGrammar.cpp',
# Additional .cpp files from the webcore_inspector_sources list.
- '<(SHARED_INTERMEDIATE_DIR)/webcore/RemoteInspectorFrontend.cpp',
+ '<(SHARED_INTERMEDIATE_DIR)/webcore/InspectorFrontend.cpp',
'<(SHARED_INTERMEDIATE_DIR)/webcore/InspectorBackendDispatcher.cpp',
],
'conditions': [
@@ -885,6 +885,9 @@
# Don't build IDBFactoryBackendInterface. We have our own implementation.
'../storage/IDBFactoryBackendInterface.cpp',
+ # Don't build IDBKeyPathBackendImpl. We have our own implementation.
+ '../storage/IDBKeyPathBackendImpl.cpp',
+
# Use history/BackForwardListChromium.cpp instead.
'../history/BackForwardListImpl.cpp',
diff --git a/WebCore/WebCore.gypi b/WebCore/WebCore.gypi
index d906385..0f15977 100644
--- a/WebCore/WebCore.gypi
+++ b/WebCore/WebCore.gypi
@@ -118,6 +118,7 @@
'html/FileError.idl',
'html/FileList.idl',
'html/FileReader.idl',
+ 'html/FileWriter.idl',
'html/HTMLAllCollection.idl',
'html/HTMLAnchorElement.idl',
'html/HTMLAppletElement.idl',
@@ -1150,6 +1151,8 @@
'dom/DocumentFragment.cpp',
'dom/DocumentFragment.h',
'dom/DocumentMarker.h',
+ 'dom/DocumentMarkerController.cpp',
+ 'dom/DocumentMarkerController.h',
'dom/DocumentParser.cpp',
'dom/DocumentParser.h',
'dom/DocumentType.cpp',
@@ -1518,9 +1521,8 @@
'html/FileList.h',
'html/FileReader.cpp',
'html/FileReader.h',
- 'html/FileStream.cpp',
- 'html/FileStream.h',
- 'html/FileStreamClient.h',
+ 'html/FileWriter.cpp',
+ 'html/FileWriter.h',
'html/FileStreamProxy.cpp',
'html/FileStreamProxy.h',
'html/FileThread.cpp',
@@ -1673,8 +1675,6 @@
'html/HTMLParagraphElement.h',
'html/HTMLParamElement.cpp',
'html/HTMLParamElement.h',
- 'html/LegacyHTMLTreeBuilder.cpp',
- 'html/LegacyHTMLTreeBuilder.h',
'html/HTMLParserErrorCodes.cpp',
'html/HTMLParserErrorCodes.h',
'html/HTMLParserScheduler.cpp',
@@ -1768,6 +1768,8 @@
'inspector/InspectorFrontendClient.h',
'inspector/InspectorFrontendHost.cpp',
'inspector/InspectorFrontendHost.h',
+ 'inspector/InspectorProfilerAgent.cpp',
+ 'inspector/InspectorProfilerAgent.h',
'inspector/InspectorResource.cpp',
'inspector/InspectorResource.h',
'inspector/InspectorStorageAgent.cpp',
@@ -1844,8 +1846,6 @@
'loader/CachedResourceHandle.h',
'loader/CachedScript.cpp',
'loader/CachedScript.h',
- 'loader/CachedXBLDocument.cpp',
- 'loader/CachedXBLDocument.h',
'loader/CachedXSLStyleSheet.cpp',
'loader/CachedXSLStyleSheet.h',
'loader/CrossOriginAccessControl.cpp',
@@ -1891,6 +1891,8 @@
'loader/NavigationAction.h',
'loader/NetscapePlugInStreamLoader.cpp',
'loader/NetscapePlugInStreamLoader.h',
+ 'loader/PingLoader.cpp',
+ 'loader/PingLoader.h',
'loader/PlaceholderDocument.cpp',
'loader/PlaceholderDocument.h',
'loader/PluginDocument.cpp',
@@ -2230,6 +2232,8 @@
'platform/graphics/cg/TransformationMatrixCG.cpp',
'platform/graphics/chromium/CanvasLayerChromium.cpp',
'platform/graphics/chromium/CanvasLayerChromium.h',
+ 'platform/graphics/chromium/ContentLayerChromium.cpp',
+ 'platform/graphics/chromium/ContentLayerChromium.h',
'platform/graphics/chromium/FontCacheChromiumWin.cpp',
'platform/graphics/chromium/FontCacheLinux.cpp',
'platform/graphics/chromium/FontChromiumWin.cpp',
@@ -2269,8 +2273,6 @@
'platform/graphics/chromium/SimpleFontDataLinux.cpp',
'platform/graphics/chromium/TilingData.h',
'platform/graphics/chromium/TilingData.cpp',
- 'platform/graphics/chromium/TransformLayerChromium.cpp',
- 'platform/graphics/chromium/TransformLayerChromium.h',
'platform/graphics/chromium/TransparencyWin.cpp',
'platform/graphics/chromium/TransparencyWin.h',
'platform/graphics/chromium/UniscribeHelper.cpp',
@@ -2788,8 +2790,6 @@
'platform/network/BlobData.cpp',
'platform/network/BlobData.h',
'platform/network/BlobRegistry.h',
- 'platform/network/BlobRegistryImpl.cpp',
- 'platform/network/BlobRegistryImpl.h',
'platform/network/BlobStorageData.h',
'platform/network/Credential.cpp',
'platform/network/Credential.h',
@@ -3037,6 +3037,7 @@
'platform/wx/WidgetWx.cpp',
'platform/Arena.cpp',
'platform/Arena.h',
+ 'platform/AsyncFileStream.h',
'platform/AutodrainedPool.h',
'platform/BlobItem.cpp',
'platform/BlobItem.h',
@@ -3060,6 +3061,9 @@
'platform/EventLoop.h',
'platform/FileChooser.cpp',
'platform/FileChooser.h',
+ 'platform/FileStream.cpp',
+ 'platform/FileStream.h',
+ 'platform/FileStreamClient.h',
'platform/FileSystem.cpp',
'platform/FileSystem.h',
'platform/FloatConversion.h',
@@ -3187,8 +3191,6 @@
'plugins/PluginViewNone.cpp',
'plugins/npapi.cpp',
'plugins/npfunctions.h',
- 'rendering/style/BindingURI.cpp',
- 'rendering/style/BindingURI.h',
'rendering/style/BorderData.h',
'rendering/style/BorderValue.h',
'rendering/style/CollapsedBorderValue.h',
@@ -3528,6 +3530,7 @@
'storage/ChangeVersionWrapper.h',
'storage/chromium/DatabaseObserver.h',
'storage/chromium/IDBFactoryBackendInterface.cpp',
+ 'storage/chromium/IDBKeyPathBackendImpl.cpp',
'storage/chromium/DatabaseTrackerChromium.cpp',
'storage/chromium/QuotaTracker.cpp',
'storage/chromium/QuotaTracker.h',
@@ -3551,6 +3554,8 @@
'storage/DirectoryEntry.h',
'storage/DirectoryReader.cpp',
'storage/DirectoryReader.h',
+ 'storage/DOMFilePath.cpp',
+ 'storage/DOMFilePath.h',
'storage/DOMFileSystem.cpp',
'storage/DOMFileSystem.h',
'storage/EntriesCallback.h',
@@ -3563,7 +3568,11 @@
'storage/FileEntry.cpp',
'storage/FileEntry.h',
'storage/FileSystemCallback.h',
+ 'storage/FileSystemCallbacks.cpp',
+ 'storage/FileSystemCallbacks.h',
'storage/Flags.h',
+ 'storage/IDBAbortEvent.cpp',
+ 'storage/IDBAbortEvent.h',
'storage/IDBAny.cpp',
'storage/IDBAny.h',
'storage/IDBCallbacks.h',
@@ -3585,6 +3594,8 @@
'storage/IDBErrorEvent.h',
'storage/IDBFactory.cpp',
'storage/IDBFactory.h',
+ 'storage/IDBKeyPathBackendImpl.cpp',
+ 'storage/IDBKeyPathBackendImpl.h',
'storage/IDBFactoryBackendInterface.cpp',
'storage/IDBFactoryBackendInterface.h',
'storage/IDBFactoryBackendImpl.cpp',
@@ -3606,13 +3617,20 @@
'storage/IDBObjectStoreBackendImpl.cpp',
'storage/IDBObjectStoreBackendImpl.h',
'storage/IDBObjectStoreBackendInterface.h',
+ 'storage/IDBPendingTransactionMonitor.cpp',
+ 'storage/IDBPendingTransactionMonitor.h',
'storage/IDBRequest.cpp',
'storage/IDBRequest.h',
'storage/IDBSuccessEvent.cpp',
'storage/IDBSuccessEvent.h',
'storage/IDBTransaction.cpp',
'storage/IDBTransaction.h',
+ 'storage/IDBTransactionBackendImpl.cpp',
+ 'storage/IDBTransactionBackendImpl.h',
'storage/IDBTransactionBackendInterface.h',
+ 'storage/IDBTransactionCallbacks.h',
+ 'storage/IDBTransactionCoordinator.cpp',
+ 'storage/IDBTransactionCoordinator.h',
'storage/LocalStorageTask.cpp',
'storage/LocalStorageTask.h',
'storage/LocalStorageThread.cpp',
diff --git a/WebCore/WebCore.pri b/WebCore/WebCore.pri
index de9638f..477e1ba 100644
--- a/WebCore/WebCore.pri
+++ b/WebCore/WebCore.pri
@@ -179,6 +179,7 @@ IDL_BINDINGS += \
html/FileError.idl \
html/FileList.idl \
html/FileReader.idl \
+ html/FileWriter.idl \
html/HTMLAllCollection.idl \
html/HTMLAudioElement.idl \
html/HTMLAnchorElement.idl \
@@ -554,7 +555,7 @@ idl.depends = $$PWD/bindings/scripts/CodeGenerator.pm \
addExtraCompiler(idl)
# GENERATOR 2: inspector idl compiler
-inspectorIDL.output = $${WC_GENERATED_SOURCES_DIR}/Remote${QMAKE_FILE_BASE}Frontend.cpp $${WC_GENERATED_SOURCES_DIR}/${QMAKE_FILE_BASE}BackendDispatcher.cpp
+inspectorIDL.output = $${WC_GENERATED_SOURCES_DIR}/${QMAKE_FILE_BASE}Frontend.cpp $${WC_GENERATED_SOURCES_DIR}/${QMAKE_FILE_BASE}BackendDispatcher.cpp
inspectorIDL.input = INSPECTOR_INTERFACES
inspectorIDL.wkScript = $$PWD/bindings/scripts/generate-bindings.pl
inspectorIDL.commands = perl -I$$PWD/bindings/scripts -I$$PWD/inspector $$inspectorIDL.wkScript --defines \"$${FEATURE_DEFINES_JAVASCRIPT}\" --generator Inspector --outputDir $$WC_GENERATED_SOURCES_DIR --preprocessor \"$${QMAKE_MOC} -E\" ${QMAKE_FILE_NAME}
diff --git a/WebCore/WebCore.pro b/WebCore/WebCore.pro
index 2f5769c..d1ff8b2 100644
--- a/WebCore/WebCore.pro
+++ b/WebCore/WebCore.pro
@@ -8,7 +8,15 @@ meegotouch {
symbian: {
TARGET.EPOCALLOWDLLDATA=1
- TARGET.CAPABILITY = All -Tcb
+ # DRM and Allfiles capabilites need to be audited to be signed on Symbian
+ # For regular users that is not possible, so use the CONFIG(production) flag is added
+ # To use all capabilies add CONFIG+=production
+ # If building from QT source tree, also add CONFIG-=QTDIR_build as qbase.pri defaults capabilities to All -Tcb.
+ CONFIG(production) {
+ TARGET.CAPABILITY = All -Tcb
+ } else {
+ TARGET.CAPABILITY = All -Tcb -DRM -AllFiles
+ }
isEmpty(QT_LIBINFIX) {
TARGET.UID3 = 0x200267C2
} else {
@@ -38,11 +46,6 @@ symbian: {
DEPLOYMENT += webkitlibs webkitbackup
- # Need to guarantee that these come before system includes of /epoc32/include
- MMP_RULES += "USERINCLUDE bridge"
- MMP_RULES += "USERINCLUDE platform/animation"
- MMP_RULES += "USERINCLUDE platform/text"
- MMP_RULES += "USERINCLUDE rendering"
symbian-abld|symbian-sbsv2 {
# RO text (code) section in qtwebkit.dll exceeds allocated space for gcce udeb target.
# Move RW-section base address to start from 0xE00000 instead of the toolchain default 0x400000.
@@ -175,7 +178,7 @@ defineTest(addExtraCompiler) {
}
include(WebCore.pri)
-INCLUDEPATH = \
+WEBCORE_INCLUDEPATH = \
$$PWD \
$$PWD/accessibility \
$$PWD/bindings \
@@ -223,10 +226,9 @@ INCLUDEPATH = \
$$PWD/wml \
$$PWD/workers \
$$PWD/xml \
- $$WC_GENERATED_SOURCES_DIR \
- $$INCLUDEPATH
+ $$WC_GENERATED_SOURCES_DIR
-INCLUDEPATH = \
+WEBCORE_INCLUDEPATH = \
$$PWD/bridge/qt \
$$PWD/page/qt \
$$PWD/platform/graphics/qt \
@@ -234,7 +236,13 @@ INCLUDEPATH = \
$$PWD/platform/qt \
$$PWD/../WebKit/qt/Api \
$$PWD/../WebKit/qt/WebCoreSupport \
- $$INCLUDEPATH
+ $$WEBCORE_INCLUDEPATH
+
+symbian {
+ PREPEND_INCLUDEPATH = $$WEBCORE_INCLUDEPATH $$PREPEND_INCLUDEPATH
+} else {
+ INCLUDEPATH = $$WEBCORE_INCLUDEPATH $$INCLUDEPATH
+}
QT += network
@@ -487,6 +495,7 @@ SOURCES += \
dom/DeviceOrientationEvent.cpp \
dom/Document.cpp \
dom/DocumentFragment.cpp \
+ dom/DocumentMarkerController.cpp \
dom/DocumentParser.cpp \
dom/DocumentType.cpp \
dom/DOMImplementation.cpp \
@@ -636,9 +645,9 @@ SOURCES += \
html/File.cpp \
html/FileList.cpp \
html/FileReader.cpp \
- html/FileStream.cpp \
html/FileStreamProxy.cpp \
html/FileThread.cpp \
+ html/FileWriter.cpp \
html/FormDataList.cpp \
html/HTMLEntityParser.cpp \
html/HTMLTokenizer.cpp \
@@ -710,7 +719,6 @@ SOURCES += \
html/HTMLOptionsCollection.cpp \
html/HTMLParagraphElement.cpp \
html/HTMLParamElement.cpp \
- html/LegacyHTMLTreeBuilder.cpp \
html/HTMLParserErrorCodes.cpp \
html/HTMLParserScheduler.cpp \
html/HTMLPlugInElement.cpp \
@@ -753,6 +761,7 @@ SOURCES += \
inspector/InspectorDOMStorageResource.cpp \
inspector/InspectorFrontendClientLocal.cpp \
inspector/InspectorFrontendHost.cpp \
+ inspector/InspectorProfilerAgent.cpp \
inspector/InspectorResource.cpp \
inspector/InspectorStorageAgent.cpp \
inspector/InspectorTimelineAgent.cpp \
@@ -792,6 +801,7 @@ SOURCES += \
loader/MediaDocument.cpp \
loader/NavigationAction.cpp \
loader/NetscapePlugInStreamLoader.cpp \
+ loader/PingLoader.cpp \
loader/PlaceholderDocument.cpp \
loader/PluginDocument.cpp \
loader/PolicyCallback.cpp \
@@ -875,6 +885,7 @@ SOURCES += \
platform/DragData.cpp \
platform/DragImage.cpp \
platform/FileChooser.cpp \
+ platform/FileStream.cpp \
platform/FileSystem.cpp \
platform/GeolocationService.cpp \
platform/image-decoders/qt/RGBA32BufferQt.cpp \
@@ -930,6 +941,7 @@ SOURCES += \
platform/network/AuthenticationChallengeBase.cpp \
platform/network/BlobData.cpp \
platform/network/BlobRegistryImpl.cpp \
+ platform/network/BlobResourceHandle.cpp \
platform/network/Credential.cpp \
platform/network/FormData.cpp \
platform/network/FormDataBuilder.cpp \
@@ -1049,7 +1061,6 @@ SOURCES += \
rendering/ShadowElement.cpp \
rendering/TextControlInnerElements.cpp \
rendering/TransformState.cpp \
- rendering/style/BindingURI.cpp \
rendering/style/ContentData.cpp \
rendering/style/CounterDirectives.cpp \
rendering/style/FillLayer.cpp \
@@ -1257,15 +1268,17 @@ HEADERS += \
dom/CustomEvent.h \
dom/default/PlatformMessagePortChannel.h \
dom/DeviceMotionClient.h \
- dom/DeviceMotionData.h \
dom/DeviceMotionController.h \
+ dom/DeviceMotionData.h \
dom/DeviceMotionEvent.h \
dom/DeviceOrientation.h \
dom/DeviceOrientationClient.h \
dom/DeviceOrientationController.h \
dom/DeviceOrientationEvent.h \
- dom/DocumentFragment.h \
dom/Document.h \
+ dom/DocumentFragment.h \
+ dom/DocumentMarker.h \
+ dom/DocumentMarkerController.h \
dom/DocumentType.h \
dom/DOMImplementation.h \
dom/DOMStringList.h \
@@ -1410,11 +1423,10 @@ HEADERS += \
html/FileError.h \
html/FileList.h \
html/FileReader.h \
- html/FileStream.h \
- html/FileStreamClient.h \
html/FileStreamProxy.h \
html/FileThread.h \
html/FileThreadTask.h \
+ html/FileWriter.h \
html/FormDataList.h \
html/HTMLAllCollection.h \
html/HTMLAnchorElement.h \
@@ -1479,7 +1491,6 @@ HEADERS += \
html/HTMLParagraphElement.h \
html/HTMLParamElement.h \
html/HTMLParserErrorCodes.h \
- html/LegacyHTMLTreeBuilder.h \
html/HTMLPlugInElement.h \
html/HTMLPlugInImageElement.h \
html/HTMLPreElement.h \
@@ -1521,6 +1532,7 @@ HEADERS += \
inspector/InspectorFrontendClient.h \
inspector/InspectorFrontendClientLocal.h \
inspector/InspectorFrontendHost.h \
+ inspector/InspectorProfilerAgent.h \
inspector/InspectorResource.h \
inspector/InspectorStorageAgent.h \
inspector/InspectorTimelineAgent.h \
@@ -1645,6 +1657,7 @@ HEADERS += \
platform/animation/Animation.h \
platform/animation/AnimationList.h \
platform/Arena.h \
+ platform/AsyncFileStream.h \
platform/BlobItem.h \
platform/ContentType.h \
platform/ContextMenu.h \
@@ -1653,6 +1666,8 @@ HEADERS += \
platform/DragData.h \
platform/DragImage.h \
platform/FileChooser.h \
+ platform/FileStream.h \
+ platform/FileStreamClient.h \
platform/FileSystem.h \
platform/GeolocationService.h \
platform/image-decoders/ImageDecoder.h \
@@ -1726,6 +1741,7 @@ HEADERS += \
platform/network/BlobData.h \
platform/network/BlobRegistry.h \
platform/network/BlobRegistryImpl.h \
+ platform/network/BlobResourceHandle.h \
platform/network/BlobStorageData.h \
platform/network/Credential.h \
platform/network/FormDataBuilder.h \
@@ -1900,7 +1916,6 @@ HEADERS += \
rendering/RootInlineBox.h \
rendering/ScrollBehavior.h \
rendering/ShadowElement.h \
- rendering/style/BindingURI.h \
rendering/style/ContentData.h \
rendering/style/CounterDirectives.h \
rendering/style/CursorData.h \
@@ -2568,6 +2583,7 @@ contains(DEFINES, ENABLE_FILE_SYSTEM=1) {
HEADERS += \
storage/DirectoryEntry.h \
storage/DirectoryReader.h \
+ storage/DOMFilePath.h \
storage/DOMFileSystem.h \
storage/EntriesCallback.h \
storage/Entry.h \
@@ -2576,6 +2592,7 @@ contains(DEFINES, ENABLE_FILE_SYSTEM=1) {
storage/ErrorCallback.h \
storage/FileEntry.h \
storage/FileSystemCallback.h \
+ storage/FileSystemCallbacks.h \
storage/Flags.h \
storage/Metadata.h \
storage/MetadataCallback.h
@@ -2583,10 +2600,12 @@ contains(DEFINES, ENABLE_FILE_SYSTEM=1) {
SOURCES += \
storage/DirectoryEntry.cpp \
storage/DirectoryReader.cpp \
+ storage/DOMFilePath.cpp \
storage/DOMFileSystem.cpp \
storage/Entry.cpp \
storage/EntryArray.cpp \
- storage/FileEntry.cpp
+ storage/FileEntry.cpp \
+ storage/FileSystemCallbacks.cpp
}
contains(DEFINES, ENABLE_ICONDATABASE=1) {
@@ -2799,6 +2818,7 @@ contains(DEFINES, ENABLE_QT_BEARER=1) {
}
contains(DEFINES, ENABLE_GEOLOCATION=1) {
+ DEFINES += WTF_USE_PREEMPT_GEOLOCATION_PERMISSION
HEADERS += \
platform/qt/GeolocationServiceQt.h
SOURCES += \
diff --git a/WebCore/WebCore.vcproj/WebCore.vcproj b/WebCore/WebCore.vcproj/WebCore.vcproj
index d2f6d3d..a049866 100644
--- a/WebCore/WebCore.vcproj/WebCore.vcproj
+++ b/WebCore/WebCore.vcproj/WebCore.vcproj
@@ -553,6 +553,14 @@
>
</File>
<File
+ RelativePath="$(WebKitOutputDir)\obj\$(ProjectName)\DerivedSources\InspectorFrontend.cpp"
+ >
+ </File>
+ <File
+ RelativePath="$(WebKitOutputDir)\obj\$(ProjectName)\DerivedSources\InspectorFrontend.h"
+ >
+ </File>
+ <File
RelativePath="$(WebKitOutputDir)\obj\WebCore\DerivedSources\JSAbstractWorker.cpp"
>
<FileConfiguration
@@ -5037,6 +5045,62 @@
>
</File>
<File
+ RelativePath="$(WebKitOutputDir)\obj\$(ProjectName)\DerivedSources\JSFileWriter.cpp"
+ >
+ <FileConfiguration
+ Name="Debug|Win32"
+ ExcludedFromBuild="true"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|Win32"
+ ExcludedFromBuild="true"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Debug_Internal|Win32"
+ ExcludedFromBuild="true"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Debug_Cairo|Win32"
+ ExcludedFromBuild="true"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release_Cairo|Win32"
+ ExcludedFromBuild="true"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Debug_All|Win32"
+ ExcludedFromBuild="true"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ />
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath="$(WebKitOutputDir)\obj\$(ProjectName)\DerivedSources\JSFileWriter.h"
+ >
+ </File>
+ <File
RelativePath="$(WebKitOutputDir)\obj\$(ProjectName)\DerivedSources\JSFlags.cpp"
>
<FileConfiguration
@@ -21421,14 +21485,6 @@
>
</File>
<File
- RelativePath="$(WebKitOutputDir)\obj\$(ProjectName)\DerivedSources\RemoteInspectorFrontend.cpp"
- >
- </File>
- <File
- RelativePath="$(WebKitOutputDir)\obj\$(ProjectName)\DerivedSources\RemoteInspectorFrontend.h"
- >
- </File>
- <File
RelativePath="$(WebKitOutputDir)\obj\$(ProjectName)\DerivedSources\SVGElementFactory.cpp"
>
</File>
@@ -23417,14 +23473,6 @@
>
</File>
<File
- RelativePath="..\loader\CachedXBLDocument.cpp"
- >
- </File>
- <File
- RelativePath="..\loader\CachedXBLDocument.h"
- >
- </File>
- <File
RelativePath="..\loader\CachedXSLStyleSheet.cpp"
>
</File>
@@ -23617,6 +23665,14 @@
>
</File>
<File
+ RelativePath="..\loader\PingLoader.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\loader\PingLoader.h"
+ >
+ </File>
+ <File
RelativePath="..\loader\PlaceholderDocument.cpp"
>
</File>
@@ -23941,6 +23997,10 @@
>
</File>
<File
+ RelativePath="..\platform\AsyncFileStream.h"
+ >
+ </File>
+ <File
RelativePath="..\platform\AutodrainedPool.h"
>
</File>
@@ -24033,6 +24093,18 @@
>
</File>
<File
+ RelativePath="..\platform\FileStream.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\platform\FileStream.h"
+ >
+ </File>
+ <File
+ RelativePath="..\platform\FileStreamClient.h"
+ >
+ </File>
+ <File
RelativePath="..\platform\FileSystem.cpp"
>
</File>
@@ -26575,6 +26647,42 @@
</FileConfiguration>
</File>
<File
+ RelativePath="..\platform\graphics\cairo\PlatformRefPtrCairo.cpp"
+ >
+ <FileConfiguration
+ Name="Debug|Win32"
+ ExcludedFromBuild="true"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|Win32"
+ ExcludedFromBuild="true"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Debug_Internal|Win32"
+ ExcludedFromBuild="true"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Debug_All|Win32"
+ ExcludedFromBuild="true"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ />
+ </FileConfiguration>
+ </File>
+ <File
RelativePath="..\platform\graphics\cairo\TransformationMatrixCairo.cpp"
>
<FileConfiguration
@@ -26820,6 +26928,14 @@
>
</File>
<File
+ RelativePath="..\platform\network\BlobResourceHandle.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\platform\network\BlobResourceHandle.h"
+ >
+ </File>
+ <File
RelativePath="..\platform\network\BlobStorageData.h"
>
</File>
@@ -26872,15 +26988,15 @@
>
</File>
<File
- RelativePath="..\platform\network\NetworkStateNotifier.cpp"
+ RelativePath="..\platform\network\NetworkingContext.h"
>
</File>
<File
- RelativePath="..\platform\network\NetworkStateNotifier.h"
+ RelativePath="..\platform\network\NetworkStateNotifier.cpp"
>
</File>
<File
- RelativePath="..\platform\network\NetworkingContext.h"
+ RelativePath="..\platform\network\NetworkStateNotifier.h"
>
</File>
<File
@@ -32726,14 +32842,6 @@
Name="style"
>
<File
- RelativePath="..\rendering\style\BindingURI.cpp"
- >
- </File>
- <File
- RelativePath="..\rendering\style\BindingURI.h"
- >
- </File>
- <File
RelativePath="..\rendering\style\BorderData.h"
>
</File>
@@ -33253,15 +33361,15 @@
>
</File>
<File
- RelativePath="..\dom\AtomicStringList.h"
+ RelativePath="..\dom\AsyncScriptRunner.cpp"
>
</File>
<File
- RelativePath="..\dom\AsyncScriptRunner.cpp"
+ RelativePath="..\dom\AsyncScriptRunner.h"
>
</File>
<File
- RelativePath="..\dom\AsyncScriptRunner.h"
+ RelativePath="..\dom\AtomicStringList.h"
>
</File>
<File
@@ -33521,6 +33629,14 @@
>
</File>
<File
+ RelativePath="..\dom\DocumentMarkerController.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\dom\DocumentMarkerController.h"
+ >
+ </File>
+ <File
RelativePath="..\dom\DocumentParser.cpp"
>
</File>
@@ -33817,19 +33933,19 @@
>
</File>
<File
- RelativePath="..\dom\PendingScript.cpp"
+ RelativePath="..\dom\PageTransitionEvent.cpp"
>
</File>
<File
- RelativePath="..\dom\PendingScript.h"
+ RelativePath="..\dom\PageTransitionEvent.h"
>
</File>
<File
- RelativePath="..\dom\PageTransitionEvent.cpp"
+ RelativePath="..\dom\PendingScript.cpp"
>
</File>
<File
- RelativePath="..\dom\PageTransitionEvent.h"
+ RelativePath="..\dom\PendingScript.h"
>
</File>
<File
@@ -37137,35 +37253,31 @@
>
</File>
<File
- RelativePath="..\html\FileStream.cpp"
+ RelativePath="..\html\FileStreamProxy.cpp"
>
</File>
<File
- RelativePath="..\html\FileStream.h"
+ RelativePath="..\html\FileStreamProxy.h"
>
</File>
<File
- RelativePath="..\html\FileStreamClient.h"
+ RelativePath="..\html\FileThread.cpp"
>
</File>
<File
- RelativePath="..\html\FileStreamProxy.cpp"
+ RelativePath="..\html\FileThread.h"
>
</File>
<File
- RelativePath="..\html\FileStreamProxy.h"
+ RelativePath="..\html\FileThreadTask.h"
>
</File>
<File
- RelativePath="..\html\FileThread.cpp"
+ RelativePath="..\html\FileWriter.cpp"
>
</File>
<File
- RelativePath="..\html\FileThread.h"
- >
- </File>
- <File
- RelativePath="..\html\FileThreadTask.h"
+ RelativePath="..\html\FileWriter.h"
>
</File>
<File
@@ -38349,14 +38461,6 @@
>
</File>
<File
- RelativePath="..\html\HTMLEntitySearch.cpp"
- >
- </File>
- <File
- RelativePath="..\html\HTMLEntitySearch.h"
- >
- </File>
- <File
RelativePath="..\html\HTMLEmbedElement.cpp"
>
<FileConfiguration
@@ -38421,6 +38525,14 @@
>
</File>
<File
+ RelativePath="..\html\HTMLEntitySearch.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\html\HTMLEntitySearch.h"
+ >
+ </File>
+ <File
RelativePath="..\html\HTMLFieldSetElement.cpp"
>
<FileConfiguration
@@ -41649,14 +41761,6 @@
>
</File>
<File
- RelativePath="..\html\LegacyHTMLTreeBuilder.cpp"
- >
- </File>
- <File
- RelativePath="..\html\LegacyHTMLTreeBuilder.h"
- >
- </File>
- <File
RelativePath="..\html\MediaError.h"
>
</File>
@@ -45104,7 +45208,7 @@
</FileConfiguration>
</File>
<File
- RelativePath="$(WebKitOutputDir)\obj\$(ProjectName)\DerivedSources\JSIDBCursor.cpp"
+ RelativePath="..\bindings\js\JSHTMLOptionsCollectionCustom.cpp"
>
<FileConfiguration
Name="Debug|Win32"
@@ -45156,7 +45260,7 @@
</FileConfiguration>
</File>
<File
- RelativePath="$(WebKitOutputDir)\obj\$(ProjectName)\DerivedSources\JSIDBCursor.h"
+ RelativePath="..\bindings\js\JSHTMLSelectElementCustom.cpp"
>
<FileConfiguration
Name="Debug|Win32"
@@ -45208,7 +45312,11 @@
</FileConfiguration>
</File>
<File
- RelativePath="..\bindings\js\JSHTMLOptionsCollectionCustom.cpp"
+ RelativePath="..\bindings\js\JSHTMLSelectElementCustom.h"
+ >
+ </File>
+ <File
+ RelativePath="$(WebKitOutputDir)\obj\$(ProjectName)\DerivedSources\JSIDBAny.cpp"
>
<FileConfiguration
Name="Debug|Win32"
@@ -45260,7 +45368,11 @@
</FileConfiguration>
</File>
<File
- RelativePath="..\bindings\js\JSHTMLSelectElementCustom.cpp"
+ RelativePath="$(WebKitOutputDir)\obj\$(ProjectName)\DerivedSources\JSIDBAny.h"
+ >
+ </File>
+ <File
+ RelativePath="..\bindings\js\JSIDBAnyCustom.cpp"
>
<FileConfiguration
Name="Debug|Win32"
@@ -45312,11 +45424,7 @@
</FileConfiguration>
</File>
<File
- RelativePath="..\bindings\js\JSHTMLSelectElementCustom.h"
- >
- </File>
- <File
- RelativePath="$(WebKitOutputDir)\obj\$(ProjectName)\DerivedSources\JSIDBAny.cpp"
+ RelativePath="$(WebKitOutputDir)\obj\$(ProjectName)\DerivedSources\JSIDBCursor.cpp"
>
<FileConfiguration
Name="Debug|Win32"
@@ -45368,11 +45476,7 @@
</FileConfiguration>
</File>
<File
- RelativePath="$(WebKitOutputDir)\obj\$(ProjectName)\DerivedSources\JSIDBAny.h"
- >
- </File>
- <File
- RelativePath="..\bindings\js\JSIDBAnyCustom.cpp"
+ RelativePath="$(WebKitOutputDir)\obj\$(ProjectName)\DerivedSources\JSIDBCursor.h"
>
<FileConfiguration
Name="Debug|Win32"
@@ -51101,6 +51205,14 @@
>
</File>
<File
+ RelativePath="..\storage\DOMFilePath.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\storage\DOMFilePath.h"
+ >
+ </File>
+ <File
RelativePath="..\storage\DOMFileSystem.cpp"
>
</File>
@@ -51149,6 +51261,14 @@
>
</File>
<File
+ RelativePath="..\storage\FileSystemCallbacks.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\storage\FileSystemCallbacks.h"
+ >
+ </File>
+ <File
RelativePath="..\storage\Flags.h"
>
</File>
@@ -51341,19 +51461,19 @@
>
</File>
<File
- RelativePath="..\storage\Metadata.h"
+ RelativePath="..\storage\LocalStorageThread.cpp"
>
</File>
<File
- RelativePath="..\storage\MetadataCallback.h"
+ RelativePath="..\storage\LocalStorageThread.h"
>
</File>
<File
- RelativePath="..\storage\LocalStorageThread.cpp"
+ RelativePath="..\storage\Metadata.h"
>
</File>
<File
- RelativePath="..\storage\LocalStorageThread.h"
+ RelativePath="..\storage\MetadataCallback.h"
>
</File>
<File
@@ -51809,6 +51929,14 @@
>
</File>
<File
+ RelativePath="..\inspector\InspectorProfilerAgent.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\inspector\InspectorProfilerAgent.h"
+ >
+ </File>
+ <File
RelativePath="..\inspector\InspectorResource.cpp"
>
</File>
diff --git a/WebCore/WebCore.xcodeproj/project.pbxproj b/WebCore/WebCore.xcodeproj/project.pbxproj
index 2953b96..d7633e3 100644
--- a/WebCore/WebCore.xcodeproj/project.pbxproj
+++ b/WebCore/WebCore.xcodeproj/project.pbxproj
@@ -704,6 +704,8 @@
2EA768040FE7126400AB9C8A /* WorkerScriptLoaderClient.h in Headers */ = {isa = PBXBuildFile; fileRef = 2EA768030FE7126400AB9C8A /* WorkerScriptLoaderClient.h */; };
2EAFAF0E10E2AF2D007ED3D6 /* Blob.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2EAFAF0B10E2AF2D007ED3D6 /* Blob.cpp */; };
2EAFAF0F10E2AF2D007ED3D6 /* Blob.h in Headers */ = {isa = PBXBuildFile; fileRef = 2EAFAF0C10E2AF2D007ED3D6 /* Blob.h */; };
+ 2EB4BCD2121F03E300EC4885 /* BlobResourceHandle.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2EB4BCD0121F03E300EC4885 /* BlobResourceHandle.cpp */; };
+ 2EB4BCD3121F03E300EC4885 /* BlobResourceHandle.h in Headers */ = {isa = PBXBuildFile; fileRef = 2EB4BCD1121F03E300EC4885 /* BlobResourceHandle.h */; };
2ECF7ADC10162B3800427DE7 /* JSErrorEvent.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2ECF7ADA10162B3800427DE7 /* JSErrorEvent.cpp */; };
2ECF7ADD10162B3800427DE7 /* JSErrorEvent.h in Headers */ = {isa = PBXBuildFile; fileRef = 2ECF7ADB10162B3800427DE7 /* JSErrorEvent.h */; };
2ECF7AE110162B5800427DE7 /* ErrorEvent.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2ECF7ADE10162B5800427DE7 /* ErrorEvent.cpp */; };
@@ -720,6 +722,10 @@
2EED575612109ED0007656BB /* BlobURL.h in Headers */ = {isa = PBXBuildFile; fileRef = 2EED575112109ED0007656BB /* BlobURL.h */; };
2EED57FD1214A9C2007656BB /* ThreadableBlobRegistry.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2EED57FB1214A9C2007656BB /* ThreadableBlobRegistry.cpp */; };
2EED57FE1214A9C2007656BB /* ThreadableBlobRegistry.h in Headers */ = {isa = PBXBuildFile; fileRef = 2EED57FC1214A9C2007656BB /* ThreadableBlobRegistry.h */; };
+ 2EF1BFEA121C9F4200C27627 /* FileStream.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2EF1BFE8121C9F4200C27627 /* FileStream.cpp */; };
+ 2EF1BFEB121C9F4200C27627 /* FileStream.h in Headers */ = {isa = PBXBuildFile; fileRef = 2EF1BFE9121C9F4200C27627 /* FileStream.h */; settings = {ATTRIBUTES = (Private, ); }; };
+ 2EF1BFF7121CB0BD00C27627 /* AsyncFileStream.h in Headers */ = {isa = PBXBuildFile; fileRef = 2EF1BFF6121CB0BD00C27627 /* AsyncFileStream.h */; settings = {ATTRIBUTES = (Private, ); }; };
+ 2EF1BFF9121CB0CE00C27627 /* FileStreamClient.h in Headers */ = {isa = PBXBuildFile; fileRef = 2EF1BFF8121CB0CE00C27627 /* FileStreamClient.h */; settings = {ATTRIBUTES = (Private, ); }; };
31288E720E3005D6003619AE /* WebKitCSSKeyframeRule.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 31288E6E0E3005D6003619AE /* WebKitCSSKeyframeRule.cpp */; };
31288E730E3005D6003619AE /* WebKitCSSKeyframeRule.h in Headers */ = {isa = PBXBuildFile; fileRef = 31288E6F0E3005D6003619AE /* WebKitCSSKeyframeRule.h */; };
31288E740E3005D6003619AE /* WebKitCSSKeyframesRule.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 31288E700E3005D6003619AE /* WebKitCSSKeyframesRule.cpp */; };
@@ -894,6 +900,8 @@
4614A1FE0B23A8D600446E1C /* copyCursor.png in Resources */ = {isa = PBXBuildFile; fileRef = 4614A1FD0B23A8D600446E1C /* copyCursor.png */; };
464EA2730B8A350B00A8E6E3 /* crossHairCursor.png in Resources */ = {isa = PBXBuildFile; fileRef = 464EA2710B8A350B00A8E6E3 /* crossHairCursor.png */; };
464EA2740B8A350B00A8E6E3 /* notAllowedCursor.png in Resources */ = {isa = PBXBuildFile; fileRef = 464EA2720B8A350B00A8E6E3 /* notAllowedCursor.png */; };
+ 46A26905121B6B4300C41F3A /* FileWriter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 46A26902121B6B4300C41F3A /* FileWriter.cpp */; };
+ 46A26906121B6B4300C41F3A /* FileWriter.h in Headers */ = {isa = PBXBuildFile; fileRef = 46A26903121B6B4300C41F3A /* FileWriter.h */; };
46BD16E30B279473001F0839 /* noneCursor.png in Resources */ = {isa = PBXBuildFile; fileRef = 46BD16E20B279473001F0839 /* noneCursor.png */; };
46D4F2490AF97E810035385A /* cellCursor.png in Resources */ = {isa = PBXBuildFile; fileRef = 46D4F2460AF97E810035385A /* cellCursor.png */; };
46D4F24A0AF97E810035385A /* contextMenuCursor.png in Resources */ = {isa = PBXBuildFile; fileRef = 46D4F2470AF97E810035385A /* contextMenuCursor.png */; };
@@ -1063,7 +1071,7 @@
4F1534E011B533020021FD86 /* EditingBehaviorTypes.h in Headers */ = {isa = PBXBuildFile; fileRef = 4F1534DF11B533020021FD86 /* EditingBehaviorTypes.h */; settings = {ATTRIBUTES = (Private, ); }; };
4F3289B511A42AAB005ABE7E /* InspectorValues.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4F3289B311A42AAB005ABE7E /* InspectorValues.cpp */; };
4F3289B611A42AAB005ABE7E /* InspectorValues.h in Headers */ = {isa = PBXBuildFile; fileRef = 4F3289B411A42AAB005ABE7E /* InspectorValues.h */; settings = {ATTRIBUTES = (Private, ); }; };
- 4F4F5FFB11CBD2E100A186BF /* RemoteInspectorFrontend.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4F4F5FFA11CBD2D200A186BF /* RemoteInspectorFrontend.cpp */; };
+ 4F4F5FFB11CBD2E100A186BF /* InspectorFrontend.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4F4F5FFA11CBD2D200A186BF /* InspectorFrontend.cpp */; };
4F707A9911EF679400ACDA69 /* InspectorBackendDispatcher.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4F707A9711EF679400ACDA69 /* InspectorBackendDispatcher.cpp */; };
4F707A9A11EF679400ACDA69 /* InspectorBackendDispatcher.h in Headers */ = {isa = PBXBuildFile; fileRef = 4F707A9811EF679400ACDA69 /* InspectorBackendDispatcher.h */; };
4FD8D0F2119C718B002FA825 /* ScriptGCEvent.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4FD8D0F0119C718B002FA825 /* ScriptGCEvent.cpp */; };
@@ -2374,14 +2382,19 @@
85FF315A0AAFBFCB00374F38 /* DOMKeyboardEvent.h in Headers */ = {isa = PBXBuildFile; fileRef = 85FF31580AAFBFCB00374F38 /* DOMKeyboardEvent.h */; };
85FF315B0AAFBFCB00374F38 /* DOMKeyboardEvent.mm in Sources */ = {isa = PBXBuildFile; fileRef = 85FF31590AAFBFCB00374F38 /* DOMKeyboardEvent.mm */; };
86243D0111BC31F700CC006A /* JSArrayBufferViewHelper.h in Headers */ = {isa = PBXBuildFile; fileRef = 86243D0011BC31F700CC006A /* JSArrayBufferViewHelper.h */; };
+ 8947A82912222C4700D95F2D /* JSMetadata.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8947A82512222C4700D95F2D /* JSMetadata.cpp */; };
+ 8947A82A12222C4700D95F2D /* JSMetadata.h in Headers */ = {isa = PBXBuildFile; fileRef = 8947A82612222C4700D95F2D /* JSMetadata.h */; };
+ 8947A82B12222C4700D95F2D /* JSMetadataCallback.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8947A82712222C4700D95F2D /* JSMetadataCallback.cpp */; };
+ 8947A82C12222C4700D95F2D /* JSMetadataCallback.h in Headers */ = {isa = PBXBuildFile; fileRef = 8947A82812222C4700D95F2D /* JSMetadataCallback.h */; };
+ 8947A83C122234F400D95F2D /* Metadata.h in Headers */ = {isa = PBXBuildFile; fileRef = 897A2D73120001440082740C /* Metadata.h */; };
+ 8947A83D122234F900D95F2D /* MetadataCallback.h in Headers */ = {isa = PBXBuildFile; fileRef = 897A2D75120001440082740C /* MetadataCallback.h */; };
8952535211641B3400CABF00 /* FileThread.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8952535011641B3400CABF00 /* FileThread.cpp */; };
8952535311641B3400CABF00 /* FileThread.h in Headers */ = {isa = PBXBuildFile; fileRef = 8952535111641B3400CABF00 /* FileThread.h */; };
- 895253D7116C4C6800CABF00 /* FileStream.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 895253D4116C4C6800CABF00 /* FileStream.cpp */; };
- 895253D8116C4C6800CABF00 /* FileStream.h in Headers */ = {isa = PBXBuildFile; fileRef = 895253D5116C4C6800CABF00 /* FileStream.h */; };
- 895253D9116C4C6800CABF00 /* FileStreamClient.h in Headers */ = {isa = PBXBuildFile; fileRef = 895253D6116C4C6800CABF00 /* FileStreamClient.h */; };
895253DC116C4EF500CABF00 /* FileStreamProxy.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 895253DA116C4EF500CABF00 /* FileStreamProxy.cpp */; };
895253DD116C4EF500CABF00 /* FileStreamProxy.h in Headers */ = {isa = PBXBuildFile; fileRef = 895253DB116C4EF500CABF00 /* FileStreamProxy.h */; };
895253DF116C4F0600CABF00 /* FileThreadTask.h in Headers */ = {isa = PBXBuildFile; fileRef = 895253DE116C4F0600CABF00 /* FileThreadTask.h */; };
+ 89686C9F122244A00076EAA4 /* DOMFilePath.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 89686C9D122244A00076EAA4 /* DOMFilePath.cpp */; };
+ 89686CA0122244A00076EAA4 /* DOMFilePath.h in Headers */ = {isa = PBXBuildFile; fileRef = 89686C9E122244A00076EAA4 /* DOMFilePath.h */; };
8988E10E11A3508B00DB732E /* BlobItem.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8988E10C11A3508B00DB732E /* BlobItem.cpp */; };
8988E10F11A3508B00DB732E /* BlobItem.h in Headers */ = {isa = PBXBuildFile; fileRef = 8988E10D11A3508B00DB732E /* BlobItem.h */; settings = {ATTRIBUTES = (Private, ); }; };
899ABC261215E4A300F9F219 /* DirectoryEntry.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 899ABC201215E4A300F9F219 /* DirectoryEntry.cpp */; };
@@ -2427,6 +2440,8 @@
89B5EAA211E8003D00F2367E /* LineEnding.h in Headers */ = {isa = PBXBuildFile; fileRef = 89B5EAA011E8003D00F2367E /* LineEnding.h */; settings = {ATTRIBUTES = (Private, ); }; };
89BED5EB11BE11CE00448492 /* BlobBuilder.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 89BED5E911BE11CE00448492 /* BlobBuilder.cpp */; };
89BED5EC11BE11CE00448492 /* BlobBuilder.h in Headers */ = {isa = PBXBuildFile; fileRef = 89BED5EA11BE11CE00448492 /* BlobBuilder.h */; };
+ 89C0DD7A121F0C69009E17CA /* FileSystemCallbacks.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 89C0DD78121F0C69009E17CA /* FileSystemCallbacks.cpp */; };
+ 89C0DD7B121F0C69009E17CA /* FileSystemCallbacks.h in Headers */ = {isa = PBXBuildFile; fileRef = 89C0DD79121F0C69009E17CA /* FileSystemCallbacks.h */; };
89CD029311C85B870070B791 /* JSBlobBuilder.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 89CD029111C85B870070B791 /* JSBlobBuilder.cpp */; };
89CD029411C85B870070B791 /* JSBlobBuilder.h in Headers */ = {isa = PBXBuildFile; fileRef = 89CD029211C85B870070B791 /* JSBlobBuilder.h */; };
8A12E35D11FA33280025836A /* DocumentLoadTiming.h in Headers */ = {isa = PBXBuildFile; fileRef = 8A12E35C11FA33280025836A /* DocumentLoadTiming.h */; settings = {ATTRIBUTES = (Private, ); }; };
@@ -2649,7 +2664,6 @@
93EB355F09E37FD600F43799 /* MouseEventWithHitTestResults.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 93EB355E09E37FD600F43799 /* MouseEventWithHitTestResults.cpp */; };
93F198E508245E59001E9ABC /* HTMLDocument.h in Headers */ = {isa = PBXBuildFile; fileRef = F523D23C02DE4396018635CA /* HTMLDocument.h */; settings = {ATTRIBUTES = (Private, ); }; };
93F198E608245E59001E9ABC /* HTMLElement.h in Headers */ = {isa = PBXBuildFile; fileRef = F523D23F02DE4396018635CA /* HTMLElement.h */; settings = {ATTRIBUTES = (Private, ); }; };
- 93F198EF08245E59001E9ABC /* LegacyHTMLTreeBuilder.h in Headers */ = {isa = PBXBuildFile; fileRef = F523D25102DE4396018635CA /* LegacyHTMLTreeBuilder.h */; };
93F198F608245E59001E9ABC /* TextResourceDecoder.h in Headers */ = {isa = PBXBuildFile; fileRef = F523D27902DE43D7018635CA /* TextResourceDecoder.h */; settings = {ATTRIBUTES = (Private, ); }; };
93F1991808245E59001E9ABC /* Range.h in Headers */ = {isa = PBXBuildFile; fileRef = F523D30402DE4476018635CA /* Range.h */; settings = {ATTRIBUTES = (Private, ); }; };
93F1992108245E59001E9ABC /* XMLDocumentParser.h in Headers */ = {isa = PBXBuildFile; fileRef = F523D30A02DE4476018635CA /* XMLDocumentParser.h */; settings = {ATTRIBUTES = (Private, ); }; };
@@ -2678,7 +2692,6 @@
93F19A5F08245E59001E9ABC /* WebCoreViewFactory.m in Sources */ = {isa = PBXBuildFile; fileRef = F587855502DE375901EA4122 /* WebCoreViewFactory.m */; };
93F19A9108245E59001E9ABC /* HTMLDocument.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F523D23B02DE4396018635CA /* HTMLDocument.cpp */; };
93F19A9208245E59001E9ABC /* HTMLElement.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F523D23E02DE4396018635CA /* HTMLElement.cpp */; };
- 93F19A9B08245E59001E9ABC /* LegacyHTMLTreeBuilder.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F523D25002DE4396018635CA /* LegacyHTMLTreeBuilder.cpp */; };
93F19A9D08245E59001E9ABC /* TextResourceDecoder.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F523D27802DE43D7018635CA /* TextResourceDecoder.cpp */; };
93F19AB908245E59001E9ABC /* Range.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F523D30302DE4476018635CA /* Range.cpp */; };
93F19ABC08245E59001E9ABC /* XMLDocumentParser.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F523D30902DE4476018635CA /* XMLDocumentParser.cpp */; };
@@ -2740,6 +2753,8 @@
97EF561011E40783007E026F /* HTMLConstructionSite.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 97EF560E11E40783007E026F /* HTMLConstructionSite.cpp */; };
97EF561111E40783007E026F /* HTMLConstructionSite.h in Headers */ = {isa = PBXBuildFile; fileRef = 97EF560F11E40783007E026F /* HTMLConstructionSite.h */; };
97EF7DFE107E55B700D7C49C /* ScriptControllerBase.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 97EF7DFD107E55B700D7C49C /* ScriptControllerBase.cpp */; };
+ 9F0D6B2E121BFEBA006C0288 /* InspectorProfilerAgent.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 9F0D6B2C121BFEBA006C0288 /* InspectorProfilerAgent.cpp */; };
+ 9F0D6B2F121BFEBA006C0288 /* InspectorProfilerAgent.h in Headers */ = {isa = PBXBuildFile; fileRef = 9F0D6B2D121BFEBA006C0288 /* InspectorProfilerAgent.h */; };
9F6FC1961122E82A00E80196 /* ScriptDebugServer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 9F6FC1941122E82A00E80196 /* ScriptDebugServer.cpp */; };
9F6FC1971122E82A00E80196 /* ScriptDebugServer.h in Headers */ = {isa = PBXBuildFile; fileRef = 9F6FC1951122E82A00E80196 /* ScriptDebugServer.h */; settings = {ATTRIBUTES = (Private, ); }; };
9F72304F11184B4100AD0126 /* ScriptProfile.h in Headers */ = {isa = PBXBuildFile; fileRef = 9F72304C11184B4100AD0126 /* ScriptProfile.h */; settings = {ATTRIBUTES = (Private, ); }; };
@@ -4646,8 +4661,6 @@
BC5EB8B90E8201BD00B25965 /* StyleFlexibleBoxData.h in Headers */ = {isa = PBXBuildFile; fileRef = BC5EB8B70E8201BD00B25965 /* StyleFlexibleBoxData.h */; settings = {ATTRIBUTES = (Private, ); }; };
BC5EB8C30E82031B00B25965 /* ShadowData.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BC5EB8C10E82031B00B25965 /* ShadowData.cpp */; };
BC5EB8C40E82031B00B25965 /* ShadowData.h in Headers */ = {isa = PBXBuildFile; fileRef = BC5EB8C20E82031B00B25965 /* ShadowData.h */; settings = {ATTRIBUTES = (Private, ); }; };
- BC5EB91F0E82040800B25965 /* BindingURI.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BC5EB91D0E82040800B25965 /* BindingURI.cpp */; };
- BC5EB9200E82040800B25965 /* BindingURI.h in Headers */ = {isa = PBXBuildFile; fileRef = BC5EB91E0E82040800B25965 /* BindingURI.h */; };
BC5EB9500E82056B00B25965 /* CounterDirectives.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BC5EB94E0E82056B00B25965 /* CounterDirectives.cpp */; };
BC5EB9510E82056B00B25965 /* CounterDirectives.h in Headers */ = {isa = PBXBuildFile; fileRef = BC5EB94F0E82056B00B25965 /* CounterDirectives.h */; settings = {ATTRIBUTES = (Private, ); }; };
BC5EB9790E82069200B25965 /* CounterContent.h in Headers */ = {isa = PBXBuildFile; fileRef = BC5EB9780E82069200B25965 /* CounterContent.h */; };
@@ -4832,8 +4845,6 @@
BCB16C220979C3BD00467741 /* CachedResourceClientWalker.h in Headers */ = {isa = PBXBuildFile; fileRef = BCB16C090979C3BD00467741 /* CachedResourceClientWalker.h */; };
BCB16C230979C3BD00467741 /* CachedScript.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BCB16C0A0979C3BD00467741 /* CachedScript.cpp */; };
BCB16C240979C3BD00467741 /* CachedScript.h in Headers */ = {isa = PBXBuildFile; fileRef = BCB16C0B0979C3BD00467741 /* CachedScript.h */; };
- BCB16C250979C3BD00467741 /* CachedXBLDocument.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BCB16C0C0979C3BD00467741 /* CachedXBLDocument.cpp */; };
- BCB16C260979C3BD00467741 /* CachedXBLDocument.h in Headers */ = {isa = PBXBuildFile; fileRef = BCB16C0D0979C3BD00467741 /* CachedXBLDocument.h */; };
BCB16C270979C3BD00467741 /* CachedXSLStyleSheet.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BCB16C0E0979C3BD00467741 /* CachedXSLStyleSheet.cpp */; };
BCB16C280979C3BD00467741 /* CachedXSLStyleSheet.h in Headers */ = {isa = PBXBuildFile; fileRef = BCB16C0F0979C3BD00467741 /* CachedXSLStyleSheet.h */; };
BCB16C290979C3BD00467741 /* DocLoader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BCB16C100979C3BD00467741 /* DocLoader.cpp */; };
@@ -5098,6 +5109,8 @@
C6D74AD509AA282E000B0A52 /* ModifySelectionListLevel.h in Headers */ = {isa = PBXBuildFile; fileRef = C6D74AD309AA282E000B0A52 /* ModifySelectionListLevel.h */; };
C6D74AE409AA290A000B0A52 /* ModifySelectionListLevel.cpp in Sources */ = {isa = PBXBuildFile; fileRef = C6D74AE309AA290A000B0A52 /* ModifySelectionListLevel.cpp */; };
CE02F0C411E83ADD00C6684A /* ScriptControllerBase.h in Headers */ = {isa = PBXBuildFile; fileRef = CE02F0C311E83ADD00C6684A /* ScriptControllerBase.h */; settings = {ATTRIBUTES = (Private, ); }; };
+ CE057FA51220731100A476D5 /* DocumentMarkerController.cpp in Sources */ = {isa = PBXBuildFile; fileRef = CE057FA31220731100A476D5 /* DocumentMarkerController.cpp */; };
+ CE057FA61220731100A476D5 /* DocumentMarkerController.h in Headers */ = {isa = PBXBuildFile; fileRef = CE057FA41220731100A476D5 /* DocumentMarkerController.h */; settings = {ATTRIBUTES = (Private, ); }; };
CE172E011136E8CE0062A533 /* ZoomMode.h in Headers */ = {isa = PBXBuildFile; fileRef = CE172E001136E8CE0062A533 /* ZoomMode.h */; settings = {ATTRIBUTES = (Private, ); }; };
CE4C00E410F6F7BA00CA38F5 /* HTMLNoScriptElement.cpp in Sources */ = {isa = PBXBuildFile; fileRef = CE4C00E310F6F7BA00CA38F5 /* HTMLNoScriptElement.cpp */; };
CE4C00E610F6F7C100CA38F5 /* HTMLNoScriptElement.h in Headers */ = {isa = PBXBuildFile; fileRef = CE4C00E510F6F7C100CA38F5 /* HTMLNoScriptElement.h */; };
@@ -5122,6 +5135,8 @@
D086FE9909D53AAB005BC74D /* UnlinkCommand.cpp in Sources */ = {isa = PBXBuildFile; fileRef = D086FE9709D53AAB005BC74D /* UnlinkCommand.cpp */; };
D0B0556809C6700100307E43 /* CreateLinkCommand.h in Headers */ = {isa = PBXBuildFile; fileRef = D0B0556609C6700100307E43 /* CreateLinkCommand.h */; };
D0B0556909C6700100307E43 /* CreateLinkCommand.cpp in Sources */ = {isa = PBXBuildFile; fileRef = D0B0556709C6700100307E43 /* CreateLinkCommand.cpp */; };
+ D0FF2A5D11F8C45A007E74E0 /* PingLoader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = D0FF2A5B11F8C45A007E74E0 /* PingLoader.cpp */; };
+ D0FF2A5E11F8C45A007E74E0 /* PingLoader.h in Headers */ = {isa = PBXBuildFile; fileRef = D0FF2A5C11F8C45A007E74E0 /* PingLoader.h */; };
D23CA55D0AB0EAAE005108A5 /* JSRangeException.h in Headers */ = {isa = PBXBuildFile; fileRef = D23CA55C0AB0EAAE005108A5 /* JSRangeException.h */; };
D23CA55F0AB0EAB6005108A5 /* JSRangeException.cpp in Sources */ = {isa = PBXBuildFile; fileRef = D23CA55E0AB0EAB6005108A5 /* JSRangeException.cpp */; };
D23CA56C0AB0EB8D005108A5 /* RangeException.h in Headers */ = {isa = PBXBuildFile; fileRef = D23CA56B0AB0EB8D005108A5 /* RangeException.h */; };
@@ -6516,6 +6531,8 @@
2EAFAF0B10E2AF2D007ED3D6 /* Blob.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Blob.cpp; sourceTree = "<group>"; };
2EAFAF0C10E2AF2D007ED3D6 /* Blob.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Blob.h; sourceTree = "<group>"; };
2EAFAF0D10E2AF2D007ED3D6 /* Blob.idl */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = Blob.idl; sourceTree = "<group>"; };
+ 2EB4BCD0121F03E300EC4885 /* BlobResourceHandle.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = BlobResourceHandle.cpp; sourceTree = "<group>"; };
+ 2EB4BCD1121F03E300EC4885 /* BlobResourceHandle.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BlobResourceHandle.h; sourceTree = "<group>"; };
2ECF7ADA10162B3800427DE7 /* JSErrorEvent.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSErrorEvent.cpp; sourceTree = "<group>"; };
2ECF7ADB10162B3800427DE7 /* JSErrorEvent.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSErrorEvent.h; sourceTree = "<group>"; };
2ECF7ADE10162B5800427DE7 /* ErrorEvent.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ErrorEvent.cpp; sourceTree = "<group>"; };
@@ -6533,6 +6550,10 @@
2EED575112109ED0007656BB /* BlobURL.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BlobURL.h; sourceTree = "<group>"; };
2EED57FB1214A9C2007656BB /* ThreadableBlobRegistry.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ThreadableBlobRegistry.cpp; sourceTree = "<group>"; };
2EED57FC1214A9C2007656BB /* ThreadableBlobRegistry.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ThreadableBlobRegistry.h; sourceTree = "<group>"; };
+ 2EF1BFE8121C9F4200C27627 /* FileStream.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = FileStream.cpp; sourceTree = "<group>"; };
+ 2EF1BFE9121C9F4200C27627 /* FileStream.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FileStream.h; sourceTree = "<group>"; };
+ 2EF1BFF6121CB0BD00C27627 /* AsyncFileStream.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AsyncFileStream.h; sourceTree = "<group>"; };
+ 2EF1BFF8121CB0CE00C27627 /* FileStreamClient.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FileStreamClient.h; sourceTree = "<group>"; };
31288E6E0E3005D6003619AE /* WebKitCSSKeyframeRule.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = WebKitCSSKeyframeRule.cpp; sourceTree = "<group>"; };
31288E6F0E3005D6003619AE /* WebKitCSSKeyframeRule.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WebKitCSSKeyframeRule.h; sourceTree = "<group>"; };
31288E700E3005D6003619AE /* WebKitCSSKeyframesRule.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = WebKitCSSKeyframesRule.cpp; sourceTree = "<group>"; };
@@ -6723,6 +6744,9 @@
4614A1FD0B23A8D600446E1C /* copyCursor.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = copyCursor.png; sourceTree = "<group>"; };
464EA2710B8A350B00A8E6E3 /* crossHairCursor.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = crossHairCursor.png; sourceTree = "<group>"; };
464EA2720B8A350B00A8E6E3 /* notAllowedCursor.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = notAllowedCursor.png; sourceTree = "<group>"; };
+ 46A26902121B6B4300C41F3A /* FileWriter.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = FileWriter.cpp; sourceTree = "<group>"; };
+ 46A26903121B6B4300C41F3A /* FileWriter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FileWriter.h; sourceTree = "<group>"; };
+ 46A26904121B6B4300C41F3A /* FileWriter.idl */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = FileWriter.idl; sourceTree = "<group>"; };
46BD16E20B279473001F0839 /* noneCursor.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = noneCursor.png; sourceTree = "<group>"; };
46D4F2460AF97E810035385A /* cellCursor.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = cellCursor.png; sourceTree = "<group>"; };
46D4F2470AF97E810035385A /* contextMenuCursor.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = contextMenuCursor.png; sourceTree = "<group>"; };
@@ -6930,8 +6954,8 @@
4F1534DF11B533020021FD86 /* EditingBehaviorTypes.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = EditingBehaviorTypes.h; sourceTree = "<group>"; };
4F3289B311A42AAB005ABE7E /* InspectorValues.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = InspectorValues.cpp; sourceTree = "<group>"; };
4F3289B411A42AAB005ABE7E /* InspectorValues.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = InspectorValues.h; sourceTree = "<group>"; };
- 4F4F5FFA11CBD2D200A186BF /* RemoteInspectorFrontend.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = RemoteInspectorFrontend.cpp; sourceTree = "<group>"; };
- 4F4F5FFC11CBD30100A186BF /* RemoteInspectorFrontend.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RemoteInspectorFrontend.h; sourceTree = "<group>"; };
+ 4F4F5FFA11CBD2D200A186BF /* InspectorFrontend.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = InspectorFrontend.cpp; sourceTree = "<group>"; };
+ 4F4F5FFC11CBD30100A186BF /* InspectorFrontend.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = InspectorFrontend.h; sourceTree = "<group>"; };
4F707A9711EF679400ACDA69 /* InspectorBackendDispatcher.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = InspectorBackendDispatcher.cpp; sourceTree = "<group>"; };
4F707A9811EF679400ACDA69 /* InspectorBackendDispatcher.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = InspectorBackendDispatcher.h; sourceTree = "<group>"; };
4FD8D0F0119C718B002FA825 /* ScriptGCEvent.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ScriptGCEvent.cpp; sourceTree = "<group>"; };
@@ -8222,14 +8246,17 @@
85FF31580AAFBFCB00374F38 /* DOMKeyboardEvent.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = DOMKeyboardEvent.h; sourceTree = "<group>"; };
85FF31590AAFBFCB00374F38 /* DOMKeyboardEvent.mm */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.objcpp; path = DOMKeyboardEvent.mm; sourceTree = "<group>"; };
86243D0011BC31F700CC006A /* JSArrayBufferViewHelper.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSArrayBufferViewHelper.h; sourceTree = "<group>"; };
+ 8947A82512222C4700D95F2D /* JSMetadata.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSMetadata.cpp; sourceTree = "<group>"; };
+ 8947A82612222C4700D95F2D /* JSMetadata.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSMetadata.h; sourceTree = "<group>"; };
+ 8947A82712222C4700D95F2D /* JSMetadataCallback.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSMetadataCallback.cpp; sourceTree = "<group>"; };
+ 8947A82812222C4700D95F2D /* JSMetadataCallback.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSMetadataCallback.h; sourceTree = "<group>"; };
8952535011641B3400CABF00 /* FileThread.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = FileThread.cpp; sourceTree = "<group>"; };
8952535111641B3400CABF00 /* FileThread.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FileThread.h; sourceTree = "<group>"; };
- 895253D4116C4C6800CABF00 /* FileStream.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = FileStream.cpp; sourceTree = "<group>"; };
- 895253D5116C4C6800CABF00 /* FileStream.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FileStream.h; sourceTree = "<group>"; };
- 895253D6116C4C6800CABF00 /* FileStreamClient.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FileStreamClient.h; sourceTree = "<group>"; };
895253DA116C4EF500CABF00 /* FileStreamProxy.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = FileStreamProxy.cpp; sourceTree = "<group>"; };
895253DB116C4EF500CABF00 /* FileStreamProxy.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FileStreamProxy.h; sourceTree = "<group>"; };
895253DE116C4F0600CABF00 /* FileThreadTask.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FileThreadTask.h; sourceTree = "<group>"; };
+ 89686C9D122244A00076EAA4 /* DOMFilePath.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = DOMFilePath.cpp; sourceTree = "<group>"; };
+ 89686C9E122244A00076EAA4 /* DOMFilePath.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DOMFilePath.h; sourceTree = "<group>"; };
897A2D1911FF58A50082740C /* DOMFileSystem.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = DOMFileSystem.cpp; sourceTree = "<group>"; };
897A2D1A11FF58A50082740C /* DOMFileSystem.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DOMFileSystem.h; sourceTree = "<group>"; };
897A2D1B11FF58A50082740C /* DOMFileSystem.idl */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = DOMFileSystem.idl; sourceTree = "<group>"; };
@@ -8290,6 +8317,8 @@
89B5EAA011E8003D00F2367E /* LineEnding.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LineEnding.h; sourceTree = "<group>"; };
89BED5E911BE11CE00448492 /* BlobBuilder.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = BlobBuilder.cpp; sourceTree = "<group>"; };
89BED5EA11BE11CE00448492 /* BlobBuilder.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BlobBuilder.h; sourceTree = "<group>"; };
+ 89C0DD78121F0C69009E17CA /* FileSystemCallbacks.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = FileSystemCallbacks.cpp; sourceTree = "<group>"; };
+ 89C0DD79121F0C69009E17CA /* FileSystemCallbacks.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FileSystemCallbacks.h; sourceTree = "<group>"; };
89CD027911C859A80070B791 /* BlobBuilder.idl */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = BlobBuilder.idl; sourceTree = "<group>"; };
89CD029111C85B870070B791 /* JSBlobBuilder.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSBlobBuilder.cpp; sourceTree = "<group>"; };
89CD029211C85B870070B791 /* JSBlobBuilder.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSBlobBuilder.h; sourceTree = "<group>"; };
@@ -8592,6 +8621,8 @@
97EF560E11E40783007E026F /* HTMLConstructionSite.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = HTMLConstructionSite.cpp; sourceTree = "<group>"; };
97EF560F11E40783007E026F /* HTMLConstructionSite.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = HTMLConstructionSite.h; sourceTree = "<group>"; };
97EF7DFD107E55B700D7C49C /* ScriptControllerBase.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ScriptControllerBase.cpp; sourceTree = "<group>"; };
+ 9F0D6B2C121BFEBA006C0288 /* InspectorProfilerAgent.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = InspectorProfilerAgent.cpp; sourceTree = "<group>"; };
+ 9F0D6B2D121BFEBA006C0288 /* InspectorProfilerAgent.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = InspectorProfilerAgent.h; sourceTree = "<group>"; };
9F6FC1941122E82A00E80196 /* ScriptDebugServer.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ScriptDebugServer.cpp; sourceTree = "<group>"; };
9F6FC1951122E82A00E80196 /* ScriptDebugServer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ScriptDebugServer.h; sourceTree = "<group>"; };
9F72304C11184B4100AD0126 /* ScriptProfile.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ScriptProfile.h; sourceTree = "<group>"; };
@@ -10412,8 +10443,6 @@
BC5EB8B70E8201BD00B25965 /* StyleFlexibleBoxData.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = StyleFlexibleBoxData.h; path = style/StyleFlexibleBoxData.h; sourceTree = "<group>"; };
BC5EB8C10E82031B00B25965 /* ShadowData.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = ShadowData.cpp; path = style/ShadowData.cpp; sourceTree = "<group>"; };
BC5EB8C20E82031B00B25965 /* ShadowData.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ShadowData.h; path = style/ShadowData.h; sourceTree = "<group>"; };
- BC5EB91D0E82040800B25965 /* BindingURI.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = BindingURI.cpp; path = style/BindingURI.cpp; sourceTree = "<group>"; };
- BC5EB91E0E82040800B25965 /* BindingURI.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = BindingURI.h; path = style/BindingURI.h; sourceTree = "<group>"; };
BC5EB94E0E82056B00B25965 /* CounterDirectives.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = CounterDirectives.cpp; path = style/CounterDirectives.cpp; sourceTree = "<group>"; };
BC5EB94F0E82056B00B25965 /* CounterDirectives.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = CounterDirectives.h; path = style/CounterDirectives.h; sourceTree = "<group>"; };
BC5EB9780E82069200B25965 /* CounterContent.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = CounterContent.h; path = style/CounterContent.h; sourceTree = "<group>"; };
@@ -10616,8 +10645,6 @@
BCB16C090979C3BD00467741 /* CachedResourceClientWalker.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = CachedResourceClientWalker.h; sourceTree = "<group>"; };
BCB16C0A0979C3BD00467741 /* CachedScript.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = CachedScript.cpp; sourceTree = "<group>"; };
BCB16C0B0979C3BD00467741 /* CachedScript.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = CachedScript.h; sourceTree = "<group>"; };
- BCB16C0C0979C3BD00467741 /* CachedXBLDocument.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = CachedXBLDocument.cpp; sourceTree = "<group>"; };
- BCB16C0D0979C3BD00467741 /* CachedXBLDocument.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = CachedXBLDocument.h; sourceTree = "<group>"; };
BCB16C0E0979C3BD00467741 /* CachedXSLStyleSheet.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = CachedXSLStyleSheet.cpp; sourceTree = "<group>"; };
BCB16C0F0979C3BD00467741 /* CachedXSLStyleSheet.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = CachedXSLStyleSheet.h; sourceTree = "<group>"; };
BCB16C100979C3BD00467741 /* DocLoader.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = DocLoader.cpp; sourceTree = "<group>"; };
@@ -10908,6 +10935,8 @@
C6D74AD309AA282E000B0A52 /* ModifySelectionListLevel.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ModifySelectionListLevel.h; sourceTree = "<group>"; };
C6D74AE309AA290A000B0A52 /* ModifySelectionListLevel.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ModifySelectionListLevel.cpp; sourceTree = "<group>"; };
CE02F0C311E83ADD00C6684A /* ScriptControllerBase.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ScriptControllerBase.h; sourceTree = "<group>"; };
+ CE057FA31220731100A476D5 /* DocumentMarkerController.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = DocumentMarkerController.cpp; sourceTree = "<group>"; };
+ CE057FA41220731100A476D5 /* DocumentMarkerController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DocumentMarkerController.h; sourceTree = "<group>"; };
CE172E001136E8CE0062A533 /* ZoomMode.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ZoomMode.h; sourceTree = "<group>"; };
CE4C00E310F6F7BA00CA38F5 /* HTMLNoScriptElement.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = HTMLNoScriptElement.cpp; sourceTree = "<group>"; };
CE4C00E510F6F7C100CA38F5 /* HTMLNoScriptElement.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = HTMLNoScriptElement.h; sourceTree = "<group>"; };
@@ -10932,6 +10961,8 @@
D086FE9709D53AAB005BC74D /* UnlinkCommand.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = UnlinkCommand.cpp; sourceTree = "<group>"; };
D0B0556609C6700100307E43 /* CreateLinkCommand.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CreateLinkCommand.h; sourceTree = "<group>"; };
D0B0556709C6700100307E43 /* CreateLinkCommand.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CreateLinkCommand.cpp; sourceTree = "<group>"; };
+ D0FF2A5B11F8C45A007E74E0 /* PingLoader.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = PingLoader.cpp; sourceTree = "<group>"; };
+ D0FF2A5C11F8C45A007E74E0 /* PingLoader.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PingLoader.h; sourceTree = "<group>"; };
D23CA5480AB0E983005108A5 /* RangeException.idl */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text; path = RangeException.idl; sourceTree = "<group>"; };
D23CA55C0AB0EAAE005108A5 /* JSRangeException.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = JSRangeException.h; sourceTree = "<group>"; };
D23CA55E0AB0EAB6005108A5 /* JSRangeException.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = JSRangeException.cpp; sourceTree = "<group>"; };
@@ -11128,8 +11159,6 @@
F523D23C02DE4396018635CA /* HTMLDocument.h */ = {isa = PBXFileReference; fileEncoding = 30; indentWidth = 4; lastKnownFileType = sourcecode.c.h; path = HTMLDocument.h; sourceTree = "<group>"; tabWidth = 8; usesTabs = 0; };
F523D23E02DE4396018635CA /* HTMLElement.cpp */ = {isa = PBXFileReference; fileEncoding = 30; indentWidth = 4; lastKnownFileType = sourcecode.cpp.cpp; path = HTMLElement.cpp; sourceTree = "<group>"; tabWidth = 8; usesTabs = 0; };
F523D23F02DE4396018635CA /* HTMLElement.h */ = {isa = PBXFileReference; fileEncoding = 30; indentWidth = 4; lastKnownFileType = sourcecode.c.h; path = HTMLElement.h; sourceTree = "<group>"; tabWidth = 8; usesTabs = 0; };
- F523D25002DE4396018635CA /* LegacyHTMLTreeBuilder.cpp */ = {isa = PBXFileReference; fileEncoding = 30; indentWidth = 4; lastKnownFileType = sourcecode.cpp.cpp; path = LegacyHTMLTreeBuilder.cpp; sourceTree = "<group>"; tabWidth = 8; usesTabs = 0; };
- F523D25102DE4396018635CA /* LegacyHTMLTreeBuilder.h */ = {isa = PBXFileReference; fileEncoding = 30; indentWidth = 4; lastKnownFileType = sourcecode.c.h; path = LegacyHTMLTreeBuilder.h; sourceTree = "<group>"; tabWidth = 8; usesTabs = 0; };
F523D27802DE43D7018635CA /* TextResourceDecoder.cpp */ = {isa = PBXFileReference; fileEncoding = 30; indentWidth = 4; lastKnownFileType = sourcecode.cpp.cpp; path = TextResourceDecoder.cpp; sourceTree = "<group>"; tabWidth = 8; usesTabs = 0; };
F523D27902DE43D7018635CA /* TextResourceDecoder.h */ = {isa = PBXFileReference; fileEncoding = 30; indentWidth = 4; lastKnownFileType = sourcecode.c.h; path = TextResourceDecoder.h; sourceTree = "<group>"; tabWidth = 8; usesTabs = 0; };
F523D30302DE4476018635CA /* Range.cpp */ = {isa = PBXFileReference; fileEncoding = 30; indentWidth = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Range.cpp; sourceTree = "<group>"; tabWidth = 8; usesTabs = 0; };
@@ -11569,6 +11598,8 @@
899ABC231215E4A300F9F219 /* DirectoryReader.cpp */,
899ABC241215E4A300F9F219 /* DirectoryReader.h */,
899ABC251215E4A300F9F219 /* DirectoryReader.idl */,
+ 89686C9D122244A00076EAA4 /* DOMFilePath.cpp */,
+ 89686C9E122244A00076EAA4 /* DOMFilePath.h */,
897A2D1911FF58A50082740C /* DOMFileSystem.cpp */,
897A2D1A11FF58A50082740C /* DOMFileSystem.h */,
897A2D1B11FF58A50082740C /* DOMFileSystem.idl */,
@@ -11589,6 +11620,8 @@
899ABC331215E4BE00F9F219 /* FileEntry.idl */,
897A2D2111FF58A50082740C /* FileSystemCallback.h */,
897A2D5F120001220082740C /* FileSystemCallback.idl */,
+ 89C0DD78121F0C69009E17CA /* FileSystemCallbacks.cpp */,
+ 89C0DD79121F0C69009E17CA /* FileSystemCallbacks.h */,
897A2D60120001220082740C /* Flags.h */,
897A2D61120001220082740C /* Flags.idl */,
C585A69811D4FB3D004C3E4B /* IDBAny.cpp */,
@@ -11732,6 +11765,8 @@
children = (
4F707A9711EF679400ACDA69 /* InspectorBackendDispatcher.cpp */,
4F707A9811EF679400ACDA69 /* InspectorBackendDispatcher.h */,
+ 4F4F5FFA11CBD2D200A186BF /* InspectorFrontend.cpp */,
+ 4F4F5FFC11CBD30100A186BF /* InspectorFrontend.h */,
7A0E76D810BF059800A0276E /* JSInjectedScriptHost.cpp */,
7A0E76D910BF059800A0276E /* JSInjectedScriptHost.h */,
7A0E771C10C00DB100A0276E /* JSInspectorFrontendHost.cpp */,
@@ -11742,8 +11777,6 @@
9FA37EF71172FD9300C4CD55 /* JSScriptProfile.h */,
9FA37EF81172FD9300C4CD55 /* JSScriptProfileNode.cpp */,
9FA37EF91172FD9300C4CD55 /* JSScriptProfileNode.h */,
- 4F4F5FFA11CBD2D200A186BF /* RemoteInspectorFrontend.cpp */,
- 4F4F5FFC11CBD30100A186BF /* RemoteInspectorFrontend.h */,
);
name = Inspector;
sourceTree = "<group>";
@@ -11782,6 +11815,8 @@
7A0E770B10C00A8800A0276E /* InspectorFrontendHost.cpp */,
7A0E770C10C00A8800A0276E /* InspectorFrontendHost.h */,
7A0E770D10C00A8800A0276E /* InspectorFrontendHost.idl */,
+ 9F0D6B2C121BFEBA006C0288 /* InspectorProfilerAgent.cpp */,
+ 9F0D6B2D121BFEBA006C0288 /* InspectorProfilerAgent.h */,
41F062000F5F0B6600A07EAC /* InspectorResource.cpp */,
41F061FF0F5F0B6600A07EAC /* InspectorResource.h */,
7AB0B1BE1211A62200A76940 /* InspectorStorageAgent.cpp */,
@@ -12445,6 +12480,8 @@
2EDEF1EF121B0EFC00726DB2 /* BlobRegistry.h */,
2EDEF1F0121B0EFC00726DB2 /* BlobRegistryImpl.cpp */,
2EDEF1F1121B0EFC00726DB2 /* BlobRegistryImpl.h */,
+ 2EB4BCD0121F03E300EC4885 /* BlobResourceHandle.cpp */,
+ 2EB4BCD1121F03E300EC4885 /* BlobResourceHandle.h */,
2EDEF1F2121B0EFC00726DB2 /* BlobStorageData.h */,
514C76580CE923A1007EF3CD /* Credential.cpp */,
514C76590CE923A1007EF3CD /* Credential.h */,
@@ -14009,14 +14046,14 @@
2E94F3CB118B908E00B7F75D /* FileReader.cpp */,
2E94F3CC118B908E00B7F75D /* FileReader.h */,
2E94F427119205B300B7F75D /* FileReader.idl */,
- 895253D4116C4C6800CABF00 /* FileStream.cpp */,
- 895253D5116C4C6800CABF00 /* FileStream.h */,
- 895253D6116C4C6800CABF00 /* FileStreamClient.h */,
895253DA116C4EF500CABF00 /* FileStreamProxy.cpp */,
895253DB116C4EF500CABF00 /* FileStreamProxy.h */,
8952535011641B3400CABF00 /* FileThread.cpp */,
8952535111641B3400CABF00 /* FileThread.h */,
895253DE116C4F0600CABF00 /* FileThreadTask.h */,
+ 46A26902121B6B4300C41F3A /* FileWriter.cpp */,
+ 46A26903121B6B4300C41F3A /* FileWriter.h */,
+ 46A26904121B6B4300C41F3A /* FileWriter.idl */,
A8136D370973A8E700D74463 /* FormDataList.cpp */,
A8136D360973A8E700D74463 /* FormDataList.h */,
BC97E239109144950010D361 /* HTMLAllCollection.cpp */,
@@ -14302,8 +14339,6 @@
B0149E7C11A4B21500196A7B /* ImageResizerThread.h */,
A456FA2411AD4A830020B420 /* LabelsNodeList.cpp */,
A456FA2511AD4A830020B420 /* LabelsNodeList.h */,
- F523D25002DE4396018635CA /* LegacyHTMLTreeBuilder.cpp */,
- F523D25102DE4396018635CA /* LegacyHTMLTreeBuilder.h */,
E446139B0CD6331000FADA75 /* MediaError.h */,
E446139C0CD6331000FADA75 /* MediaError.idl */,
A5AFB34D115151A700B045CB /* StepRange.cpp */,
@@ -15123,6 +15158,10 @@
C585A67B11D4FB07004C3E4B /* JSIDBSuccessEvent.h */,
B656626F120B1227006EA85C /* JSIDBTransaction.cpp */,
B656626E120B1227006EA85C /* JSIDBTransaction.h */,
+ 8947A82512222C4700D95F2D /* JSMetadata.cpp */,
+ 8947A82612222C4700D95F2D /* JSMetadata.h */,
+ 8947A82712222C4700D95F2D /* JSMetadataCallback.cpp */,
+ 8947A82812222C4700D95F2D /* JSMetadataCallback.h */,
514C76350CE9225E007EF3CD /* JSSQLError.cpp */,
BC8243250D0CE8A200460C8F /* JSSQLError.h */,
B525A96411CA2340003A23A8 /* JSSQLException.cpp */,
@@ -16266,8 +16305,6 @@
BC8C8FAA0DDCD2F200B592F4 /* style */ = {
isa = PBXGroup;
children = (
- BC5EB91D0E82040800B25965 /* BindingURI.cpp */,
- BC5EB91E0E82040800B25965 /* BindingURI.h */,
BC5EB5E00E81BE8700B25965 /* BorderData.h */,
BC5EB5DA0E81B7EA00B25965 /* BorderValue.h */,
BC5EB5DE0E81B9AB00B25965 /* CollapsedBorderValue.h */,
@@ -16414,8 +16451,6 @@
E472053A0E5A053A0006BB4D /* CachedResourceHandle.h */,
BCB16C0A0979C3BD00467741 /* CachedScript.cpp */,
BCB16C0B0979C3BD00467741 /* CachedScript.h */,
- BCB16C0C0979C3BD00467741 /* CachedXBLDocument.cpp */,
- BCB16C0D0979C3BD00467741 /* CachedXBLDocument.h */,
BCB16C0E0979C3BD00467741 /* CachedXSLStyleSheet.cpp */,
BCB16C0F0979C3BD00467741 /* CachedXSLStyleSheet.h */,
F587864902DE3A9A01EA4122 /* CachePolicy.h */,
@@ -16463,6 +16498,8 @@
93CCF0260AF6C52900018E89 /* NavigationAction.h */,
93E227DD0AF589AD00D48324 /* NetscapePlugInStreamLoader.cpp */,
656D372B0ADBA5DE00A4554D /* NetscapePlugInStreamLoader.h */,
+ D0FF2A5B11F8C45A007E74E0 /* PingLoader.cpp */,
+ D0FF2A5C11F8C45A007E74E0 /* PingLoader.h */,
377C4CDE1014E9F600B9AE42 /* PlaceholderDocument.cpp */,
377C4CDD1014E9F600B9AE42 /* PlaceholderDocument.h */,
1AC694C50A3B1676003F5049 /* PluginDocument.cpp */,
@@ -16569,6 +16606,7 @@
B2C3D9EC0D006C1D00EF6F26 /* text */,
BCFB2F74097A2E1A00BA703D /* Arena.cpp */,
BCFB2F75097A2E1A00BA703D /* Arena.h */,
+ 2EF1BFF6121CB0BD00C27627 /* AsyncFileStream.h */,
51E1ECB10C91C55600DC255B /* AutodrainedPool.h */,
8988E10C11A3508B00DB732E /* BlobItem.cpp */,
8988E10D11A3508B00DB732E /* BlobItem.h */,
@@ -16594,6 +16632,9 @@
1CA19E150DC255CA0065A994 /* EventLoop.h */,
934FE9E40B5CA539003E4A73 /* FileChooser.cpp */,
066C772A0AB603B700238CC4 /* FileChooser.h */,
+ 2EF1BFE8121C9F4200C27627 /* FileStream.cpp */,
+ 2EF1BFE9121C9F4200C27627 /* FileStream.h */,
+ 2EF1BFF8121CB0CE00C27627 /* FileStreamClient.h */,
C57FEDE01212EE9C0097BE65 /* FileSystem.cpp */,
514B3F720C722047000530DF /* FileSystem.h */,
BC073BA90C399B1F000F5979 /* FloatConversion.h */,
@@ -17356,6 +17397,8 @@
A8185F3509765765005826D9 /* DocumentFragment.h */,
1A494ED50A123F1A00FDAFC1 /* DocumentFragment.idl */,
ED2BA83B09A24B91006C0AC4 /* DocumentMarker.h */,
+ CE057FA31220731100A476D5 /* DocumentMarkerController.cpp */,
+ CE057FA41220731100A476D5 /* DocumentMarkerController.h */,
A8C2280D11D4A59700D5A7D3 /* DocumentParser.cpp */,
BCCFBAE70B5152ED0001F1D7 /* DocumentParser.h */,
A8185F3209765765005826D9 /* DocumentType.cpp */,
@@ -17675,7 +17718,6 @@
B2C3DA250D006C1D00EF6F26 /* BidiResolver.h in Headers */,
BCE789861120E7A60060ECE5 /* BidiRun.h in Headers */,
938192050F87E1EC00D5352A /* BinaryPropertyList.h in Headers */,
- BC5EB9200E82040800B25965 /* BindingURI.h in Headers */,
A89943280B42338800D7C802 /* BitmapImage.h in Headers */,
2EAFAF0F10E2AF2D007ED3D6 /* Blob.h in Headers */,
89BED5EC11BE11CE00448492 /* BlobBuilder.h in Headers */,
@@ -17705,7 +17747,6 @@
E47B4BE80E71241600038854 /* CachedResourceHandle.h in Headers */,
BCB16C240979C3BD00467741 /* CachedScript.h in Headers */,
BCD533640ED6848900887468 /* CachedScriptSourceProvider.h in Headers */,
- BCB16C260979C3BD00467741 /* CachedXBLDocument.h in Headers */,
BCB16C280979C3BD00467741 /* CachedXSLStyleSheet.h in Headers */,
93F1995008245E59001E9ABC /* CachePolicy.h in Headers */,
6E4E91AD10F7FB3100A2779C /* CanvasContextAttributes.h in Headers */,
@@ -18673,8 +18714,6 @@
2E3BC0BD117D3A4F00B9409A /* FileError.h in Headers */,
BCDBB8AC0E088CA500C60FF6 /* FileList.h in Headers */,
2E94F4511192096A00B7F75D /* FileReader.h in Headers */,
- 895253D8116C4C6800CABF00 /* FileStream.h in Headers */,
- 895253D9116C4C6800CABF00 /* FileStreamClient.h in Headers */,
895253DD116C4EF500CABF00 /* FileStreamProxy.h in Headers */,
514B3F730C722047000530DF /* FileSystem.h in Headers */,
8952535311641B3400CABF00 /* FileThread.h in Headers */,
@@ -19413,7 +19452,6 @@
A456FA2711AD4A830020B420 /* LabelsNodeList.h in Headers */,
85EC9AFB0A71A2C600EEEAED /* Language.h in Headers */,
2D9066070BE141D400956998 /* LayoutState.h in Headers */,
- 93F198EF08245E59001E9ABC /* LegacyHTMLTreeBuilder.h in Headers */,
512DD8F50D91E6AF000F89EE /* LegacyWebArchive.h in Headers */,
BCE65BEB0EACDF16007E4533 /* Length.h in Headers */,
BCFF64910EAD15C200C1D6F7 /* LengthBox.h in Headers */,
@@ -20291,6 +20329,7 @@
E1BE512E0CF6C512002EA959 /* XSLTUnicodeSort.h in Headers */,
97DD4D870FDF4D6E00ECF9A4 /* XSSAuditor.h in Headers */,
CE172E011136E8CE0062A533 /* ZoomMode.h in Headers */,
+ D0FF2A5E11F8C45A007E74E0 /* PingLoader.h in Headers */,
C50B561712119D23008B46E0 /* GroupSettings.h in Headers */,
BCA979171215D055005C485C /* ImageBufferData.h in Headers */,
490707E71219C04300D90E51 /* ANGLEWebKitBridge.h in Headers */,
@@ -20320,6 +20359,19 @@
2EDEF1F5121B0EFC00726DB2 /* BlobRegistry.h in Headers */,
2EDEF1F7121B0EFC00726DB2 /* BlobRegistryImpl.h in Headers */,
2EDEF1F8121B0EFC00726DB2 /* BlobStorageData.h in Headers */,
+ 2EF1BFEB121C9F4200C27627 /* FileStream.h in Headers */,
+ 46A26906121B6B4300C41F3A /* FileWriter.h in Headers */,
+ 2EF1BFF7121CB0BD00C27627 /* AsyncFileStream.h in Headers */,
+ 2EF1BFF9121CB0CE00C27627 /* FileStreamClient.h in Headers */,
+ 89C0DD7B121F0C69009E17CA /* FileSystemCallbacks.h in Headers */,
+ CE057FA61220731100A476D5 /* DocumentMarkerController.h in Headers */,
+ 9F0D6B2F121BFEBA006C0288 /* InspectorProfilerAgent.h in Headers */,
+ 2EB4BCD3121F03E300EC4885 /* BlobResourceHandle.h in Headers */,
+ 89686CA0122244A00076EAA4 /* DOMFilePath.h in Headers */,
+ 8947A82A12222C4700D95F2D /* JSMetadata.h in Headers */,
+ 8947A82C12222C4700D95F2D /* JSMetadataCallback.h in Headers */,
+ 8947A83C122234F400D95F2D /* Metadata.h in Headers */,
+ 8947A83D122234F900D95F2D /* MetadataCallback.h in Headers */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@@ -20379,7 +20431,6 @@
isa = PBXProject;
buildConfigurationList = 149C284308902B11008A9EFC /* Build configuration list for PBXProject "WebCore" */;
compatibilityVersion = "Xcode 2.4";
- developmentRegion = English;
hasScannedForEncodings = 1;
knownRegions = (
English,
@@ -20473,6 +20524,7 @@
);
inputPaths = (
"$(SRCROOT)/inspector/front-end",
+ "${BUILT_PRODUCTS_DIR}/DerivedSources/WebCore/InspectorBackendStub.js",
);
name = "Copy Inspector Resources";
outputPaths = (
@@ -20480,7 +20532,7 @@
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
- shellScript = "# Copy all the Inspector front-end resources.\nditto \"${SRCROOT}/inspector/front-end\" \"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/inspector\"\nditto \"${BUILT_PRODUCTS_DIR}/DerivedSources/WebCore/InspectorBackendStub.js\" \"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/inspector\"\n\n# Remove the WebKit.qrc file since it is not used on the Mac (this file is for Qt)\nrm -f \"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/inspector/WebKit.qrc\"\n\n# Remove *.re2js files, they are only used to generate some .js files.\nrm -f \"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/inspector/\"*.re2js\n";
+ shellScript = "# Copy all the Inspector front-end resources.\nditto \"${SRCROOT}/inspector/front-end\" \"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/inspector\"\nditto \"${BUILT_PRODUCTS_DIR}/DerivedSources/WebCore/InspectorBackendStub.js\" \"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/inspector\"\n\n# Remove the WebKit.qrc file since it is not used on the Mac (this file is for Qt).\nrm -f \"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/inspector/WebKit.qrc\"\n\n# Remove *.re2js files, they are only used to generate some .js files.\nrm -f \"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/inspector/\"*.re2js\n\n# Remove any .svn directories that may have been copied over.\nfind \"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/inspector\" -name \".svn\" -type d | xargs rm -rf\n";
};
5D0D540D0E9862F60029E223 /* Check For Weak VTables and Externals */ = {
isa = PBXShellScriptBuildPhase;
@@ -20682,7 +20734,6 @@
B2C3DA230D006C1D00EF6F26 /* BidiContext.cpp in Sources */,
BCE7898B1120E8020060ECE5 /* BidiRun.cpp in Sources */,
938192030F87E1E600D5352A /* BinaryPropertyList.cpp in Sources */,
- BC5EB91F0E82040800B25965 /* BindingURI.cpp in Sources */,
A89943290B42338800D7C802 /* BitmapImage.cpp in Sources */,
2EAFAF0E10E2AF2D007ED3D6 /* Blob.cpp in Sources */,
89BED5EB11BE11CE00448492 /* BlobBuilder.cpp in Sources */,
@@ -20706,7 +20757,6 @@
BCB16C210979C3BD00467741 /* CachedResourceClientWalker.cpp in Sources */,
E47B4BE90E71241600038854 /* CachedResourceHandle.cpp in Sources */,
BCB16C230979C3BD00467741 /* CachedScript.cpp in Sources */,
- BCB16C250979C3BD00467741 /* CachedXBLDocument.cpp in Sources */,
BCB16C270979C3BD00467741 /* CachedXSLStyleSheet.cpp in Sources */,
6E4E91AC10F7FB3100A2779C /* CanvasContextAttributes.cpp in Sources */,
49484FC1102CF23C00187DD3 /* CanvasGradient.cpp in Sources */,
@@ -21175,7 +21225,6 @@
066C772D0AB603D200238CC4 /* FileChooserMac.mm in Sources */,
BCDBB8AD0E088CA500C60FF6 /* FileList.cpp in Sources */,
2E94F4501192096400B7F75D /* FileReader.cpp in Sources */,
- 895253D7116C4C6800CABF00 /* FileStream.cpp in Sources */,
895253DC116C4EF500CABF00 /* FileStreamProxy.cpp in Sources */,
5160306C0CC4362300C8AC25 /* FileSystemCF.cpp in Sources */,
514B3F760C722055000530DF /* FileSystemMac.mm in Sources */,
@@ -21418,6 +21467,7 @@
F33F053D120B0DA500E5743A /* InspectorDebuggerAgent.cpp in Sources */,
7A24587B1021EAF4000A00AA /* InspectorDOMAgent.cpp in Sources */,
41F061750F5F00AC00A07EAC /* InspectorDOMStorageResource.cpp in Sources */,
+ 4F4F5FFB11CBD2E100A186BF /* InspectorFrontend.cpp in Sources */,
F344C75811294FF600F26EEE /* InspectorFrontendClientLocal.cpp in Sources */,
7A0E770E10C00A8800A0276E /* InspectorFrontendHost.cpp in Sources */,
41F062020F5F0B6600A07EAC /* InspectorResource.cpp in Sources */,
@@ -21983,7 +22033,6 @@
A456FA2611AD4A830020B420 /* LabelsNodeList.cpp in Sources */,
9352084509BD43B900F2038D /* Language.mm in Sources */,
2D9066060BE141D400956998 /* LayoutState.cpp in Sources */,
- 93F19A9B08245E59001E9ABC /* LegacyHTMLTreeBuilder.cpp in Sources */,
512DD8F40D91E6AF000F89EE /* LegacyWebArchive.cpp in Sources */,
51B2417B0D931F3F00E83F5C /* LegacyWebArchiveMac.mm in Sources */,
BCE65BEA0EACDF16007E4533 /* Length.cpp in Sources */,
@@ -22112,7 +22161,6 @@
979F43D31075E44A0000F83B /* RedirectScheduler.cpp in Sources */,
85031B4B0A44EFC700F992E0 /* RegisteredEventListener.cpp in Sources */,
B2C3DA2C0D006C1D00EF6F26 /* RegularExpression.cpp in Sources */,
- 4F4F5FFB11CBD2E100A186BF /* RemoteInspectorFrontend.cpp in Sources */,
93309E00099E64920056E581 /* RemoveCSSPropertyCommand.cpp in Sources */,
D06C0D900CFD11460065F43F /* RemoveFormatCommand.cpp in Sources */,
93309E04099E64920056E581 /* RemoveNodeCommand.cpp in Sources */,
@@ -22749,6 +22797,7 @@
93F19B0508245E59001E9ABC /* XSLTProcessorLibxslt.cpp in Sources */,
E1BE512D0CF6C512002EA959 /* XSLTUnicodeSort.cpp in Sources */,
97DD4D860FDF4D6E00ECF9A4 /* XSSAuditor.cpp in Sources */,
+ D0FF2A5D11F8C45A007E74E0 /* PingLoader.cpp in Sources */,
C50B561612119D23008B46E0 /* GroupSettings.cpp in Sources */,
490707E61219C04300D90E51 /* ANGLEWebKitBridge.cpp in Sources */,
899ABC261215E4A300F9F219 /* DirectoryEntry.cpp in Sources */,
@@ -22771,6 +22820,15 @@
C57FEDE11212EE9C0097BE65 /* FileSystem.cpp in Sources */,
2EDEF1F3121B0EFC00726DB2 /* BlobData.cpp in Sources */,
2EDEF1F6121B0EFC00726DB2 /* BlobRegistryImpl.cpp in Sources */,
+ 2EF1BFEA121C9F4200C27627 /* FileStream.cpp in Sources */,
+ 46A26905121B6B4300C41F3A /* FileWriter.cpp in Sources */,
+ 89C0DD7A121F0C69009E17CA /* FileSystemCallbacks.cpp in Sources */,
+ CE057FA51220731100A476D5 /* DocumentMarkerController.cpp in Sources */,
+ 9F0D6B2E121BFEBA006C0288 /* InspectorProfilerAgent.cpp in Sources */,
+ 2EB4BCD2121F03E300EC4885 /* BlobResourceHandle.cpp in Sources */,
+ 89686C9F122244A00076EAA4 /* DOMFilePath.cpp in Sources */,
+ 8947A82912222C4700D95F2D /* JSMetadata.cpp in Sources */,
+ 8947A82B12222C4700D95F2D /* JSMetadataCallback.cpp in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
diff --git a/WebCore/accessibility/AccessibilityRenderObject.cpp b/WebCore/accessibility/AccessibilityRenderObject.cpp
index 6b90b63..92c57c6 100644
--- a/WebCore/accessibility/AccessibilityRenderObject.cpp
+++ b/WebCore/accessibility/AccessibilityRenderObject.cpp
@@ -370,9 +370,12 @@ AccessibilityObject* AccessibilityRenderObject::nextSibling() const
static RenderBoxModelObject* nextContinuation(RenderObject* renderer)
{
- if (renderer->isInline() && !renderer->isReplaced())
+ ASSERT(renderer);
+ if (renderer->isRenderInline() && !renderer->isReplaced())
return toRenderInline(renderer)->continuation();
- return toRenderBlock(renderer)->inlineElementContinuation();
+ if (renderer->isRenderBlock())
+ return toRenderBlock(renderer)->inlineElementContinuation();
+ return 0;
}
RenderObject* AccessibilityRenderObject::renderParentObject() const
diff --git a/WebCore/bindings/gobject/WebKitHTMLElementWrapperFactory.cpp b/WebCore/bindings/gobject/WebKitHTMLElementWrapperFactory.cpp
index 4c57946..da420ae 100644
--- a/WebCore/bindings/gobject/WebKitHTMLElementWrapperFactory.cpp
+++ b/WebCore/bindings/gobject/WebKitHTMLElementWrapperFactory.cpp
@@ -96,7 +96,6 @@
#include "webkit/WebKitDOMHTMLAnchorElementPrivate.h"
#include "webkit/WebKitDOMHTMLAppletElementPrivate.h"
#include "webkit/WebKitDOMHTMLAreaElementPrivate.h"
-#include "webkit/WebKitDOMHTMLAudioElementPrivate.h"
#include "webkit/WebKitDOMHTMLBRElementPrivate.h"
#include "webkit/WebKitDOMHTMLBaseElementPrivate.h"
#include "webkit/WebKitDOMHTMLBaseFontElementPrivate.h"
@@ -153,6 +152,10 @@
#include "webkit/WebKitDOMHTMLUListElementPrivate.h"
#include "webkit/webkitdom.h"
+#if ENABLE(VIDEO)
+#include "webkit/WebKitDOMHTMLAudioElementPrivate.h"
+#endif
+
#include <wtf/text/CString.h>
namespace WebKit {
@@ -177,10 +180,12 @@ static gpointer createAreaWrapper(PassRefPtr<HTMLElement> element)
return wrapHTMLAreaElement(static_cast<HTMLAreaElement*>(element.get()));
}
+#if ENABLE(VIDEO)
static gpointer createAudioWrapper(PassRefPtr<HTMLElement> element)
{
return wrapHTMLAudioElement(static_cast<HTMLAudioElement*>(element.get()));
}
+#endif
static gpointer createBaseWrapper(PassRefPtr<HTMLElement> element)
{
@@ -453,7 +458,9 @@ gpointer createHTMLElementWrapper(PassRefPtr<WebCore::HTMLElement> element)
if (map.isEmpty()) {
map.set(aTag.localName().impl(), createAnchorWrapper);
map.set(appletTag.localName().impl(), createAppletWrapper);
+#if ENABLE(VIDEO)
map.set(audioTag.localName().impl(), createAudioWrapper);
+#endif
map.set(areaTag.localName().impl(), createAreaWrapper);
map.set(baseTag.localName().impl(), createBaseWrapper);
map.set(basefontTag.localName().impl(), createBaseFontWrapper);
diff --git a/WebCore/bindings/js/JSInjectedScriptHostCustom.cpp b/WebCore/bindings/js/JSInjectedScriptHostCustom.cpp
index 06360fb..ac5225e 100644
--- a/WebCore/bindings/js/JSInjectedScriptHostCustom.cpp
+++ b/WebCore/bindings/js/JSInjectedScriptHostCustom.cpp
@@ -103,6 +103,12 @@ ScriptObject InjectedScriptHost::createInjectedScript(const String& source, Scri
return ScriptObject();
}
+void InjectedScriptHost::discardInjectedScript(ScriptState* scriptState)
+{
+ JSDOMGlobalObject* globalObject = static_cast<JSDOMGlobalObject*>(scriptState->lexicalGlobalObject());
+ globalObject->setInjectedScript(0);
+}
+
#if ENABLE(JAVASCRIPT_DEBUGGER)
JSValue JSInjectedScriptHost::currentCallFrame(ExecState* exec)
{
diff --git a/WebCore/bindings/js/JSInspectorFrontendHostCustom.cpp b/WebCore/bindings/js/JSInspectorFrontendHostCustom.cpp
index b724f50..1df1af0 100644
--- a/WebCore/bindings/js/JSInspectorFrontendHostCustom.cpp
+++ b/WebCore/bindings/js/JSInspectorFrontendHostCustom.cpp
@@ -40,6 +40,7 @@
#include "InspectorFrontendHost.h"
#include "JSEvent.h"
#include "MouseEvent.h"
+#include "PlatformString.h"
#include <runtime/JSArray.h>
#include <runtime/JSLock.h>
#include <runtime/JSObject.h>
@@ -90,14 +91,26 @@ JSValue JSInspectorFrontendHost::showContextMenu(ExecState* exec)
for (size_t i = 0; i < array->length(); ++i) {
JSObject* item = asObject(array->getIndex(i));
JSValue label = item->get(exec, Identifier(exec, "label"));
+ JSValue type = item->get(exec, Identifier(exec, "type"));
JSValue id = item->get(exec, Identifier(exec, "id"));
- if (label.isUndefined() || id.isUndefined())
+ JSValue enabled = item->get(exec, Identifier(exec, "enabled"));
+ JSValue checked = item->get(exec, Identifier(exec, "checked"));
+ if (!type.isString())
+ continue;
+
+ String typeString = ustringToString(type.toString(exec));
+ if (typeString == "separator") {
items.append(new ContextMenuItem(SeparatorType,
ContextMenuItemCustomTagNoAction,
String()));
- else {
+ } else {
ContextMenuAction typedId = static_cast<ContextMenuAction>(ContextMenuItemBaseCustomTag + id.toInt32(exec));
- items.append(new ContextMenuItem(ActionType, typedId, ustringToString(label.toString(exec))));
+ ContextMenuItem* menuItem = new ContextMenuItem((typeString == "checkbox" ? CheckableActionType : ActionType), typedId, ustringToString(label.toString(exec)));
+ if (!enabled.isUndefined())
+ menuItem->setEnabled(enabled.toBoolean(exec));
+ if (!checked.isUndefined())
+ menuItem->setChecked(checked.toBoolean(exec));
+ items.append(menuItem);
}
}
diff --git a/WebCore/bindings/js/JSNodeFilterCondition.cpp b/WebCore/bindings/js/JSNodeFilterCondition.cpp
index b723286..b269e5f 100644
--- a/WebCore/bindings/js/JSNodeFilterCondition.cpp
+++ b/WebCore/bindings/js/JSNodeFilterCondition.cpp
@@ -23,6 +23,7 @@
#include "JSNode.h"
#include "JSNodeFilter.h"
#include "NodeFilter.h"
+#include <runtime/Error.h>
#include <runtime/JSLock.h>
namespace WebCore {
@@ -45,9 +46,7 @@ short JSNodeFilterCondition::acceptNode(JSC::ExecState* exec, Node* filterNode)
{
JSLock lock(SilenceAssertionsOnly);
- CallData callData;
- CallType callType = getCallData(m_filter, callData);
- if (callType == CallTypeNone)
+ if (!m_filter.isObject())
return NodeFilter::FILTER_ACCEPT;
// The exec argument here should only be null if this was called from a
@@ -59,6 +58,18 @@ short JSNodeFilterCondition::acceptNode(JSC::ExecState* exec, Node* filterNode)
if (!exec)
return NodeFilter::FILTER_REJECT;
+ JSValue function = m_filter;
+ CallData callData;
+ CallType callType = getCallData(function, callData);
+ if (callType == CallTypeNone) {
+ function = m_filter.get(exec, Identifier(exec, "acceptNode"));
+ callType = getCallData(function, callData);
+ if (callType == CallTypeNone) {
+ throwError(exec, createTypeError(exec, "NodeFilter object does not have an acceptNode function"));
+ return NodeFilter::FILTER_REJECT;
+ }
+ }
+
MarkedArgumentBuffer args;
// FIXME: The node should have the prototype chain that came from its document, not
// whatever prototype chain might be on the window this filter came from. Bug 27662
@@ -66,7 +77,7 @@ short JSNodeFilterCondition::acceptNode(JSC::ExecState* exec, Node* filterNode)
if (exec->hadException())
return NodeFilter::FILTER_REJECT;
- JSValue result = JSC::call(exec, m_filter, callType, callData, m_filter, args);
+ JSValue result = JSC::call(exec, function, callType, callData, m_filter, args);
if (exec->hadException())
return NodeFilter::FILTER_REJECT;
diff --git a/WebCore/bindings/js/JSWebGLRenderingContextCustom.cpp b/WebCore/bindings/js/JSWebGLRenderingContextCustom.cpp
index 0342ab6..4b31659 100644
--- a/WebCore/bindings/js/JSWebGLRenderingContextCustom.cpp
+++ b/WebCore/bindings/js/JSWebGLRenderingContextCustom.cpp
@@ -167,6 +167,8 @@ JSValue JSWebGLRenderingContext::getAttachedShaders(ExecState* exec)
return throwSyntaxError(exec);
ExceptionCode ec = 0;
WebGLRenderingContext* context = static_cast<WebGLRenderingContext*>(impl());
+ if (exec->argumentCount() > 0 && !exec->argument(0).isUndefinedOrNull() && !exec->argument(0).inherits(&JSWebGLProgram::s_info))
+ return throwTypeError(exec);
WebGLProgram* program = toWebGLProgram(exec->argument(0));
if (exec->hadException())
return jsUndefined();
@@ -238,6 +240,8 @@ JSValue JSWebGLRenderingContext::getProgramParameter(ExecState* exec)
ExceptionCode ec = 0;
WebGLRenderingContext* context = static_cast<WebGLRenderingContext*>(impl());
+ if (exec->argumentCount() > 0 && !exec->argument(0).isUndefinedOrNull() && !exec->argument(0).inherits(&JSWebGLProgram::s_info))
+ return throwTypeError(exec);
WebGLProgram* program = toWebGLProgram(exec->argument(0));
unsigned pname = exec->argument(1).toInt32(exec);
if (exec->hadException())
@@ -262,6 +266,8 @@ JSValue JSWebGLRenderingContext::getShaderParameter(ExecState* exec)
ExceptionCode ec = 0;
WebGLRenderingContext* context = static_cast<WebGLRenderingContext*>(impl());
+ if (exec->argumentCount() > 0 && !exec->argument(0).isUndefinedOrNull() && !exec->argument(0).inherits(&JSWebGLShader::s_info))
+ return throwTypeError(exec);
WebGLShader* shader = toWebGLShader(exec->argument(0));
unsigned pname = exec->argument(1).toInt32(exec);
if (exec->hadException())
@@ -286,7 +292,11 @@ JSValue JSWebGLRenderingContext::getUniform(ExecState* exec)
ExceptionCode ec = 0;
WebGLRenderingContext* context = static_cast<WebGLRenderingContext*>(impl());
+ if (exec->argumentCount() > 0 && !exec->argument(0).isUndefinedOrNull() && !exec->argument(0).inherits(&JSWebGLProgram::s_info))
+ return throwTypeError(exec);
WebGLProgram* program = toWebGLProgram(exec->argument(0));
+ if (exec->argumentCount() > 1 && !exec->argument(1).isUndefinedOrNull() && !exec->argument(1).inherits(&JSWebGLUniformLocation::s_info))
+ return throwTypeError(exec);
WebGLUniformLocation* loc = toWebGLUniformLocation(exec->argument(1));
if (exec->hadException())
return jsUndefined();
@@ -354,9 +364,11 @@ static JSC::JSValue dataFunctionf(DataFunctionToCall f, JSC::ExecState* exec, We
WebGLUniformLocation* location = 0;
long index = -1;
- if (functionForUniform(f))
+ if (functionForUniform(f)) {
+ if (exec->argumentCount() > 0 && !exec->argument(0).isUndefinedOrNull() && !exec->argument(0).inherits(&JSWebGLUniformLocation::s_info))
+ return throwTypeError(exec);
location = toWebGLUniformLocation(exec->argument(0));
- else
+ } else
index = exec->argument(0).toInt32(exec);
if (exec->hadException())
@@ -439,6 +451,8 @@ static JSC::JSValue dataFunctioni(DataFunctionToCall f, JSC::ExecState* exec, We
if (exec->argumentCount() != 2)
return throwSyntaxError(exec);
+ if (exec->argumentCount() > 0 && !exec->argument(0).isUndefinedOrNull() && !exec->argument(0).inherits(&JSWebGLUniformLocation::s_info))
+ return throwTypeError(exec);
WebGLUniformLocation* location = toWebGLUniformLocation(exec->argument(0));
if (exec->hadException())
@@ -502,6 +516,8 @@ static JSC::JSValue dataFunctionMatrix(DataFunctionMatrixToCall f, JSC::ExecStat
if (exec->argumentCount() != 3)
return throwSyntaxError(exec);
+ if (exec->argumentCount() > 0 && !exec->argument(0).isUndefinedOrNull() && !exec->argument(0).inherits(&JSWebGLUniformLocation::s_info))
+ return throwTypeError(exec);
WebGLUniformLocation* location = toWebGLUniformLocation(exec->argument(0));
if (exec->hadException())
diff --git a/WebCore/bindings/js/ScriptDebugServer.cpp b/WebCore/bindings/js/ScriptDebugServer.cpp
index cd80de4..ecb7fa6 100644
--- a/WebCore/bindings/js/ScriptDebugServer.cpp
+++ b/WebCore/bindings/js/ScriptDebugServer.cpp
@@ -205,6 +205,11 @@ void ScriptDebugServer::pause()
m_pauseOnNextStatement = true;
}
+void ScriptDebugServer::breakProgram()
+{
+ // FIXME(WK43332): implement this.
+}
+
void ScriptDebugServer::continueProgram()
{
if (!m_paused)
diff --git a/WebCore/bindings/js/ScriptDebugServer.h b/WebCore/bindings/js/ScriptDebugServer.h
index fd8976b..432fe9a 100644
--- a/WebCore/bindings/js/ScriptDebugServer.h
+++ b/WebCore/bindings/js/ScriptDebugServer.h
@@ -79,6 +79,7 @@ public:
void setPauseOnExceptionsState(PauseOnExceptionsState);
void pause();
+ void breakProgram();
void continueProgram();
void stepIntoStatement();
void stepOverStatement();
diff --git a/WebCore/bindings/js/ScriptProfiler.cpp b/WebCore/bindings/js/ScriptProfiler.cpp
index f372c3c..62ae9ba 100644
--- a/WebCore/bindings/js/ScriptProfiler.cpp
+++ b/WebCore/bindings/js/ScriptProfiler.cpp
@@ -46,6 +46,11 @@ PassRefPtr<ScriptProfile> ScriptProfiler::stop(ScriptState* state, const String&
return ScriptProfile::create(profile);
}
+bool ScriptProfiler::isProfilerAlwaysEnabled()
+{
+ return false;
+}
+
} // namespace WebCore
#endif // ENABLE(JAVASCRIPT_DEBUGGER)
diff --git a/WebCore/bindings/js/ScriptProfiler.h b/WebCore/bindings/js/ScriptProfiler.h
index 4fa331c..180c49f 100644
--- a/WebCore/bindings/js/ScriptProfiler.h
+++ b/WebCore/bindings/js/ScriptProfiler.h
@@ -41,6 +41,7 @@ public:
static PassRefPtr<ScriptProfile> stop(ScriptState* state, const String& title);
static void takeHeapSnapshot() { }
static long getProfilerLogLines(long, String*) { return 0; }
+ static bool isProfilerAlwaysEnabled();
};
} // namespace WebCore
diff --git a/WebCore/bindings/objc/DOM.mm b/WebCore/bindings/objc/DOM.mm
index 008acec..c526123 100644
--- a/WebCore/bindings/objc/DOM.mm
+++ b/WebCore/bindings/objc/DOM.mm
@@ -377,7 +377,7 @@ id <DOMEventTarget> kit(WebCore::EventTarget* eventTarget)
WebCore::Frame* frame = node->document()->frame();
if (!frame)
return nil;
- return frame->nodeImage(node);
+ return frame->nodeImage(node).get();
}
- (NSArray *)textRects
diff --git a/WebCore/bindings/scripts/CodeGeneratorJS.pm b/WebCore/bindings/scripts/CodeGeneratorJS.pm
index 0b18d95..84e3919 100644
--- a/WebCore/bindings/scripts/CodeGeneratorJS.pm
+++ b/WebCore/bindings/scripts/CodeGeneratorJS.pm
@@ -1963,6 +1963,20 @@ sub GenerateImplementation
push(@implContent, " RefPtr<" . $parameter->type . "> $name = ${callbackClassName}::create(asObject(exec->argument($argsIndex)), castedThis->globalObject());\n");
}
} else {
+ # For functions with "StrictTypeChecking", if an input parameter's type does not match the signature,
+ # a TypeError is thrown instead of casting to null.
+ if ($function->signature->extendedAttributes->{"StrictTypeChecking"}) {
+ my $argValue = "exec->argument($argsIndex)";
+ my $argType = $codeGenerator->StripModule($parameter->type);
+ if (!IsNativeType($argType)) {
+ push(@implContent, " if (exec->argumentCount() > $argsIndex && !${argValue}.isUndefinedOrNull() && !${argValue}.inherits(&JS${argType}::s_info))\n");
+ push(@implContent, " return throwVMTypeError(exec);\n");
+ } elsif ($codeGenerator->IsStringType($argType)) {
+ push(@implContent, " if (exec->argumentCount() > $argsIndex && !${argValue}.isUndefinedOrNull() && !${argValue}.isString() && !${argValue}.isObject())\n");
+ push(@implContent, " return throwVMTypeError(exec);\n");
+ }
+ }
+
push(@implContent, " " . GetNativeTypeFromSignature($parameter) . " $name = " . JSValueToNative($parameter, "exec->argument($argsIndex)") . ";\n");
# If a parameter is "an index" and it's negative it should throw an INDEX_SIZE_ERR exception.
diff --git a/WebCore/bindings/scripts/CodeGeneratorV8.pm b/WebCore/bindings/scripts/CodeGeneratorV8.pm
index ebbcf8b..56838ca 100644
--- a/WebCore/bindings/scripts/CodeGeneratorV8.pm
+++ b/WebCore/bindings/scripts/CodeGeneratorV8.pm
@@ -1245,6 +1245,23 @@ END
}
} else {
$implIncludes{"V8BindingMacros.h"} = 1;
+ # For functions with "StrictTypeChecking", if an input parameter's type does not match the signature,
+ # a TypeError is thrown instead of casting to null.
+ if ($function->signature->extendedAttributes->{"StrictTypeChecking"}) {
+ my $argValue = "args[$paramIndex]";
+ my $argType = GetTypeFromSignature($parameter);
+ if (IsWrapperType($argType)) {
+ push(@implContentDecls, " if (args.Length() > $paramIndex && !isUndefinedOrNull($argValue) && !V8${argType}::HasInstance($argValue)) {\n");
+ push(@implContentDecls, " V8Proxy::throwTypeError();\n");
+ push(@implContentDecls, " return notHandledByInterceptor();\n");
+ push(@implContentDecls, " }\n");
+ } elsif ($codeGenerator->IsStringType($argType)) {
+ push(@implContentDecls, " if (args.Length() > $paramIndex && !isUndefinedOrNull($argValue) && !${argValue}->IsString() && !${argValue}->IsObject()) {\n");
+ push(@implContentDecls, " V8Proxy::throwTypeError();\n");
+ push(@implContentDecls, " return notHandledByInterceptor();\n");
+ push(@implContentDecls, " }\n");
+ }
+ }
push(@implContentDecls, " EXCEPTION_BLOCK($nativeType, $parameterName, " .
JSValueToNative($parameter, "args[$paramIndex]", BasicTypeCanFailConversion($parameter) ? "${parameterName}Ok" : undef) . ");\n");
}
@@ -2988,7 +3005,10 @@ sub RequiresCustomSignature
if (@{$function->{overloads}} > 1) {
return 0;
}
-
+ # Type checking is performed in the generated code
+ if ($function->signature->extendedAttributes->{"StrictTypeChecking"}) {
+ return 0;
+ }
foreach my $parameter (@{$function->parameters}) {
if ($parameter->extendedAttributes->{"Optional"} || $parameter->extendedAttributes->{"Callback"}) {
return 0;
diff --git a/WebCore/bindings/v8/ScriptDebugServer.cpp b/WebCore/bindings/v8/ScriptDebugServer.cpp
index 0c24678..3f1a0c5 100644
--- a/WebCore/bindings/v8/ScriptDebugServer.cpp
+++ b/WebCore/bindings/v8/ScriptDebugServer.cpp
@@ -84,6 +84,7 @@ ScriptDebugServer::ScriptDebugServer()
: m_pauseOnExceptionsState(DontPauseOnExceptions)
, m_pausedPage(0)
, m_enabled(true)
+ , m_breakpointsActivated(true)
{
}
@@ -186,7 +187,7 @@ void ScriptDebugServer::clearBreakpoints()
v8::Debug::Call(clearBreakpoints);
}
-void ScriptDebugServer::setBreakpointsActivated(bool enabled)
+void ScriptDebugServer::setBreakpointsActivated(bool activated)
{
ensureDebuggerScriptCompiled();
v8::HandleScope scope;
@@ -194,9 +195,11 @@ void ScriptDebugServer::setBreakpointsActivated(bool enabled)
v8::Context::Scope contextScope(debuggerContext);
v8::Local<v8::Object> args = v8::Object::New();
- args->Set(v8::String::New("enabled"), v8::Boolean::New(enabled));
+ args->Set(v8::String::New("enabled"), v8::Boolean::New(activated));
v8::Handle<v8::Function> setBreakpointsActivated = v8::Local<v8::Function>::Cast(m_debuggerScript.get()->Get(v8::String::New("setBreakpointsActivated")));
v8::Debug::Call(setBreakpointsActivated, args);
+
+ m_breakpointsActivated = activated;
}
ScriptDebugServer::PauseOnExceptionsState ScriptDebugServer::pauseOnExceptionsState()
@@ -228,6 +231,31 @@ void ScriptDebugServer::pause()
v8::Debug::DebugBreak();
}
+void ScriptDebugServer::breakProgram()
+{
+ DEFINE_STATIC_LOCAL(v8::Persistent<v8::FunctionTemplate>, callbackTemplate, ());
+
+ if (!m_breakpointsActivated)
+ return;
+
+ if (!v8::Context::InContext())
+ return;
+
+ if (callbackTemplate.IsEmpty()) {
+ callbackTemplate = v8::Persistent<v8::FunctionTemplate>::New(v8::FunctionTemplate::New());
+ callbackTemplate->SetCallHandler(&ScriptDebugServer::breakProgramCallback);
+ }
+
+ v8::Handle<v8::Context> context = v8::Context::GetCurrent();
+ if (context.IsEmpty())
+ return;
+
+ m_pausedPageContext = *context;
+ v8::Handle<v8::Function> breakProgramFunction = callbackTemplate->GetFunction();
+ v8::Debug::Call(breakProgramFunction);
+ m_pausedPageContext.Clear();
+}
+
void ScriptDebugServer::continueProgram()
{
if (m_pausedPage)
@@ -323,6 +351,41 @@ void ScriptDebugServer::runPendingTasks()
v8::Debug::ProcessDebugMessages();
}
+v8::Handle<v8::Value> ScriptDebugServer::breakProgramCallback(const v8::Arguments& args)
+{
+ ASSERT(2 == args.Length());
+ ScriptDebugServer::shared().breakProgram(v8::Handle<v8::Object>::Cast(args[0]));
+ return v8::Undefined();
+}
+
+void ScriptDebugServer::breakProgram(v8::Handle<v8::Object> executionState)
+{
+ // Don't allow nested breaks.
+ if (m_pausedPage)
+ return;
+
+ Frame* frame = retrieveFrame(m_pausedPageContext);
+ if (!frame)
+ return;
+
+ ScriptDebugListener* listener = m_listenersMap.get(frame->page());
+ if (!listener)
+ return;
+
+ m_executionState.set(executionState);
+ m_pausedPage = frame->page();
+ ScriptState* currentCallFrameState = ScriptState::forContext(m_pausedPageContext);
+ listener->didPause(currentCallFrameState);
+
+ // Wait for continue or step command.
+ m_clientMessageLoop->run(m_pausedPage);
+ ASSERT(!m_pausedPage);
+
+ // The listener may have been removed in the nested loop.
+ if (ScriptDebugListener* listener = m_listenersMap.get(frame->page()))
+ listener->didContinue();
+}
+
void ScriptDebugServer::v8DebugEventCallback(const v8::Debug::EventDetails& eventDetails)
{
ScriptDebugServer::shared().handleV8DebugEvent(eventDetails);
@@ -365,21 +428,9 @@ void ScriptDebugServer::handleV8DebugEvent(const v8::Debug::EventDetails& eventD
return;
}
- // Don't allow nested breaks.
- if (m_pausedPage)
- return;
- m_executionState.set(eventDetails.GetExecutionState());
- m_pausedPage = frame->page();
- ScriptState* currentCallFrameState = mainWorldScriptState(frame);
- listener->didPause(currentCallFrameState);
-
- // Wait for continue or step command.
- m_clientMessageLoop->run(m_pausedPage);
- ASSERT(!m_pausedPage);
-
- // The listener may have been removed in the nested loop.
- if (ScriptDebugListener* listener = m_listenersMap.get(frame->page()))
- listener->didContinue();
+ m_pausedPageContext = *eventContext;
+ breakProgram(eventDetails.GetExecutionState());
+ m_pausedPageContext.Clear();
}
}
}
diff --git a/WebCore/bindings/v8/ScriptDebugServer.h b/WebCore/bindings/v8/ScriptDebugServer.h
index a1e0a47..d1fd71f 100644
--- a/WebCore/bindings/v8/ScriptDebugServer.h
+++ b/WebCore/bindings/v8/ScriptDebugServer.h
@@ -71,6 +71,7 @@ public:
void setPauseOnExceptionsState(PauseOnExceptionsState pauseOnExceptionsState);
void pause();
+ void breakProgram();
void continueProgram();
void stepIntoStatement();
void stepOverStatement();
@@ -111,6 +112,9 @@ private:
ScriptDebugServer();
~ScriptDebugServer() { }
+ static v8::Handle<v8::Value> breakProgramCallback(const v8::Arguments& args);
+ void breakProgram(v8::Handle<v8::Object> executionState);
+
static void v8DebugEventCallback(const v8::Debug::EventDetails& eventDetails);
void handleV8DebugEvent(const v8::Debug::EventDetails& eventDetails);
@@ -128,7 +132,10 @@ private:
OwnHandle<v8::Object> m_executionState;
OwnPtr<ClientMessageLoop> m_clientMessageLoop;
Page* m_pausedPage;
+ v8::Local<v8::Context> m_pausedPageContext;
bool m_enabled;
+
+ bool m_breakpointsActivated;
};
} // namespace WebCore
diff --git a/WebCore/bindings/v8/ScriptProfiler.cpp b/WebCore/bindings/v8/ScriptProfiler.cpp
index 9213774..0de4a24 100644
--- a/WebCore/bindings/v8/ScriptProfiler.cpp
+++ b/WebCore/bindings/v8/ScriptProfiler.cpp
@@ -69,4 +69,9 @@ long ScriptProfiler::getProfilerLogLines(long position, String* data)
return position;
}
+bool ScriptProfiler::isProfilerAlwaysEnabled()
+{
+ return true;
+}
+
} // namespace WebCore
diff --git a/WebCore/bindings/v8/ScriptProfiler.h b/WebCore/bindings/v8/ScriptProfiler.h
index 5c1054b..b1ab3b1 100644
--- a/WebCore/bindings/v8/ScriptProfiler.h
+++ b/WebCore/bindings/v8/ScriptProfiler.h
@@ -45,6 +45,7 @@ public:
static PassRefPtr<ScriptProfile> stop(ScriptState* state, const String& title);
static void takeHeapSnapshot();
static long getProfilerLogLines(long position, String* data);
+ static bool isProfilerAlwaysEnabled();
};
} // namespace WebCore
diff --git a/WebCore/bindings/v8/V8DOMWrapper.cpp b/WebCore/bindings/v8/V8DOMWrapper.cpp
index 8a72a3a..921f957 100644
--- a/WebCore/bindings/v8/V8DOMWrapper.cpp
+++ b/WebCore/bindings/v8/V8DOMWrapper.cpp
@@ -51,6 +51,7 @@
#include "V8HTMLCollection.h"
#include "V8HTMLDocument.h"
#include "V8IDBRequest.h"
+#include "V8IDBTransaction.h"
#include "V8IsolatedContext.h"
#include "V8Location.h"
#include "V8MessageChannel.h"
@@ -221,9 +222,6 @@ PassRefPtr<NodeFilter> V8DOMWrapper::wrapNativeNodeFilter(v8::Handle<v8::Value>
// to NodeFilter. NodeFilter has a ref counted pointer to NodeFilterCondition.
// In NodeFilterCondition, filter object is persisted in its constructor,
// and disposed in its destructor.
- if (!filter->IsFunction())
- return 0;
-
return NodeFilter::create(V8NodeFilterCondition::create(filter));
}
@@ -382,6 +380,8 @@ v8::Handle<v8::Value> V8DOMWrapper::convertEventTargetToV8Object(EventTarget* ta
#if ENABLE(INDEXED_DATABASE)
if (IDBRequest* idbRequest = target->toIDBRequest())
return toV8(idbRequest);
+ if (IDBTransaction* idbTransaction = target->toIDBTransaction())
+ return toV8(idbTransaction);
#endif
#if ENABLE(WEB_SOCKETS)
diff --git a/WebCore/bindings/v8/V8HiddenPropertyName.h b/WebCore/bindings/v8/V8HiddenPropertyName.h
index 2d0e8d6..7867b36 100644
--- a/WebCore/bindings/v8/V8HiddenPropertyName.h
+++ b/WebCore/bindings/v8/V8HiddenPropertyName.h
@@ -40,10 +40,12 @@ namespace WebCore {
V(listener) \
V(attributeListener) \
V(scriptState) \
+ V(devtoolsInjectedScript) \
V(sleepFunction) \
V(toStringString) \
V(event)
+
class V8HiddenPropertyName {
public:
#define V8_DECLARE_PROPERTY(name) static v8::Handle<v8::String> name();
diff --git a/WebCore/bindings/v8/V8NodeFilterCondition.cpp b/WebCore/bindings/v8/V8NodeFilterCondition.cpp
index 2170698..4e0240d 100644
--- a/WebCore/bindings/v8/V8NodeFilterCondition.cpp
+++ b/WebCore/bindings/v8/V8NodeFilterCondition.cpp
@@ -62,13 +62,24 @@ short V8NodeFilterCondition::acceptNode(ScriptState* state, Node* node) const
{
ASSERT(v8::Context::InContext());
- if (!m_filter->IsFunction())
+ if (!m_filter->IsObject())
return NodeFilter::FILTER_ACCEPT;
v8::TryCatch exceptionCatcher;
+ v8::Handle<v8::Function> callback;
+ if (m_filter->IsFunction())
+ callback = v8::Handle<v8::Function>::Cast(m_filter);
+ else {
+ v8::Local<v8::Value> value = m_filter->ToObject()->Get(v8::String::New("acceptNode"));
+ if (!value->IsFunction()) {
+ V8Proxy::throwError(V8Proxy::TypeError, "NodeFilter object does not have an acceptNode function");
+ return NodeFilter::FILTER_REJECT;
+ }
+ callback = v8::Handle<v8::Function>::Cast(value);
+ }
+
v8::Handle<v8::Object> object = v8::Context::GetCurrent()->Global();
- v8::Handle<v8::Function> callback = v8::Handle<v8::Function>::Cast(m_filter);
OwnArrayPtr<v8::Handle<v8::Value> > args(new v8::Handle<v8::Value>[1]);
args[0] = toV8(node);
diff --git a/WebCore/bindings/v8/V8Proxy.cpp b/WebCore/bindings/v8/V8Proxy.cpp
index 50e9fdc..5d3eeb8 100644
--- a/WebCore/bindings/v8/V8Proxy.cpp
+++ b/WebCore/bindings/v8/V8Proxy.cpp
@@ -37,6 +37,8 @@
#include "DocumentLoader.h"
#include "Frame.h"
#include "FrameLoaderClient.h"
+#include "IDBFactoryBackendInterface.h"
+#include "IDBPendingTransactionMonitor.h"
#include "InspectorTimelineAgent.h"
#include "Page.h"
#include "PageGroup.h"
@@ -487,7 +489,7 @@ v8::Local<v8::Value> V8Proxy::runScriptInternal(v8::Handle<v8::Script> script, b
}
// Release the storage mutex if applicable.
- releaseStorageMutex();
+ didLeaveScriptContext();
if (handleOutOfMemory())
ASSERT(result.IsEmpty());
@@ -563,7 +565,7 @@ v8::Local<v8::Value> V8Proxy::callFunction(v8::Handle<v8::Function> function, v8
}
// Release the storage mutex if applicable.
- releaseStorageMutex();
+ didLeaveScriptContext();
if (v8::V8::IsDead())
handleFatalErrorInV8();
@@ -675,16 +677,24 @@ void V8Proxy::disconnectFrame()
{
}
-void V8Proxy::releaseStorageMutex()
+void V8Proxy::didLeaveScriptContext()
{
+ Page* page = m_frame->page();
+ if (!page)
+ return;
+ // If we've just left a script context and indexed database has been
+ // instantiated, we must let its transaction coordinator know so it can terminate
+ // any not-yet-started transactions.
+ if (IDBPendingTransactionMonitor::hasPendingTransactions()) {
+ ASSERT(page->group().hasIDBFactory());
+ page->group().idbFactory()->abortPendingTransactions(IDBPendingTransactionMonitor::pendingTransactions());
+ IDBPendingTransactionMonitor::clearPendingTransactions();
+ }
// If we've just left a top level script context and local storage has been
// instantiated, we must ensure that any storage locks have been freed.
// Per http://dev.w3.org/html5/spec/Overview.html#storage-mutex
if (m_recursion != 0)
return;
- Page* page = m_frame->page();
- if (!page)
- return;
if (page->group().hasLocalStorage())
page->group().localStorage()->unlock();
}
diff --git a/WebCore/bindings/v8/V8Proxy.h b/WebCore/bindings/v8/V8Proxy.h
index 94ff17c..ca3920b 100644
--- a/WebCore/bindings/v8/V8Proxy.h
+++ b/WebCore/bindings/v8/V8Proxy.h
@@ -346,9 +346,7 @@ namespace WebCore {
static void reportUnsafeAccessTo(Frame* target, DelayReporting delay);
private:
- // If m_recursionCount is 0, let LocalStorage know so we can release
- // the storage mutex.
- void releaseStorageMutex();
+ void didLeaveScriptContext();
void resetIsolatedWorlds();
diff --git a/WebCore/bindings/v8/custom/V8InjectedScriptHostCustom.cpp b/WebCore/bindings/v8/custom/V8InjectedScriptHostCustom.cpp
index 1b069cf..b3007a4 100644
--- a/WebCore/bindings/v8/custom/V8InjectedScriptHostCustom.cpp
+++ b/WebCore/bindings/v8/custom/V8InjectedScriptHostCustom.cpp
@@ -46,6 +46,7 @@
#include "V8BindingState.h"
#include "V8DOMWindow.h"
#include "V8Database.h"
+#include "V8HiddenPropertyName.h"
#include "V8JavaScriptCallFrame.h"
#include "V8Node.h"
#include "V8Proxy.h"
@@ -120,6 +121,21 @@ ScriptObject InjectedScriptHost::createInjectedScript(const String& scriptSource
return ScriptObject(inspectedScriptState, injectedScript);
}
+void InjectedScriptHost::discardInjectedScript(ScriptState* inspectedScriptState)
+{
+ v8::HandleScope handleScope;
+ v8::Local<v8::Context> context = inspectedScriptState->context();
+ v8::Context::Scope contextScope(context);
+
+ v8::Local<v8::Object> global = context->Global();
+ // Skip proxy object. The proxy object will survive page navigation while we need
+ // an object whose lifetime consides with that of the inspected context.
+ global = v8::Local<v8::Object>::Cast(global->GetPrototype());
+
+ v8::Handle<v8::String> key = V8HiddenPropertyName::devtoolsInjectedScript();
+ global->DeleteHiddenValue(key);
+}
+
v8::Handle<v8::Value> V8InjectedScriptHost::nodeForIdCallback(const v8::Arguments& args)
{
INC_STATS("InjectedScriptHost.nodeForId()");
@@ -206,7 +222,7 @@ InjectedScript InjectedScriptHost::injectedScriptFor(ScriptState* inspectedScrip
// an object whose lifetime consides with that of the inspected context.
global = v8::Local<v8::Object>::Cast(global->GetPrototype());
- v8::Local<v8::String> key = v8::String::New("Devtools_InjectedScript");
+ v8::Handle<v8::String> key = V8HiddenPropertyName::devtoolsInjectedScript();
v8::Local<v8::Value> val = global->GetHiddenValue(key);
if (!val.IsEmpty() && val->IsObject())
return InjectedScript(ScriptObject(inspectedScriptState, v8::Local<v8::Object>::Cast(val)));
diff --git a/WebCore/bindings/v8/custom/V8InspectorFrontendHostCustom.cpp b/WebCore/bindings/v8/custom/V8InspectorFrontendHostCustom.cpp
index 7733a70..25b9010 100644
--- a/WebCore/bindings/v8/custom/V8InspectorFrontendHostCustom.cpp
+++ b/WebCore/bindings/v8/custom/V8InspectorFrontendHostCustom.cpp
@@ -33,6 +33,7 @@
#include "InspectorController.h"
#include "InspectorFrontendHost.h"
+#include "PlatformString.h"
#include "V8Binding.h"
#include "V8MouseEvent.h"
@@ -76,18 +77,26 @@ v8::Handle<v8::Value> V8InspectorFrontendHost::showContextMenuCallback(const v8:
for (size_t i = 0; i < array->Length(); ++i) {
v8::Local<v8::Object> item = v8::Local<v8::Object>::Cast(array->Get(v8::Integer::New(i)));
- v8::Local<v8::Value> label = item->Get(v8::String::New("label"));
+ v8::Local<v8::Value> type = item->Get(v8::String::New("type"));
v8::Local<v8::Value> id = item->Get(v8::String::New("id"));
- if (label->IsUndefined() || id->IsUndefined()) {
- items.append(new ContextMenuItem(SeparatorType,
- ContextMenuItemCustomTagNoAction,
- String()));
+ v8::Local<v8::Value> label = item->Get(v8::String::New("label"));
+ v8::Local<v8::Value> enabled = item->Get(v8::String::New("enabled"));
+ v8::Local<v8::Value> checked = item->Get(v8::String::New("checked"));
+ if (!type->IsString())
+ continue;
+ String typeString = toWebCoreStringWithNullCheck(type);
+ if (typeString == "separator") {
+ items.append(new ContextMenuItem(SeparatorType,
+ ContextMenuItemCustomTagNoAction,
+ String()));
} else {
- ContextMenuAction typedId = static_cast<ContextMenuAction>(
- ContextMenuItemBaseCustomTag + id->ToInt32()->Value());
- items.append(new ContextMenuItem(ActionType,
- typedId,
- toWebCoreStringWithNullCheck(label)));
+ ContextMenuAction typedId = static_cast<ContextMenuAction>(ContextMenuItemBaseCustomTag + id->ToInt32()->Value());
+ ContextMenuItem* menuItem = new ContextMenuItem((typeString == "checkbox" ? CheckableActionType : ActionType), typedId, toWebCoreStringWithNullCheck(label));
+ if (checked->IsBoolean())
+ menuItem->setChecked(checked->ToBoolean()->Value());
+ if (enabled->IsBoolean())
+ menuItem->setEnabled(enabled->ToBoolean()->Value());
+ items.append(menuItem);
}
}
diff --git a/WebCore/bindings/v8/custom/V8WebGLRenderingContextCustom.cpp b/WebCore/bindings/v8/custom/V8WebGLRenderingContextCustom.cpp
index fd6e120..9346a05 100644
--- a/WebCore/bindings/v8/custom/V8WebGLRenderingContextCustom.cpp
+++ b/WebCore/bindings/v8/custom/V8WebGLRenderingContextCustom.cpp
@@ -227,6 +227,10 @@ v8::Handle<v8::Value> V8WebGLRenderingContext::getAttachedShadersCallback(const
ExceptionCode ec = 0;
WebGLRenderingContext* context = V8WebGLRenderingContext::toNative(args.Holder());
+ if (args.Length() > 0 && !isUndefinedOrNull(args[0]) && !V8WebGLProgram::HasInstance(args[0])) {
+ V8Proxy::throwTypeError();
+ return notHandledByInterceptor();
+ }
WebGLProgram* program = V8WebGLProgram::HasInstance(args[0]) ? V8WebGLProgram::toNative(v8::Handle<v8::Object>::Cast(args[0])) : 0;
Vector<WebGLShader*> shaders;
bool succeed = context->getAttachedShaders(program, shaders, ec);
@@ -319,6 +323,10 @@ v8::Handle<v8::Value> V8WebGLRenderingContext::getProgramParameterCallback(const
ExceptionCode ec = 0;
WebGLRenderingContext* context = V8WebGLRenderingContext::toNative(args.Holder());
+ if (args.Length() > 0 && !isUndefinedOrNull(args[0]) && !V8WebGLProgram::HasInstance(args[0])) {
+ V8Proxy::throwTypeError();
+ return notHandledByInterceptor();
+ }
WebGLProgram* program = V8WebGLProgram::HasInstance(args[0]) ? V8WebGLProgram::toNative(v8::Handle<v8::Object>::Cast(args[0])) : 0;
bool ok;
unsigned pname = toInt32(args[1], ok);
@@ -351,6 +359,10 @@ v8::Handle<v8::Value> V8WebGLRenderingContext::getShaderParameterCallback(const
ExceptionCode ec = 0;
WebGLRenderingContext* context = V8WebGLRenderingContext::toNative(args.Holder());
+ if (args.Length() > 0 && !isUndefinedOrNull(args[0]) && !V8WebGLShader::HasInstance(args[0])) {
+ V8Proxy::throwTypeError();
+ return notHandledByInterceptor();
+ }
WebGLShader* shader = V8WebGLShader::HasInstance(args[0]) ? V8WebGLShader::toNative(v8::Handle<v8::Object>::Cast(args[0])) : 0;
bool ok;
unsigned pname = toInt32(args[1], ok);
@@ -383,8 +395,16 @@ v8::Handle<v8::Value> V8WebGLRenderingContext::getUniformCallback(const v8::Argu
ExceptionCode ec = 0;
WebGLRenderingContext* context = V8WebGLRenderingContext::toNative(args.Holder());
+ if (args.Length() > 0 && !isUndefinedOrNull(args[0]) && !V8WebGLProgram::HasInstance(args[0])) {
+ V8Proxy::throwTypeError();
+ return notHandledByInterceptor();
+ }
WebGLProgram* program = V8WebGLProgram::HasInstance(args[0]) ? V8WebGLProgram::toNative(v8::Handle<v8::Object>::Cast(args[0])) : 0;
+ if (args.Length() > 1 && !isUndefinedOrNull(args[1]) && !V8WebGLUniformLocation::HasInstance(args[1])) {
+ V8Proxy::throwTypeError();
+ return notHandledByInterceptor();
+ }
bool ok = false;
WebGLUniformLocation* location = toWebGLUniformLocation(args[1], ok);
@@ -452,8 +472,13 @@ static v8::Handle<v8::Value> vertexAttribAndUniformHelperf(const v8::Arguments&
if (isFunctionToCallForAttribute(functionToCall))
index = toInt32(args[0], ok);
- else
+ else {
+ if (args.Length() > 0 && !isUndefinedOrNull(args[0]) && !V8WebGLUniformLocation::HasInstance(args[0])) {
+ V8Proxy::throwTypeError();
+ return notHandledByInterceptor();
+ }
location = toWebGLUniformLocation(args[0], ok);
+ }
WebGLRenderingContext* context = V8WebGLRenderingContext::toNative(args.Holder());
@@ -526,6 +551,10 @@ static v8::Handle<v8::Value> uniformHelperi(const v8::Arguments& args,
}
WebGLRenderingContext* context = V8WebGLRenderingContext::toNative(args.Holder());
+ if (args.Length() > 0 && !isUndefinedOrNull(args[0]) && !V8WebGLUniformLocation::HasInstance(args[0])) {
+ V8Proxy::throwTypeError();
+ return notHandledByInterceptor();
+ }
bool ok = false;
WebGLUniformLocation* location = toWebGLUniformLocation(args[0], ok);
@@ -639,6 +668,10 @@ static v8::Handle<v8::Value> uniformMatrixHelper(const v8::Arguments& args,
WebGLRenderingContext* context = V8WebGLRenderingContext::toNative(args.Holder());
+ if (args.Length() > 0 && !isUndefinedOrNull(args[0]) && !V8WebGLUniformLocation::HasInstance(args[0])) {
+ V8Proxy::throwTypeError();
+ return notHandledByInterceptor();
+ }
bool ok = false;
WebGLUniformLocation* location = toWebGLUniformLocation(args[0], ok);
diff --git a/WebCore/bridge/qt/qt_runtime.cpp b/WebCore/bridge/qt/qt_runtime.cpp
index 6881c2e..630fd2f 100644
--- a/WebCore/bridge/qt/qt_runtime.cpp
+++ b/WebCore/bridge/qt/qt_runtime.cpp
@@ -905,7 +905,7 @@ JSValue convertQVariantToValue(ExecState* exec, PassRefPtr<RootObject> root, con
JSValue val = convertQVariantToValue(exec, root.get(), i.value());
if (val) {
PutPropertySlot slot;
- ret->put(exec, Identifier(exec, (const UChar *)s.constData(), s.length()), val, slot);
+ ret->put(exec, Identifier(exec, reinterpret_cast_ptr<const UChar *>(s.constData()), s.length()), val, slot);
// ### error case?
}
++i;
diff --git a/WebCore/css/CSSComputedStyleDeclaration.cpp b/WebCore/css/CSSComputedStyleDeclaration.cpp
index 418251f..cbb9ca8 100644
--- a/WebCore/css/CSSComputedStyleDeclaration.cpp
+++ b/WebCore/css/CSSComputedStyleDeclaration.cpp
@@ -893,8 +893,6 @@ PassRefPtr<CSSValue> CSSComputedStyleDeclaration::getPropertyCSSValue(int proper
}
case CSSPropertyFontSize:
return CSSPrimitiveValue::create(style->fontDescription().computedPixelSize(), CSSPrimitiveValue::CSS_PX);
- case CSSPropertyWebkitBinding:
- break;
case CSSPropertyFontStyle:
if (style->fontDescription().italic())
return CSSPrimitiveValue::createIdentifier(CSSValueItalic);
diff --git a/WebCore/css/CSSParser.cpp b/WebCore/css/CSSParser.cpp
index 7528cd8..f511507 100644
--- a/WebCore/css/CSSParser.cpp
+++ b/WebCore/css/CSSParser.cpp
@@ -1201,40 +1201,6 @@ bool CSSParser::parseValue(int propId, bool important)
validPrimitive = true;
break;
- case CSSPropertyWebkitBinding:
-#if ENABLE(XBL)
- if (id == CSSValueNone)
- validPrimitive = true;
- else {
- RefPtr<CSSValueList> values = CSSValueList::createCommaSeparated();
- CSSParserValue* val;
- RefPtr<CSSValue> parsedValue;
- while ((val = m_valueList->current())) {
- if (val->unit == CSSPrimitiveValue::CSS_URI && m_styleSheet) {
- // FIXME: The completeURL call should be done when using the CSSPrimitiveValue,
- // not when creating it.
- parsedValue = CSSPrimitiveValue::create(m_styleSheet->completeURL(val->string), CSSPrimitiveValue::CSS_URI);
- }
- if (!parsedValue)
- break;
-
- // FIXME: We can't use release() here since we might hit this path twice
- // but that logic seems wrong to me to begin with, we convert all non-uri values
- // into the last seen URI value!?
- // -webkit-binding: url(foo.xml), 1, 2; (if that were valid) is treated as:
- // -webkit-binding: url(foo.xml), url(foo.xml), url(foo.xml); !?
- values->append(parsedValue.get());
- m_valueList->next();
- }
- if (!values->length())
- return false;
-
- addProperty(propId, values.release(), important);
- m_valueList->next();
- return true;
- }
-#endif
- break;
case CSSPropertyWebkitBorderImage:
case CSSPropertyWebkitMaskBoxImage:
if (id == CSSValueNone)
@@ -3887,6 +3853,27 @@ static inline bool parseAlphaValue(const UChar*& string, const UChar* end, UChar
return *foundTerminator == terminator;
}
+static inline bool mightBeRGBA(const UChar* characters, unsigned length)
+{
+ if (length < 5)
+ return false;
+ return characters[4] == '('
+ && (characters[0] | 0x20) == 'r'
+ && (characters[1] | 0x20) == 'g'
+ && (characters[2] | 0x20) == 'b'
+ && (characters[3] | 0x20) == 'a';
+}
+
+static inline bool mightBeRGB(const UChar* characters, unsigned length)
+{
+ if (length < 4)
+ return false;
+ return characters[3] == '('
+ && (characters[0] | 0x20) == 'r'
+ && (characters[1] | 0x20) == 'g'
+ && (characters[2] | 0x20) == 'b';
+}
+
bool CSSParser::parseColor(const String &name, RGBA32& rgb, bool strict)
{
const UChar* characters = name.characters();
@@ -3903,7 +3890,7 @@ bool CSSParser::parseColor(const String &name, RGBA32& rgb, bool strict)
}
// Try rgba() syntax.
- if (name.startsWith("rgba(")) {
+ if (mightBeRGBA(characters, length)) {
const UChar* current = characters + 5;
const UChar* end = characters + length;
int red;
@@ -3925,7 +3912,7 @@ bool CSSParser::parseColor(const String &name, RGBA32& rgb, bool strict)
}
// Try rgb() syntax.
- if (name.startsWith("rgb(")) {
+ if (mightBeRGB(characters, length)) {
const UChar* current = characters + 4;
const UChar* end = characters + length;
int red;
diff --git a/WebCore/css/CSSPropertyNames.in b/WebCore/css/CSSPropertyNames.in
index d236b45..0216ae1 100644
--- a/WebCore/css/CSSPropertyNames.in
+++ b/WebCore/css/CSSPropertyNames.in
@@ -172,7 +172,6 @@ z-index
# a single value: -webkit-background-size: l; is equivalent to background-size: l l;
# whereas background-size: l; is equivalent to background-size: l auto;
-webkit-background-size
--webkit-binding
-webkit-border-end
-webkit-border-end-color
-webkit-border-end-style
diff --git a/WebCore/css/CSSStyleSelector.cpp b/WebCore/css/CSSStyleSelector.cpp
index fd411d9..aa724a3 100644
--- a/WebCore/css/CSSStyleSelector.cpp
+++ b/WebCore/css/CSSStyleSelector.cpp
@@ -4687,37 +4687,6 @@ void CSSStyleSelector::applyProperty(int id, CSSValue *value)
m_style->setAppearance(*primitiveValue);
return;
}
- case CSSPropertyWebkitBinding: {
-#if ENABLE(XBL)
- if (isInitial || (primitiveValue && primitiveValue->getIdent() == CSSValueNone)) {
- m_style->deleteBindingURIs();
- return;
- }
- else if (isInherit) {
- if (m_parentStyle->bindingURIs())
- m_style->inheritBindingURIs(m_parentStyle->bindingURIs());
- else
- m_style->deleteBindingURIs();
- return;
- }
-
- if (!value->isValueList()) return;
- CSSValueList* list = static_cast<CSSValueList*>(value);
- bool firstBinding = true;
- for (unsigned int i = 0; i < list->length(); i++) {
- CSSValue *item = list->itemWithoutBoundsCheck(i);
- CSSPrimitiveValue *val = static_cast<CSSPrimitiveValue*>(item);
- if (val->primitiveType() == CSSPrimitiveValue::CSS_URI) {
- if (firstBinding) {
- firstBinding = false;
- m_style->deleteBindingURIs();
- }
- m_style->addBindingURI(val->getStringValue());
- }
- }
-#endif
- return;
- }
case CSSPropertyWebkitBorderImage:
case CSSPropertyWebkitMaskBoxImage: {
diff --git a/WebCore/css/CSSStyleSelector.h b/WebCore/css/CSSStyleSelector.h
index ad801da..b0d977e 100644
--- a/WebCore/css/CSSStyleSelector.h
+++ b/WebCore/css/CSSStyleSelector.h
@@ -50,6 +50,7 @@ class CSSStyleSheet;
class CSSValue;
class CSSVariableDependentValue;
class CSSVariablesRule;
+class ContainerNode;
class DataGridColumn;
class Document;
class Element;
@@ -298,7 +299,7 @@ public:
Element* m_element;
StyledElement* m_styledElement;
EInsideLink m_elementLinkState;
- Node* m_parentNode;
+ ContainerNode* m_parentNode;
CSSValue* m_lineHeightValue;
bool m_fontDirty;
bool m_matchAuthorAndUserStyles;
diff --git a/WebCore/css/makeprop.pl b/WebCore/css/makeprop.pl
index 0fd1f08..8810e8d 100644
--- a/WebCore/css/makeprop.pl
+++ b/WebCore/css/makeprop.pl
@@ -95,6 +95,12 @@ print HEADER "const int firstCSSProperty = $first;\n";
print HEADER "const int numCSSProperties = $num;\n";
print HEADER "const size_t maxCSSPropertyNameLength = $maxLen;\n";
+print HEADER "const char* const propertyNameStrings[$num] = {\n";
+foreach my $name (@names) {
+ print HEADER "\"$name\",\n";
+}
+print HEADER "};\n";
+
print HEADER << "EOF";
const char* getPropertyName(CSSPropertyID);
@@ -108,14 +114,8 @@ close HEADER;
system("gperf --key-positions=\"*\" -D -n -s 2 CSSPropertyNames.gperf > CSSPropertyNames.cpp") == 0 || die "calling gperf failed: $?";
open C, ">>CSSPropertyNames.cpp" || die "Could not open CSSPropertyNames.cpp for writing";
-print C "static const char * const propertyNameStrings[$num] = {\n";
-
-foreach my $name (@names) {
- print C "\"$name\",\n";
-}
-
print C << "EOF";
-};
+
const char* getPropertyName(CSSPropertyID id)
{
if (id < firstCSSProperty)
diff --git a/WebCore/dom/ContainerNode.cpp b/WebCore/dom/ContainerNode.cpp
index e559ba7..ef62b38 100644
--- a/WebCore/dom/ContainerNode.cpp
+++ b/WebCore/dom/ContainerNode.cpp
@@ -134,31 +134,12 @@ bool ContainerNode::insertBefore(PassRefPtr<Node> newChild, Node* refChild, Exce
if (child->parentNode())
break;
- ASSERT(!child->nextSibling());
- ASSERT(!child->previousSibling());
-
- // Add child before "next".
- forbidEventDispatch();
- Node* prev = next->previousSibling();
- ASSERT(m_lastChild != prev);
- next->setPreviousSibling(child);
- if (prev) {
- ASSERT(m_firstChild != next);
- ASSERT(prev->nextSibling() == next);
- prev->setNextSibling(child);
- } else {
- ASSERT(m_firstChild == next);
- m_firstChild = child;
- }
- child->setParent(this);
- child->setPreviousSibling(prev);
- child->setNextSibling(next.get());
- allowEventDispatch();
+ insertBeforeCommon(next.get(), child);
// Send notification about the children change.
childrenChanged(false, refChildPreviousSibling.get(), next.get(), 1);
notifyChildInserted(child);
-
+
// Add child to the rendering tree.
if (attached() && !child->attached() && child->parent() == this) {
if (shouldLazyAttach)
@@ -176,6 +157,57 @@ bool ContainerNode::insertBefore(PassRefPtr<Node> newChild, Node* refChild, Exce
return true;
}
+void ContainerNode::insertBeforeCommon(Node* nextChild, Node* newChild)
+{
+ ASSERT(newChild);
+ ASSERT(!newChild->parent()); // Use insertBefore if you need to handle reparenting (and want DOM mutation events).
+ ASSERT(!newChild->nextSibling());
+ ASSERT(!newChild->previousSibling());
+
+ forbidEventDispatch();
+ Node* prev = nextChild->previousSibling();
+ ASSERT(m_lastChild != prev);
+ nextChild->setPreviousSibling(newChild);
+ if (prev) {
+ ASSERT(m_firstChild != nextChild);
+ ASSERT(prev->nextSibling() == nextChild);
+ prev->setNextSibling(newChild);
+ } else {
+ ASSERT(m_firstChild == nextChild);
+ m_firstChild = newChild;
+ }
+ newChild->setParent(this);
+ newChild->setPreviousSibling(prev);
+ newChild->setNextSibling(nextChild);
+ allowEventDispatch();
+}
+
+void ContainerNode::parserInsertBefore(PassRefPtr<Node> newChild, Node* nextChild)
+{
+ ASSERT(newChild);
+ ASSERT(nextChild);
+ ASSERT(nextChild->parentNode() == this);
+
+ NodeVector targets;
+ collectTargetNodes(newChild.get(), targets);
+ if (targets.isEmpty())
+ return;
+
+ if (nextChild->previousSibling() == newChild || nextChild == newChild) // nothing to do
+ return;
+
+ RefPtr<Node> next = nextChild;
+ RefPtr<Node> nextChildPreviousSibling = nextChild->previousSibling();
+ for (NodeVector::const_iterator it = targets.begin(); it != targets.end(); ++it) {
+ Node* child = it->get();
+
+ insertBeforeCommon(next.get(), child);
+
+ childrenChanged(true, nextChildPreviousSibling.get(), nextChild, 1);
+ notifyChildInserted(child);
+ }
+}
+
bool ContainerNode::replaceChild(PassRefPtr<Node> newChild, Node* oldChild, ExceptionCode& ec, bool shouldLazyAttach)
{
// Check that this node is not "floating".
@@ -367,31 +399,9 @@ bool ContainerNode::removeChild(Node* oldChild, ExceptionCode& ec)
// that no callers call with ref count == 0 and parent = 0 (as of this
// writing, there are definitely callers who call that way).
- forbidEventDispatch();
-
- // Remove from rendering tree
- if (child->attached())
- child->detach();
-
- // Remove the child
- Node *prev, *next;
- prev = child->previousSibling();
- next = child->nextSibling();
-
- if (next)
- next->setPreviousSibling(prev);
- if (prev)
- prev->setNextSibling(next);
- if (m_firstChild == child)
- m_firstChild = next;
- if (m_lastChild == child)
- m_lastChild = prev;
-
- child->setPreviousSibling(0);
- child->setNextSibling(0);
- child->setParent(0);
-
- allowEventDispatch();
+ Node* prev = child->previousSibling();
+ Node* next = child->nextSibling();
+ removeBetween(prev, next, child.get());
// Dispatch post-removal mutation events
childrenChanged(false, prev, next, -1);
@@ -405,6 +415,50 @@ bool ContainerNode::removeChild(Node* oldChild, ExceptionCode& ec)
return child;
}
+void ContainerNode::removeBetween(Node* previousChild, Node* nextChild, Node* oldChild)
+{
+ ASSERT(oldChild);
+ ASSERT(oldChild->parentNode() == this);
+
+ forbidEventDispatch();
+
+ // Remove from rendering tree
+ if (oldChild->attached())
+ oldChild->detach();
+
+ if (nextChild)
+ nextChild->setPreviousSibling(previousChild);
+ if (previousChild)
+ previousChild->setNextSibling(nextChild);
+ if (m_firstChild == oldChild)
+ m_firstChild = nextChild;
+ if (m_lastChild == oldChild)
+ m_lastChild = previousChild;
+
+ oldChild->setPreviousSibling(0);
+ oldChild->setNextSibling(0);
+ oldChild->setParent(0);
+
+ allowEventDispatch();
+}
+
+void ContainerNode::parserRemoveChild(Node* oldChild)
+{
+ ASSERT(oldChild);
+ ASSERT(oldChild->parentNode() == this);
+
+ Node* prev = oldChild->previousSibling();
+ Node* next = oldChild->nextSibling();
+
+ removeBetween(prev, next, oldChild);
+
+ childrenChanged(true, prev, next, -1);
+ if (oldChild->inDocument())
+ oldChild->removedFromDocument();
+ else
+ oldChild->removedFromTree(true);
+}
+
// this differs from other remove functions because it forcibly removes all the children,
// regardless of read-only status or event exceptions, e.g.
bool ContainerNode::removeChildren()
@@ -534,45 +588,27 @@ bool ContainerNode::appendChild(PassRefPtr<Node> newChild, ExceptionCode& ec, bo
return true;
}
-void ContainerNode::addChildCommon(Node* newChild)
+void ContainerNode::parserAddChild(PassRefPtr<Node> newChild)
{
- ASSERT(!newChild->parent()); // Use appendChild if you need to handle reparenting.
+ ASSERT(newChild);
+ ASSERT(!newChild->parent()); // Use appendChild if you need to handle reparenting (and want DOM mutation events).
+
forbidEventDispatch();
Node* last = m_lastChild;
// FIXME: This method should take a PassRefPtr.
- appendChildToContainer<Node, ContainerNode>(newChild, this);
+ appendChildToContainer<Node, ContainerNode>(newChild.get(), this);
allowEventDispatch();
+ // FIXME: Why doesn't this use notifyChildInserted(newChild) instead?
document()->incDOMTreeVersion();
if (inDocument())
newChild->insertedIntoDocument();
childrenChanged(true, last, 0, 1);
}
-void ContainerNode::parserAddChild(PassRefPtr<Node> newChild)
+void ContainerNode::deprecatedParserAddChild(PassRefPtr<Node> node)
{
- ASSERT(newChild);
- // This function is only used during parsing.
- // It does not send any DOM mutation events or handle reparenting.
-
- addChildCommon(newChild.get());
-}
-
-ContainerNode* ContainerNode::legacyParserAddChild(PassRefPtr<Node> newChild)
-{
- ASSERT(newChild);
- // This function is only used during parsing.
- // It does not send any DOM mutation events.
-
- // Check for consistency with DTD, but only when parsing HTML.
- if (document()->isHTMLDocument() && !childAllowed(newChild.get()))
- return 0;
-
- addChildCommon(newChild.get());
-
- if (newChild->isElementNode())
- return static_cast<ContainerNode*>(newChild.get());
- return this;
+ parserAddChild(node);
}
void ContainerNode::suspendPostAttachCallbacks()
diff --git a/WebCore/dom/ContainerNode.h b/WebCore/dom/ContainerNode.h
index a27d95b..ad0a54a 100644
--- a/WebCore/dom/ContainerNode.h
+++ b/WebCore/dom/ContainerNode.h
@@ -48,8 +48,12 @@ public:
virtual bool removeChild(Node* child, ExceptionCode&);
virtual bool appendChild(PassRefPtr<Node> newChild, ExceptionCode&, bool shouldLazyAttach = false);
- virtual ContainerNode* legacyParserAddChild(PassRefPtr<Node>);
- virtual void parserAddChild(PassRefPtr<Node>);
+ // These methods are only used during parsing.
+ // They don't send DOM mutation events or handle reparenting.
+ // However, arbitrary code may be run by beforeload handlers.
+ void parserAddChild(PassRefPtr<Node>);
+ void parserRemoveChild(Node*);
+ void parserInsertBefore(PassRefPtr<Node> newChild, Node* refChild);
bool hasChildNodes() const { return m_firstChild; }
virtual void attach();
@@ -95,8 +99,14 @@ protected:
void setLastChild(Node* child) { m_lastChild = child; }
private:
- // FIXME: This should take a PassRefPtr.
- void addChildCommon(Node*);
+ // Never call this function directly. If you're trying to call this
+ // function, your code is either wrong or you're supposed to call
+ // parserAddChild. Please do not call parserAddChild unless you are the
+ // parser!
+ virtual void deprecatedParserAddChild(PassRefPtr<Node>);
+
+ void removeBetween(Node* previousChild, Node* nextChild, Node* oldChild);
+ void insertBeforeCommon(Node* nextChild, Node* oldChild);
static void dispatchPostAttachCallbacks();
diff --git a/WebCore/dom/DOMImplementation.cpp b/WebCore/dom/DOMImplementation.cpp
index 467f1fc..30e889f 100644
--- a/WebCore/dom/DOMImplementation.cpp
+++ b/WebCore/dom/DOMImplementation.cpp
@@ -258,9 +258,9 @@ PassRefPtr<Document> DOMImplementation::createDocument(const String& namespaceUR
// FIXME: Shouldn't this call appendChild instead?
if (doctype)
- doc->legacyParserAddChild(doctype);
+ doc->parserAddChild(doctype);
if (documentElement)
- doc->legacyParserAddChild(documentElement.release());
+ doc->parserAddChild(documentElement.release());
return doc.release();
}
diff --git a/WebCore/dom/DeviceOrientationController.cpp b/WebCore/dom/DeviceOrientationController.cpp
index 111577f..a744366 100644
--- a/WebCore/dom/DeviceOrientationController.cpp
+++ b/WebCore/dom/DeviceOrientationController.cpp
@@ -44,9 +44,9 @@ DeviceOrientationController::DeviceOrientationController(Page* page, DeviceOrien
void DeviceOrientationController::timerFired(Timer<DeviceOrientationController>* timer)
{
ASSERT_UNUSED(timer, timer == &m_timer);
- ASSERT(!m_client || m_client->lastOrientation());
+ ASSERT(m_client->lastOrientation());
- RefPtr<DeviceOrientation> orientation = m_client ? m_client->lastOrientation() : DeviceOrientation::create();
+ RefPtr<DeviceOrientation> orientation = m_client->lastOrientation();
RefPtr<DeviceOrientationEvent> event = DeviceOrientationEvent::create(eventNames().deviceorientationEvent, orientation.get());
Vector<DOMWindow*> listenersVector;
@@ -58,11 +58,10 @@ void DeviceOrientationController::timerFired(Timer<DeviceOrientationController>*
void DeviceOrientationController::addListener(DOMWindow* window)
{
- // If no client is present, we should fire an event with all parameters null. If
- // the client already has an orientation, we should fire an event with that
- // orientation. In both cases, the event is fired asynchronously, but without
+ // If the client already has an orientation, we should fire an event with that
+ // orientation. The event is fired asynchronously, but without
// waiting for the client to get a new orientation.
- if (!m_client || m_client->lastOrientation()) {
+ if (m_client->lastOrientation()) {
m_newListeners.add(window);
if (!m_timer.isActive())
m_timer.startOneShot(0);
@@ -71,7 +70,7 @@ void DeviceOrientationController::addListener(DOMWindow* window)
// The client must not call back synchronously.
bool wasEmpty = m_listeners.isEmpty();
m_listeners.add(window);
- if (wasEmpty && m_client)
+ if (wasEmpty)
m_client->startUpdating();
}
@@ -79,7 +78,7 @@ void DeviceOrientationController::removeListener(DOMWindow* window)
{
m_listeners.remove(window);
m_newListeners.remove(window);
- if (m_listeners.isEmpty() && m_client)
+ if (m_listeners.isEmpty())
m_client->stopUpdating();
}
@@ -91,7 +90,7 @@ void DeviceOrientationController::removeAllListeners(DOMWindow* window)
m_listeners.removeAll(window);
m_newListeners.remove(window);
- if (m_listeners.isEmpty() && m_client)
+ if (m_listeners.isEmpty())
m_client->stopUpdating();
}
diff --git a/WebCore/dom/Document.cpp b/WebCore/dom/Document.cpp
index 20c6b16..03ad8e7 100644
--- a/WebCore/dom/Document.cpp
+++ b/WebCore/dom/Document.cpp
@@ -89,7 +89,6 @@
#include "InspectorController.h"
#include "InspectorTimelineAgent.h"
#include "KeyboardEvent.h"
-#include "LegacyHTMLTreeBuilder.h"
#include "Logging.h"
#include "MessageEvent.h"
#include "MouseEvent.h"
@@ -123,7 +122,6 @@
#include "StaticHashSetNodeList.h"
#include "StyleSheetList.h"
#include "TextEvent.h"
-#include "TextIterator.h"
#include "TextResourceDecoder.h"
#include "Timer.h"
#include "TransformSource.h"
@@ -165,10 +163,6 @@
#include "XSLTProcessor.h"
#endif
-#if ENABLE(XBL)
-#include "XBLBindingManager.h"
-#endif
-
#if ENABLE(SVG)
#include "SVGDocumentExtensions.h"
#include "SVGElementFactory.h"
@@ -394,9 +388,6 @@ Document::Document(Frame* frame, const KURL& url, bool isXHTML, bool isHTML)
, m_asyncScriptRunner(AsyncScriptRunner::create())
, m_xmlVersion("1.0")
, m_xmlStandalone(false)
-#if ENABLE(XBL)
- , m_bindingManager(new XBLBindingManager(this))
-#endif
, m_savedRenderer(0)
, m_designMode(inherit)
, m_selfOnlyRefCount(0)
@@ -441,8 +432,14 @@ Document::Document(Frame* frame, const KURL& url, bool isXHTML, bool isHTML)
#if !PLATFORM(ANDROID)
m_axObjectCache = 0;
+<<<<<<< HEAD
#endif
+=======
+
+ m_markers = new DocumentMarkerController();
+
+>>>>>>> webkit.org at r66079
m_docLoader = new DocLoader(this);
m_visuallyOrdered = false;
@@ -515,10 +512,9 @@ void Document::removedLastRef()
removeAllChildren();
- deleteAllValues(m_markers);
- m_markers.clear();
+ m_markers->detach();
- m_parser.clear();
+ detachParser();
m_cssCanvasElements.clear();
@@ -551,18 +547,19 @@ Document::~Document()
destroyAllWrapperCaches();
#endif
- m_parser.clear();
+ // Currently we believe that Document can never outlive the parser.
+ // Although the Document may be replaced synchronously, DocumentParsers
+ // generally keep at least one reference to an Element which would in turn
+ // has a reference to the Document. If you hit this ASSERT, then that
+ // assumption is wrong. DocumentParser::detach() should ensure that even
+ // if the DocumentParser outlives the Document it won't cause badness.
+ ASSERT(!m_parser || m_parser->refCount() == 1);
+ detachParser();
m_document = 0;
m_docLoader.clear();
m_renderArena.clear();
-#if ENABLE(XBL)
- m_bindingManager.clear();
-#endif
-
- deleteAllValues(m_markers);
-
clearAXObjectCache();
m_decoder = 0;
@@ -1009,8 +1006,11 @@ void Document::setXMLVersion(const String& version, ExceptionCode& ec)
ec = NOT_SUPPORTED_ERR;
return;
}
-
- // FIXME: Also raise NOT_SUPPORTED_ERR if the version is set to a value that is not supported by this Document.
+
+ if (!XMLDocumentParser::supportsXMLVersion(version)) {
+ ec = NOT_SUPPORTED_ERR;
+ return;
+ }
m_xmlVersion = version;
}
@@ -1514,6 +1514,8 @@ bail_out:
void Document::updateStyleIfNeeded()
{
+ ASSERT(!view() || (!view()->isInLayout() && !view()->isPainting()));
+
if (!childNeedsStyleRecalc() || inPageCache())
return;
@@ -1822,10 +1824,10 @@ void Document::setVisuallyOrdered()
renderer()->style()->setVisuallyOrdered(true);
}
-DocumentParser* Document::createParser()
+PassRefPtr<DocumentParser> Document::createParser()
{
// FIXME: this should probably pass the frame instead
- return new XMLDocumentParser(this, view());
+ return XMLDocumentParser::create(this, view());
}
ScriptableDocumentParser* Document::scriptableDocumentParser() const
@@ -1859,6 +1861,14 @@ void Document::open(Document* ownerDocument)
m_frame->loader()->didExplicitOpen();
}
+void Document::detachParser()
+{
+ if (!m_parser)
+ return;
+ m_parser->detach();
+ m_parser.clear();
+}
+
void Document::cancelParsing()
{
if (m_parser) {
@@ -1866,7 +1876,7 @@ void Document::cancelParsing()
// the onload handler when closing as a side effect of a cancel-style
// change, such as opening a new document or closing the window while
// still parsing
- m_parser.clear();
+ detachParser();
close();
}
}
@@ -1875,8 +1885,6 @@ void Document::implicitOpen()
{
cancelParsing();
- m_parser.clear();
-
removeChildren();
m_parser = createParser();
@@ -1953,6 +1961,26 @@ void Document::close()
}
}
+// FIXME: These settings probably don't work anymore. We should either remove
+// them or make them work properly.
+#ifdef BUILDING_ON_LEOPARD
+static bool shouldCreateImplicitHead(Document* document)
+{
+ ASSERT(document);
+ Settings* settings = document->page() ? document->page()->settings() : 0;
+ return settings ? !settings->needsLeopardMailQuirks() : true;
+}
+#elif defined(BUILDING_ON_TIGER)
+static bool shouldCreateImplicitHead(Document* document)
+{
+ ASSERT(document);
+ Settings* settings = document->page() ? document->page()->settings() : 0;
+ return settings ? !settings->needsTigerMailQuirks() : true;
+}
+#else
+inline bool shouldCreateImplicitHead(Document*) { return true; }
+#endif
+
void Document::implicitClose()
{
// If we're in the middle of recalcStyle, we need to defer the close until the style information is accurate and all elements are re-attached.
@@ -1974,7 +2002,7 @@ void Document::implicitClose()
// We have to clear the parser, in case someone document.write()s from the
// onLoad event handler, as in Radar 3206524.
- m_parser.clear();
+ detachParser();
// Parser should have picked up all preloads by now
m_docLoader->clearPreloads();
@@ -3233,7 +3261,7 @@ void Document::textInserted(Node* text, unsigned offset, unsigned length)
}
// Update the markers for spelling and grammar checking.
- shiftMarkers(text, offset, length);
+ m_markers->shiftMarkers(text, offset, length);
}
void Document::textRemoved(Node* text, unsigned offset, unsigned length)
@@ -3245,8 +3273,8 @@ void Document::textRemoved(Node* text, unsigned offset, unsigned length)
}
// Update the markers for spelling and grammar checking.
- removeMarkers(text, offset, length);
- shiftMarkers(text, offset + length, 0 - length);
+ m_markers->removeMarkers(text, offset, length);
+ m_markers->shiftMarkers(text, offset + length, 0 - length);
}
void Document::textNodesMerged(Text* oldNode, unsigned offset)
@@ -3822,6 +3850,9 @@ static Editor::Command command(Document* document, const String& commandName, bo
Frame* frame = document->frame();
if (!frame || frame->document() != document)
return Editor::Command();
+
+ document->updateStyleIfNeeded();
+
return frame->editor()->command(commandName,
userInterface ? CommandFromDOMWithUserInterface : CommandFromDOM);
}
@@ -3856,489 +3887,6 @@ String Document::queryCommandValue(const String& commandName)
return command(this, commandName).value();
}
-static IntRect placeholderRectForMarker()
-{
- return IntRect(-1, -1, -1, -1);
-}
-
-void Document::addMarker(Range* range, DocumentMarker::MarkerType type, String description)
-{
- // Use a TextIterator to visit the potentially multiple nodes the range covers.
- for (TextIterator markedText(range); !markedText.atEnd(); markedText.advance()) {
- RefPtr<Range> textPiece = markedText.range();
- int exception = 0;
- DocumentMarker marker = {type, textPiece->startOffset(exception), textPiece->endOffset(exception), description, false};
- addMarker(textPiece->startContainer(exception), marker);
- }
-}
-
-void Document::removeMarkers(Range* range, DocumentMarker::MarkerType markerType)
-{
- if (m_markers.isEmpty())
- return;
-
- ExceptionCode ec = 0;
- Node* startContainer = range->startContainer(ec);
- Node* endContainer = range->endContainer(ec);
-
- Node* pastLastNode = range->pastLastNode();
- for (Node* node = range->firstNode(); node != pastLastNode; node = node->traverseNextNode()) {
- int startOffset = node == startContainer ? range->startOffset(ec) : 0;
- int endOffset = node == endContainer ? range->endOffset(ec) : INT_MAX;
- int length = endOffset - startOffset;
- removeMarkers(node, startOffset, length, markerType);
- }
-}
-
-// Markers are stored in order sorted by their start offset.
-// Markers of the same type do not overlap each other.
-
-void Document::addMarker(Node* node, DocumentMarker newMarker)
-{
- ASSERT(newMarker.endOffset >= newMarker.startOffset);
- if (newMarker.endOffset == newMarker.startOffset)
- return;
-
- MarkerMapVectorPair* vectorPair = m_markers.get(node);
-
- if (!vectorPair) {
- vectorPair = new MarkerMapVectorPair;
- vectorPair->first.append(newMarker);
- vectorPair->second.append(placeholderRectForMarker());
- m_markers.set(node, vectorPair);
- } else {
- Vector<DocumentMarker>& markers = vectorPair->first;
- Vector<IntRect>& rects = vectorPair->second;
- size_t numMarkers = markers.size();
- ASSERT(numMarkers == rects.size());
- size_t i;
- // Iterate over all markers whose start offset is less than or equal to the new marker's.
- // If one of them is of the same type as the new marker and touches it or intersects with it
- // (there is at most one), remove it and adjust the new marker's start offset to encompass it.
- for (i = 0; i < numMarkers; ++i) {
- DocumentMarker marker = markers[i];
- if (marker.startOffset > newMarker.startOffset)
- break;
- if (marker.type == newMarker.type && marker.endOffset >= newMarker.startOffset) {
- newMarker.startOffset = marker.startOffset;
- markers.remove(i);
- rects.remove(i);
- numMarkers--;
- break;
- }
- }
- size_t j = i;
- // Iterate over all markers whose end offset is less than or equal to the new marker's,
- // removing markers of the same type as the new marker which touch it or intersect with it,
- // adjusting the new marker's end offset to cover them if necessary.
- while (j < numMarkers) {
- DocumentMarker marker = markers[j];
- if (marker.startOffset > newMarker.endOffset)
- break;
- if (marker.type == newMarker.type) {
- markers.remove(j);
- rects.remove(j);
- if (newMarker.endOffset <= marker.endOffset) {
- newMarker.endOffset = marker.endOffset;
- break;
- }
- numMarkers--;
- } else
- j++;
- }
- // At this point i points to the node before which we want to insert.
- markers.insert(i, newMarker);
- rects.insert(i, placeholderRectForMarker());
- }
-
- // repaint the affected node
- if (node->renderer())
- node->renderer()->repaint();
-}
-
-// copies markers from srcNode to dstNode, applying the specified shift delta to the copies. The shift is
-// useful if, e.g., the caller has created the dstNode from a non-prefix substring of the srcNode.
-void Document::copyMarkers(Node* srcNode, unsigned startOffset, int length, Node* dstNode, int delta, DocumentMarker::MarkerType markerType)
-{
- if (length <= 0)
- return;
-
- MarkerMapVectorPair* vectorPair = m_markers.get(srcNode);
- if (!vectorPair)
- return;
-
- ASSERT(vectorPair->first.size() == vectorPair->second.size());
-
- bool docDirty = false;
- unsigned endOffset = startOffset + length - 1;
- Vector<DocumentMarker>& markers = vectorPair->first;
- for (size_t i = 0; i != markers.size(); ++i) {
- DocumentMarker marker = markers[i];
-
- // stop if we are now past the specified range
- if (marker.startOffset > endOffset)
- break;
-
- // skip marker that is before the specified range or is the wrong type
- if (marker.endOffset < startOffset || (marker.type != markerType && markerType != DocumentMarker::AllMarkers))
- continue;
-
- // pin the marker to the specified range and apply the shift delta
- docDirty = true;
- if (marker.startOffset < startOffset)
- marker.startOffset = startOffset;
- if (marker.endOffset > endOffset)
- marker.endOffset = endOffset;
- marker.startOffset += delta;
- marker.endOffset += delta;
-
- addMarker(dstNode, marker);
- }
-
- // repaint the affected node
- if (docDirty && dstNode->renderer())
- dstNode->renderer()->repaint();
-}
-
-void Document::removeMarkers(Node* node, unsigned startOffset, int length, DocumentMarker::MarkerType markerType)
-{
- if (length <= 0)
- return;
-
- MarkerMapVectorPair* vectorPair = m_markers.get(node);
- if (!vectorPair)
- return;
-
- Vector<DocumentMarker>& markers = vectorPair->first;
- Vector<IntRect>& rects = vectorPair->second;
- ASSERT(markers.size() == rects.size());
- bool docDirty = false;
- unsigned endOffset = startOffset + length;
- for (size_t i = 0; i < markers.size();) {
- DocumentMarker marker = markers[i];
-
- // markers are returned in order, so stop if we are now past the specified range
- if (marker.startOffset >= endOffset)
- break;
-
- // skip marker that is wrong type or before target
- if (marker.endOffset < startOffset || (marker.type != markerType && markerType != DocumentMarker::AllMarkers)) {
- i++;
- continue;
- }
-
- // at this point we know that marker and target intersect in some way
- docDirty = true;
-
- // pitch the old marker and any associated rect
- markers.remove(i);
- rects.remove(i);
-
- // add either of the resulting slices that are left after removing target
- if (startOffset > marker.startOffset) {
- DocumentMarker newLeft = marker;
- newLeft.endOffset = startOffset;
- markers.insert(i, newLeft);
- rects.insert(i, placeholderRectForMarker());
- // i now points to the newly-inserted node, but we want to skip that one
- i++;
- }
- if (marker.endOffset > endOffset) {
- DocumentMarker newRight = marker;
- newRight.startOffset = endOffset;
- markers.insert(i, newRight);
- rects.insert(i, placeholderRectForMarker());
- // i now points to the newly-inserted node, but we want to skip that one
- i++;
- }
- }
-
- if (markers.isEmpty()) {
- ASSERT(rects.isEmpty());
- m_markers.remove(node);
- delete vectorPair;
- }
-
- // repaint the affected node
- if (docDirty && node->renderer())
- node->renderer()->repaint();
-}
-
-DocumentMarker* Document::markerContainingPoint(const IntPoint& point, DocumentMarker::MarkerType markerType)
-{
- // outer loop: process each node that contains any markers
- MarkerMap::iterator end = m_markers.end();
- for (MarkerMap::iterator nodeIterator = m_markers.begin(); nodeIterator != end; ++nodeIterator) {
- // inner loop; process each marker in this node
- MarkerMapVectorPair* vectorPair = nodeIterator->second;
- Vector<DocumentMarker>& markers = vectorPair->first;
- Vector<IntRect>& rects = vectorPair->second;
- ASSERT(markers.size() == rects.size());
- unsigned markerCount = markers.size();
- for (unsigned markerIndex = 0; markerIndex < markerCount; ++markerIndex) {
- DocumentMarker& marker = markers[markerIndex];
-
- // skip marker that is wrong type
- if (marker.type != markerType && markerType != DocumentMarker::AllMarkers)
- continue;
-
- IntRect& r = rects[markerIndex];
-
- // skip placeholder rects
- if (r == placeholderRectForMarker())
- continue;
-
- if (r.contains(point))
- return &marker;
- }
- }
-
- return 0;
-}
-
-Vector<DocumentMarker> Document::markersForNode(Node* node)
-{
- MarkerMapVectorPair* vectorPair = m_markers.get(node);
- if (vectorPair)
- return vectorPair->first;
- return Vector<DocumentMarker>();
-}
-
-Vector<IntRect> Document::renderedRectsForMarkers(DocumentMarker::MarkerType markerType)
-{
- Vector<IntRect> result;
-
- // outer loop: process each node
- MarkerMap::iterator end = m_markers.end();
- for (MarkerMap::iterator nodeIterator = m_markers.begin(); nodeIterator != end; ++nodeIterator) {
- // inner loop; process each marker in this node
- MarkerMapVectorPair* vectorPair = nodeIterator->second;
- Vector<DocumentMarker>& markers = vectorPair->first;
- Vector<IntRect>& rects = vectorPair->second;
- ASSERT(markers.size() == rects.size());
- unsigned markerCount = markers.size();
- for (unsigned markerIndex = 0; markerIndex < markerCount; ++markerIndex) {
- DocumentMarker marker = markers[markerIndex];
-
- // skip marker that is wrong type
- if (marker.type != markerType && markerType != DocumentMarker::AllMarkers)
- continue;
-
- IntRect r = rects[markerIndex];
- // skip placeholder rects
- if (r == placeholderRectForMarker())
- continue;
-
- result.append(r);
- }
- }
-
- return result;
-}
-
-void Document::removeMarkers(Node* node)
-{
- MarkerMap::iterator i = m_markers.find(node);
- if (i != m_markers.end()) {
- delete i->second;
- m_markers.remove(i);
- if (RenderObject* renderer = node->renderer())
- renderer->repaint();
- }
-}
-
-void Document::removeMarkers(DocumentMarker::MarkerType markerType)
-{
- // outer loop: process each markered node in the document
- MarkerMap markerMapCopy = m_markers;
- MarkerMap::iterator end = markerMapCopy.end();
- for (MarkerMap::iterator i = markerMapCopy.begin(); i != end; ++i) {
- Node* node = i->first.get();
- bool nodeNeedsRepaint = false;
-
- // inner loop: process each marker in the current node
- MarkerMapVectorPair* vectorPair = i->second;
- Vector<DocumentMarker>& markers = vectorPair->first;
- Vector<IntRect>& rects = vectorPair->second;
- ASSERT(markers.size() == rects.size());
- for (size_t i = 0; i != markers.size();) {
- DocumentMarker marker = markers[i];
-
- // skip nodes that are not of the specified type
- if (marker.type != markerType && markerType != DocumentMarker::AllMarkers) {
- ++i;
- continue;
- }
-
- // pitch the old marker
- markers.remove(i);
- rects.remove(i);
- nodeNeedsRepaint = true;
- // markerIterator now points to the next node
- }
-
- // Redraw the node if it changed. Do this before the node is removed from m_markers, since
- // m_markers might contain the last reference to the node.
- if (nodeNeedsRepaint) {
- RenderObject* renderer = node->renderer();
- if (renderer)
- renderer->repaint();
- }
-
- // delete the node's list if it is now empty
- if (markers.isEmpty()) {
- ASSERT(rects.isEmpty());
- m_markers.remove(node);
- delete vectorPair;
- }
- }
-}
-
-void Document::repaintMarkers(DocumentMarker::MarkerType markerType)
-{
- // outer loop: process each markered node in the document
- MarkerMap::iterator end = m_markers.end();
- for (MarkerMap::iterator i = m_markers.begin(); i != end; ++i) {
- Node* node = i->first.get();
-
- // inner loop: process each marker in the current node
- MarkerMapVectorPair* vectorPair = i->second;
- Vector<DocumentMarker>& markers = vectorPair->first;
- bool nodeNeedsRepaint = false;
- for (size_t i = 0; i != markers.size(); ++i) {
- DocumentMarker marker = markers[i];
-
- // skip nodes that are not of the specified type
- if (marker.type == markerType || markerType == DocumentMarker::AllMarkers) {
- nodeNeedsRepaint = true;
- break;
- }
- }
-
- if (!nodeNeedsRepaint)
- continue;
-
- // cause the node to be redrawn
- if (RenderObject* renderer = node->renderer())
- renderer->repaint();
- }
-}
-
-void Document::setRenderedRectForMarker(Node* node, const DocumentMarker& marker, const IntRect& r)
-{
- MarkerMapVectorPair* vectorPair = m_markers.get(node);
- if (!vectorPair) {
- ASSERT_NOT_REACHED(); // shouldn't be trying to set the rect for a marker we don't already know about
- return;
- }
-
- Vector<DocumentMarker>& markers = vectorPair->first;
- ASSERT(markers.size() == vectorPair->second.size());
- unsigned markerCount = markers.size();
- for (unsigned markerIndex = 0; markerIndex < markerCount; ++markerIndex) {
- DocumentMarker m = markers[markerIndex];
- if (m == marker) {
- vectorPair->second[markerIndex] = r;
- return;
- }
- }
-
- ASSERT_NOT_REACHED(); // shouldn't be trying to set the rect for a marker we don't already know about
-}
-
-void Document::invalidateRenderedRectsForMarkersInRect(const IntRect& r)
-{
- // outer loop: process each markered node in the document
- MarkerMap::iterator end = m_markers.end();
- for (MarkerMap::iterator i = m_markers.begin(); i != end; ++i) {
-
- // inner loop: process each rect in the current node
- MarkerMapVectorPair* vectorPair = i->second;
- Vector<IntRect>& rects = vectorPair->second;
-
- unsigned rectCount = rects.size();
- for (unsigned rectIndex = 0; rectIndex < rectCount; ++rectIndex)
- if (rects[rectIndex].intersects(r))
- rects[rectIndex] = placeholderRectForMarker();
- }
-}
-
-void Document::shiftMarkers(Node* node, unsigned startOffset, int delta, DocumentMarker::MarkerType markerType)
-{
- MarkerMapVectorPair* vectorPair = m_markers.get(node);
- if (!vectorPair)
- return;
-
- Vector<DocumentMarker>& markers = vectorPair->first;
- Vector<IntRect>& rects = vectorPair->second;
- ASSERT(markers.size() == rects.size());
-
- bool docDirty = false;
- for (size_t i = 0; i != markers.size(); ++i) {
- DocumentMarker& marker = markers[i];
- if (marker.startOffset >= startOffset && (markerType == DocumentMarker::AllMarkers || marker.type == markerType)) {
- ASSERT((int)marker.startOffset + delta >= 0);
- marker.startOffset += delta;
- marker.endOffset += delta;
- docDirty = true;
-
- // Marker moved, so previously-computed rendered rectangle is now invalid
- rects[i] = placeholderRectForMarker();
- }
- }
-
- // repaint the affected node
- if (docDirty && node->renderer())
- node->renderer()->repaint();
-}
-
-void Document::setMarkersActive(Range* range, bool active)
-{
- if (m_markers.isEmpty())
- return;
-
- ExceptionCode ec = 0;
- Node* startContainer = range->startContainer(ec);
- Node* endContainer = range->endContainer(ec);
-
- Node* pastLastNode = range->pastLastNode();
- for (Node* node = range->firstNode(); node != pastLastNode; node = node->traverseNextNode()) {
- int startOffset = node == startContainer ? range->startOffset(ec) : 0;
- int endOffset = node == endContainer ? range->endOffset(ec) : INT_MAX;
- setMarkersActive(node, startOffset, endOffset, active);
- }
-}
-
-void Document::setMarkersActive(Node* node, unsigned startOffset, unsigned endOffset, bool active)
-{
- MarkerMapVectorPair* vectorPair = m_markers.get(node);
- if (!vectorPair)
- return;
-
- Vector<DocumentMarker>& markers = vectorPair->first;
- ASSERT(markers.size() == vectorPair->second.size());
-
- bool docDirty = false;
- for (size_t i = 0; i != markers.size(); ++i) {
- DocumentMarker& marker = markers[i];
-
- // Markers are returned in order, so stop if we are now past the specified range.
- if (marker.startOffset >= endOffset)
- break;
-
- // Skip marker that is wrong type or before target.
- if (marker.endOffset < startOffset || marker.type != DocumentMarker::TextMatch)
- continue;
-
- marker.activeMatch = active;
- docDirty = true;
- }
-
- // repaint the affected node
- if (docDirty && node->renderer())
- node->renderer()->repaint();
-}
-
#if ENABLE(XSLT)
void Document::applyXSLTransform(ProcessingInstruction* pi)
diff --git a/WebCore/dom/Document.h b/WebCore/dom/Document.h
index fc57ddb..ff7e646 100644
--- a/WebCore/dom/Document.h
+++ b/WebCore/dom/Document.h
@@ -32,7 +32,7 @@
#include "CollectionType.h"
#include "Color.h"
#include "ContainerNode.h"
-#include "DocumentMarker.h"
+#include "DocumentMarkerController.h"
#include "QualifiedName.h"
#include "ScriptExecutionContext.h"
#include "Timer.h"
@@ -125,10 +125,6 @@ class SVGDocumentExtensions;
class TransformSource;
#endif
-#if ENABLE(XBL)
-class XBLBindingManager;
-#endif
-
#if ENABLE(XPATH)
class XPathEvaluator;
class XPathExpression;
@@ -563,7 +559,7 @@ public:
CSSStyleSheet* elementSheet();
CSSStyleSheet* mappedElementSheet();
- virtual DocumentParser* createParser();
+ virtual PassRefPtr<DocumentParser> createParser();
DocumentParser* parser() const { return m_parser.get(); }
ScriptableDocumentParser* scriptableDocumentParser() const;
@@ -819,6 +815,8 @@ public:
HTMLHeadElement* head();
+ DocumentMarkerController* markers() const { return m_markers.get(); }
+
bool execCommand(const String& command, bool userInterface = false, const String& value = String());
bool queryCommandEnabled(const String& command);
bool queryCommandIndeterm(const String& command);
@@ -826,24 +824,6 @@ public:
bool queryCommandSupported(const String& command);
String queryCommandValue(const String& command);
- void addMarker(Range*, DocumentMarker::MarkerType, String description = String());
- void addMarker(Node*, DocumentMarker);
- void copyMarkers(Node *srcNode, unsigned startOffset, int length, Node *dstNode, int delta, DocumentMarker::MarkerType = DocumentMarker::AllMarkers);
- void removeMarkers(Range*, DocumentMarker::MarkerType = DocumentMarker::AllMarkers);
- void removeMarkers(Node*, unsigned startOffset, int length, DocumentMarker::MarkerType = DocumentMarker::AllMarkers);
- void removeMarkers(DocumentMarker::MarkerType = DocumentMarker::AllMarkers);
- void removeMarkers(Node*);
- void repaintMarkers(DocumentMarker::MarkerType = DocumentMarker::AllMarkers);
- void setRenderedRectForMarker(Node*, const DocumentMarker&, const IntRect&);
- void invalidateRenderedRectsForMarkersInRect(const IntRect&);
- void shiftMarkers(Node*, unsigned startOffset, int delta, DocumentMarker::MarkerType = DocumentMarker::AllMarkers);
- void setMarkersActive(Range*, bool);
- void setMarkersActive(Node*, unsigned startOffset, unsigned endOffset, bool);
-
- DocumentMarker* markerContainingPoint(const IntPoint&, DocumentMarker::MarkerType = DocumentMarker::AllMarkers);
- Vector<DocumentMarker> markersForNode(Node*);
- Vector<IntRect> renderedRectsForMarkers(DocumentMarker::MarkerType = DocumentMarker::AllMarkers);
-
// designMode support
enum InheritedBool { off = false, on = true, inherit };
void setDesignMode(InheritedBool value);
@@ -866,11 +846,6 @@ public:
TransformSource* transformSource() const { return m_transformSource.get(); }
#endif
-#if ENABLE(XBL)
- // XBL methods
- XBLBindingManager* bindingManager() const { return m_bindingManager.get(); }
-#endif
-
void incDOMTreeVersion() { ++m_domTreeVersion; }
unsigned domTreeVersion() const { return m_domTreeVersion; }
@@ -1035,6 +1010,7 @@ protected:
private:
+ void detachParser();
typedef void (*ArgumentsCallback)(const String& keyString, const String& valueString, Document*, void* data);
void processArguments(const String& features, void* data, ArgumentsCallback);
@@ -1079,7 +1055,7 @@ private:
Frame* m_frame;
OwnPtr<DocLoader> m_docLoader;
- OwnPtr<DocumentParser> m_parser;
+ RefPtr<DocumentParser> m_parser;
bool m_wellFormed;
// Document URLs.
@@ -1193,6 +1169,7 @@ private:
OwnPtr<RenderArena> m_renderArena;
+<<<<<<< HEAD
typedef std::pair<Vector<DocumentMarker>, Vector<IntRect> > MarkerMapVectorPair;
typedef HashMap<RefPtr<Node>, MarkerMapVectorPair*> MarkerMap;
MarkerMap m_markers;
@@ -1200,6 +1177,10 @@ private:
#if !PLATFORM(ANDROID)
mutable AXObjectCache* m_axObjectCache;
#endif
+=======
+ mutable AXObjectCache* m_axObjectCache;
+ OwnPtr<DocumentMarkerController> m_markers;
+>>>>>>> webkit.org at r66079
Timer<Document> m_updateFocusAppearanceTimer;
@@ -1221,10 +1202,13 @@ private:
RefPtr<Document> m_transformSourceDocument;
#endif
+<<<<<<< HEAD
#if ENABLE(XBL)
OwnPtr<XBLBindingManager> m_bindingManager; // The access point through which documents and elements communicate with XBL.
#endif
+=======
+>>>>>>> webkit.org at r66079
typedef HashMap<AtomicStringImpl*, HTMLMapElement*> ImageMapsByName;
ImageMapsByName m_imageMapsByName;
@@ -1327,7 +1311,7 @@ inline bool Node::isDocumentNode() const
// here because it uses a Document method but we really want to inline it
inline Node::Node(Document* document, ConstructionType type)
- : TreeShared<Node>(initialRefCount(type))
+ : TreeShared<ContainerNode>(initialRefCount(type))
, m_document(document)
, m_previous(0)
, m_next(0)
diff --git a/WebCore/dom/DocumentFragment.cpp b/WebCore/dom/DocumentFragment.cpp
index 70e57b9..c9c3020 100644
--- a/WebCore/dom/DocumentFragment.cpp
+++ b/WebCore/dom/DocumentFragment.cpp
@@ -75,12 +75,6 @@ PassRefPtr<Node> DocumentFragment::cloneNode(bool deep)
return clone.release();
}
-bool DocumentFragment::shouldUseLegacyHTMLParser() const
-{
- return document()->page() && document()->page()->settings()
- && !document()->page()->settings()->html5ParserEnabled();
-}
-
void DocumentFragment::parseHTML(const String& source, Element* contextElement, FragmentScriptingPermission scriptingPermission)
{
HTMLDocumentParser::parseDocumentFragment(source, this, contextElement, scriptingPermission);
diff --git a/WebCore/dom/DocumentFragment.h b/WebCore/dom/DocumentFragment.h
index d3dadb8..d588b4e 100644
--- a/WebCore/dom/DocumentFragment.h
+++ b/WebCore/dom/DocumentFragment.h
@@ -39,8 +39,6 @@ public:
private:
DocumentFragment(Document*);
- bool shouldUseLegacyHTMLParser() const;
-
virtual String nodeName() const;
virtual NodeType nodeType() const;
virtual PassRefPtr<Node> cloneNode(bool deep);
diff --git a/WebCore/dom/DocumentMarkerController.cpp b/WebCore/dom/DocumentMarkerController.cpp
new file mode 100644
index 0000000..2b7fd85
--- /dev/null
+++ b/WebCore/dom/DocumentMarkerController.cpp
@@ -0,0 +1,527 @@
+/*
+ * 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 Apple Inc. All rights reserved.
+ * Copyright (C) 2008, 2009 Torch Mobile Inc. All rights reserved. (http://www.torchmobile.com/)
+ * Copyright (C) Research In Motion Limited 2010. 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 "DocumentMarkerController.h"
+
+#include "Node.h"
+#include "Range.h"
+#include "TextIterator.h"
+
+namespace WebCore {
+
+static IntRect placeholderRectForMarker()
+{
+ return IntRect(-1, -1, -1, -1);
+}
+
+void DocumentMarkerController::detach()
+{
+ if (m_markers.isEmpty())
+ return;
+ deleteAllValues(m_markers);
+ m_markers.clear();
+}
+
+void DocumentMarkerController::addMarker(Range* range, DocumentMarker::MarkerType type, String description)
+{
+ // Use a TextIterator to visit the potentially multiple nodes the range covers.
+ for (TextIterator markedText(range); !markedText.atEnd(); markedText.advance()) {
+ RefPtr<Range> textPiece = markedText.range();
+ int exception = 0;
+ DocumentMarker marker = {type, textPiece->startOffset(exception), textPiece->endOffset(exception), description, false};
+ addMarker(textPiece->startContainer(exception), marker);
+ }
+}
+
+void DocumentMarkerController::removeMarkers(Range* range, DocumentMarker::MarkerType markerType)
+{
+ if (m_markers.isEmpty())
+ return;
+
+ ExceptionCode ec = 0;
+ Node* startContainer = range->startContainer(ec);
+ Node* endContainer = range->endContainer(ec);
+
+ Node* pastLastNode = range->pastLastNode();
+ for (Node* node = range->firstNode(); node != pastLastNode; node = node->traverseNextNode()) {
+ int startOffset = node == startContainer ? range->startOffset(ec) : 0;
+ int endOffset = node == endContainer ? range->endOffset(ec) : INT_MAX;
+ int length = endOffset - startOffset;
+ removeMarkers(node, startOffset, length, markerType);
+ }
+}
+
+// Markers are stored in order sorted by their start offset.
+// Markers of the same type do not overlap each other.
+
+void DocumentMarkerController::addMarker(Node* node, DocumentMarker newMarker)
+{
+ ASSERT(newMarker.endOffset >= newMarker.startOffset);
+ if (newMarker.endOffset == newMarker.startOffset)
+ return;
+
+ MarkerMapVectorPair* vectorPair = m_markers.get(node);
+
+ if (!vectorPair) {
+ vectorPair = new MarkerMapVectorPair;
+ vectorPair->first.append(newMarker);
+ vectorPair->second.append(placeholderRectForMarker());
+ m_markers.set(node, vectorPair);
+ } else {
+ Vector<DocumentMarker>& markers = vectorPair->first;
+ Vector<IntRect>& rects = vectorPair->second;
+ size_t numMarkers = markers.size();
+ ASSERT(numMarkers == rects.size());
+ size_t i;
+ // Iterate over all markers whose start offset is less than or equal to the new marker's.
+ // If one of them is of the same type as the new marker and touches it or intersects with it
+ // (there is at most one), remove it and adjust the new marker's start offset to encompass it.
+ for (i = 0; i < numMarkers; ++i) {
+ DocumentMarker marker = markers[i];
+ if (marker.startOffset > newMarker.startOffset)
+ break;
+ if (marker.type == newMarker.type && marker.endOffset >= newMarker.startOffset) {
+ newMarker.startOffset = marker.startOffset;
+ markers.remove(i);
+ rects.remove(i);
+ numMarkers--;
+ break;
+ }
+ }
+ size_t j = i;
+ // Iterate over all markers whose end offset is less than or equal to the new marker's,
+ // removing markers of the same type as the new marker which touch it or intersect with it,
+ // adjusting the new marker's end offset to cover them if necessary.
+ while (j < numMarkers) {
+ DocumentMarker marker = markers[j];
+ if (marker.startOffset > newMarker.endOffset)
+ break;
+ if (marker.type == newMarker.type) {
+ markers.remove(j);
+ rects.remove(j);
+ if (newMarker.endOffset <= marker.endOffset) {
+ newMarker.endOffset = marker.endOffset;
+ break;
+ }
+ numMarkers--;
+ } else
+ j++;
+ }
+ // At this point i points to the node before which we want to insert.
+ markers.insert(i, newMarker);
+ rects.insert(i, placeholderRectForMarker());
+ }
+
+ // repaint the affected node
+ if (node->renderer())
+ node->renderer()->repaint();
+}
+
+// copies markers from srcNode to dstNode, applying the specified shift delta to the copies. The shift is
+// useful if, e.g., the caller has created the dstNode from a non-prefix substring of the srcNode.
+void DocumentMarkerController::copyMarkers(Node* srcNode, unsigned startOffset, int length, Node* dstNode, int delta, DocumentMarker::MarkerType markerType)
+{
+ if (length <= 0)
+ return;
+
+ MarkerMapVectorPair* vectorPair = m_markers.get(srcNode);
+ if (!vectorPair)
+ return;
+
+ ASSERT(vectorPair->first.size() == vectorPair->second.size());
+
+ bool docDirty = false;
+ unsigned endOffset = startOffset + length - 1;
+ Vector<DocumentMarker>& markers = vectorPair->first;
+ for (size_t i = 0; i != markers.size(); ++i) {
+ DocumentMarker marker = markers[i];
+
+ // stop if we are now past the specified range
+ if (marker.startOffset > endOffset)
+ break;
+
+ // skip marker that is before the specified range or is the wrong type
+ if (marker.endOffset < startOffset || (marker.type != markerType && markerType != DocumentMarker::AllMarkers))
+ continue;
+
+ // pin the marker to the specified range and apply the shift delta
+ docDirty = true;
+ if (marker.startOffset < startOffset)
+ marker.startOffset = startOffset;
+ if (marker.endOffset > endOffset)
+ marker.endOffset = endOffset;
+ marker.startOffset += delta;
+ marker.endOffset += delta;
+
+ addMarker(dstNode, marker);
+ }
+
+ // repaint the affected node
+ if (docDirty && dstNode->renderer())
+ dstNode->renderer()->repaint();
+}
+
+void DocumentMarkerController::removeMarkers(Node* node, unsigned startOffset, int length, DocumentMarker::MarkerType markerType)
+{
+ if (length <= 0)
+ return;
+
+ MarkerMapVectorPair* vectorPair = m_markers.get(node);
+ if (!vectorPair)
+ return;
+
+ Vector<DocumentMarker>& markers = vectorPair->first;
+ Vector<IntRect>& rects = vectorPair->second;
+ ASSERT(markers.size() == rects.size());
+ bool docDirty = false;
+ unsigned endOffset = startOffset + length;
+ for (size_t i = 0; i < markers.size();) {
+ DocumentMarker marker = markers[i];
+
+ // markers are returned in order, so stop if we are now past the specified range
+ if (marker.startOffset >= endOffset)
+ break;
+
+ // skip marker that is wrong type or before target
+ if (marker.endOffset < startOffset || (marker.type != markerType && markerType != DocumentMarker::AllMarkers)) {
+ i++;
+ continue;
+ }
+
+ // at this point we know that marker and target intersect in some way
+ docDirty = true;
+
+ // pitch the old marker and any associated rect
+ markers.remove(i);
+ rects.remove(i);
+
+ // add either of the resulting slices that are left after removing target
+ if (startOffset > marker.startOffset) {
+ DocumentMarker newLeft = marker;
+ newLeft.endOffset = startOffset;
+ markers.insert(i, newLeft);
+ rects.insert(i, placeholderRectForMarker());
+ // i now points to the newly-inserted node, but we want to skip that one
+ i++;
+ }
+ if (marker.endOffset > endOffset) {
+ DocumentMarker newRight = marker;
+ newRight.startOffset = endOffset;
+ markers.insert(i, newRight);
+ rects.insert(i, placeholderRectForMarker());
+ // i now points to the newly-inserted node, but we want to skip that one
+ i++;
+ }
+ }
+
+ if (markers.isEmpty()) {
+ ASSERT(rects.isEmpty());
+ m_markers.remove(node);
+ delete vectorPair;
+ }
+
+ // repaint the affected node
+ if (docDirty && node->renderer())
+ node->renderer()->repaint();
+}
+
+DocumentMarker* DocumentMarkerController::markerContainingPoint(const IntPoint& point, DocumentMarker::MarkerType markerType)
+{
+ // outer loop: process each node that contains any markers
+ MarkerMap::iterator end = m_markers.end();
+ for (MarkerMap::iterator nodeIterator = m_markers.begin(); nodeIterator != end; ++nodeIterator) {
+ // inner loop; process each marker in this node
+ MarkerMapVectorPair* vectorPair = nodeIterator->second;
+ Vector<DocumentMarker>& markers = vectorPair->first;
+ Vector<IntRect>& rects = vectorPair->second;
+ ASSERT(markers.size() == rects.size());
+ unsigned markerCount = markers.size();
+ for (unsigned markerIndex = 0; markerIndex < markerCount; ++markerIndex) {
+ DocumentMarker& marker = markers[markerIndex];
+
+ // skip marker that is wrong type
+ if (marker.type != markerType && markerType != DocumentMarker::AllMarkers)
+ continue;
+
+ IntRect& r = rects[markerIndex];
+
+ // skip placeholder rects
+ if (r == placeholderRectForMarker())
+ continue;
+
+ if (r.contains(point))
+ return &marker;
+ }
+ }
+
+ return 0;
+}
+
+Vector<DocumentMarker> DocumentMarkerController::markersForNode(Node* node)
+{
+ MarkerMapVectorPair* vectorPair = m_markers.get(node);
+ if (vectorPair)
+ return vectorPair->first;
+ return Vector<DocumentMarker>();
+}
+
+Vector<IntRect> DocumentMarkerController::renderedRectsForMarkers(DocumentMarker::MarkerType markerType)
+{
+ Vector<IntRect> result;
+
+ // outer loop: process each node
+ MarkerMap::iterator end = m_markers.end();
+ for (MarkerMap::iterator nodeIterator = m_markers.begin(); nodeIterator != end; ++nodeIterator) {
+ // inner loop; process each marker in this node
+ MarkerMapVectorPair* vectorPair = nodeIterator->second;
+ Vector<DocumentMarker>& markers = vectorPair->first;
+ Vector<IntRect>& rects = vectorPair->second;
+ ASSERT(markers.size() == rects.size());
+ unsigned markerCount = markers.size();
+ for (unsigned markerIndex = 0; markerIndex < markerCount; ++markerIndex) {
+ DocumentMarker marker = markers[markerIndex];
+
+ // skip marker that is wrong type
+ if (marker.type != markerType && markerType != DocumentMarker::AllMarkers)
+ continue;
+
+ IntRect r = rects[markerIndex];
+ // skip placeholder rects
+ if (r == placeholderRectForMarker())
+ continue;
+
+ result.append(r);
+ }
+ }
+
+ return result;
+}
+
+void DocumentMarkerController::removeMarkers(Node* node)
+{
+ MarkerMap::iterator i = m_markers.find(node);
+ if (i != m_markers.end()) {
+ delete i->second;
+ m_markers.remove(i);
+ if (RenderObject* renderer = node->renderer())
+ renderer->repaint();
+ }
+}
+
+void DocumentMarkerController::removeMarkers(DocumentMarker::MarkerType markerType)
+{
+ // outer loop: process each markered node in the document
+ MarkerMap markerMapCopy = m_markers;
+ MarkerMap::iterator end = markerMapCopy.end();
+ for (MarkerMap::iterator i = markerMapCopy.begin(); i != end; ++i) {
+ Node* node = i->first.get();
+ bool nodeNeedsRepaint = false;
+
+ // inner loop: process each marker in the current node
+ MarkerMapVectorPair* vectorPair = i->second;
+ Vector<DocumentMarker>& markers = vectorPair->first;
+ Vector<IntRect>& rects = vectorPair->second;
+ ASSERT(markers.size() == rects.size());
+ for (size_t i = 0; i != markers.size();) {
+ DocumentMarker marker = markers[i];
+
+ // skip nodes that are not of the specified type
+ if (marker.type != markerType && markerType != DocumentMarker::AllMarkers) {
+ ++i;
+ continue;
+ }
+
+ // pitch the old marker
+ markers.remove(i);
+ rects.remove(i);
+ nodeNeedsRepaint = true;
+ // markerIterator now points to the next node
+ }
+
+ // Redraw the node if it changed. Do this before the node is removed from m_markers, since
+ // m_markers might contain the last reference to the node.
+ if (nodeNeedsRepaint) {
+ RenderObject* renderer = node->renderer();
+ if (renderer)
+ renderer->repaint();
+ }
+
+ // delete the node's list if it is now empty
+ if (markers.isEmpty()) {
+ ASSERT(rects.isEmpty());
+ m_markers.remove(node);
+ delete vectorPair;
+ }
+ }
+}
+
+void DocumentMarkerController::repaintMarkers(DocumentMarker::MarkerType markerType)
+{
+ // outer loop: process each markered node in the document
+ MarkerMap::iterator end = m_markers.end();
+ for (MarkerMap::iterator i = m_markers.begin(); i != end; ++i) {
+ Node* node = i->first.get();
+
+ // inner loop: process each marker in the current node
+ MarkerMapVectorPair* vectorPair = i->second;
+ Vector<DocumentMarker>& markers = vectorPair->first;
+ bool nodeNeedsRepaint = false;
+ for (size_t i = 0; i != markers.size(); ++i) {
+ DocumentMarker marker = markers[i];
+
+ // skip nodes that are not of the specified type
+ if (marker.type == markerType || markerType == DocumentMarker::AllMarkers) {
+ nodeNeedsRepaint = true;
+ break;
+ }
+ }
+
+ if (!nodeNeedsRepaint)
+ continue;
+
+ // cause the node to be redrawn
+ if (RenderObject* renderer = node->renderer())
+ renderer->repaint();
+ }
+}
+
+void DocumentMarkerController::setRenderedRectForMarker(Node* node, const DocumentMarker& marker, const IntRect& r)
+{
+ MarkerMapVectorPair* vectorPair = m_markers.get(node);
+ if (!vectorPair) {
+ ASSERT_NOT_REACHED(); // shouldn't be trying to set the rect for a marker we don't already know about
+ return;
+ }
+
+ Vector<DocumentMarker>& markers = vectorPair->first;
+ ASSERT(markers.size() == vectorPair->second.size());
+ unsigned markerCount = markers.size();
+ for (unsigned markerIndex = 0; markerIndex < markerCount; ++markerIndex) {
+ DocumentMarker m = markers[markerIndex];
+ if (m == marker) {
+ vectorPair->second[markerIndex] = r;
+ return;
+ }
+ }
+
+ ASSERT_NOT_REACHED(); // shouldn't be trying to set the rect for a marker we don't already know about
+}
+
+void DocumentMarkerController::invalidateRenderedRectsForMarkersInRect(const IntRect& r)
+{
+ // outer loop: process each markered node in the document
+ MarkerMap::iterator end = m_markers.end();
+ for (MarkerMap::iterator i = m_markers.begin(); i != end; ++i) {
+
+ // inner loop: process each rect in the current node
+ MarkerMapVectorPair* vectorPair = i->second;
+ Vector<IntRect>& rects = vectorPair->second;
+
+ unsigned rectCount = rects.size();
+ for (unsigned rectIndex = 0; rectIndex < rectCount; ++rectIndex)
+ if (rects[rectIndex].intersects(r))
+ rects[rectIndex] = placeholderRectForMarker();
+ }
+}
+
+void DocumentMarkerController::shiftMarkers(Node* node, unsigned startOffset, int delta, DocumentMarker::MarkerType markerType)
+{
+ MarkerMapVectorPair* vectorPair = m_markers.get(node);
+ if (!vectorPair)
+ return;
+
+ Vector<DocumentMarker>& markers = vectorPair->first;
+ Vector<IntRect>& rects = vectorPair->second;
+ ASSERT(markers.size() == rects.size());
+
+ bool docDirty = false;
+ for (size_t i = 0; i != markers.size(); ++i) {
+ DocumentMarker& marker = markers[i];
+ if (marker.startOffset >= startOffset && (markerType == DocumentMarker::AllMarkers || marker.type == markerType)) {
+ ASSERT((int)marker.startOffset + delta >= 0);
+ marker.startOffset += delta;
+ marker.endOffset += delta;
+ docDirty = true;
+
+ // Marker moved, so previously-computed rendered rectangle is now invalid
+ rects[i] = placeholderRectForMarker();
+ }
+ }
+
+ // repaint the affected node
+ if (docDirty && node->renderer())
+ node->renderer()->repaint();
+}
+
+void DocumentMarkerController::setMarkersActive(Range* range, bool active)
+{
+ if (m_markers.isEmpty())
+ return;
+
+ ExceptionCode ec = 0;
+ Node* startContainer = range->startContainer(ec);
+ Node* endContainer = range->endContainer(ec);
+
+ Node* pastLastNode = range->pastLastNode();
+ for (Node* node = range->firstNode(); node != pastLastNode; node = node->traverseNextNode()) {
+ int startOffset = node == startContainer ? range->startOffset(ec) : 0;
+ int endOffset = node == endContainer ? range->endOffset(ec) : INT_MAX;
+ setMarkersActive(node, startOffset, endOffset, active);
+ }
+}
+
+void DocumentMarkerController::setMarkersActive(Node* node, unsigned startOffset, unsigned endOffset, bool active)
+{
+ MarkerMapVectorPair* vectorPair = m_markers.get(node);
+ if (!vectorPair)
+ return;
+
+ Vector<DocumentMarker>& markers = vectorPair->first;
+ ASSERT(markers.size() == vectorPair->second.size());
+
+ bool docDirty = false;
+ for (size_t i = 0; i != markers.size(); ++i) {
+ DocumentMarker& marker = markers[i];
+
+ // Markers are returned in order, so stop if we are now past the specified range.
+ if (marker.startOffset >= endOffset)
+ break;
+
+ // Skip marker that is wrong type or before target.
+ if (marker.endOffset < startOffset || marker.type != DocumentMarker::TextMatch)
+ continue;
+
+ marker.activeMatch = active;
+ docDirty = true;
+ }
+
+ // repaint the affected node
+ if (docDirty && node->renderer())
+ node->renderer()->repaint();
+}
+
+} // namespace WebCore
diff --git a/WebCore/dom/DocumentMarkerController.h b/WebCore/dom/DocumentMarkerController.h
new file mode 100644
index 0000000..8921baa
--- /dev/null
+++ b/WebCore/dom/DocumentMarkerController.h
@@ -0,0 +1,72 @@
+/*
+ * 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 Apple Inc. All rights reserved.
+ * Copyright (C) 2008, 2009 Torch Mobile Inc. All rights reserved. (http://www.torchmobile.com/)
+ * Copyright (C) Research In Motion Limited 2010. 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 DocumentMarkerController_h
+#define DocumentMarkerController_h
+
+#include "DocumentMarker.h"
+#include <wtf/HashMap.h>
+#include <wtf/Vector.h>
+
+namespace WebCore {
+
+class IntPoint;
+class IntRect;
+class Node;
+class Range;
+
+class DocumentMarkerController : public Noncopyable {
+public:
+ ~DocumentMarkerController() { detach(); }
+
+ void detach();
+ void addMarker(Range*, DocumentMarker::MarkerType, String description = String());
+ void addMarker(Node*, DocumentMarker);
+ void copyMarkers(Node* srcNode, unsigned startOffset, int length, Node* dstNode, int delta, DocumentMarker::MarkerType = DocumentMarker::AllMarkers);
+ void removeMarkers(Range*, DocumentMarker::MarkerType = DocumentMarker::AllMarkers);
+ void removeMarkers(Node*, unsigned startOffset, int length, DocumentMarker::MarkerType = DocumentMarker::AllMarkers);
+ void removeMarkers(DocumentMarker::MarkerType = DocumentMarker::AllMarkers);
+ void removeMarkers(Node*);
+ void repaintMarkers(DocumentMarker::MarkerType = DocumentMarker::AllMarkers);
+ void setRenderedRectForMarker(Node*, const DocumentMarker&, const IntRect&);
+ void invalidateRenderedRectsForMarkersInRect(const IntRect&);
+ void shiftMarkers(Node*, unsigned startOffset, int delta, DocumentMarker::MarkerType = DocumentMarker::AllMarkers);
+ void setMarkersActive(Range*, bool);
+ void setMarkersActive(Node*, unsigned startOffset, unsigned endOffset, bool);
+
+ DocumentMarker* markerContainingPoint(const IntPoint&, DocumentMarker::MarkerType = DocumentMarker::AllMarkers);
+ Vector<DocumentMarker> markersForNode(Node*);
+ Vector<IntRect> renderedRectsForMarkers(DocumentMarker::MarkerType = DocumentMarker::AllMarkers);
+
+private:
+ typedef std::pair<Vector<DocumentMarker>, Vector<IntRect> > MarkerMapVectorPair;
+ typedef HashMap<RefPtr<Node>, MarkerMapVectorPair*> MarkerMap;
+ MarkerMap m_markers;
+};
+
+} // namespace WebCore
+
+#endif // DocumentMarkerController_h
diff --git a/WebCore/dom/DocumentParser.cpp b/WebCore/dom/DocumentParser.cpp
index b80927c..cc4c61b 100644
--- a/WebCore/dom/DocumentParser.cpp
+++ b/WebCore/dom/DocumentParser.cpp
@@ -37,5 +37,18 @@ DocumentParser::DocumentParser(Document* document)
ASSERT(document);
}
+DocumentParser::~DocumentParser()
+{
+ // Document is expected to call detach() before releasing its ref.
+ // This ASSERT is slightly awkward for parsers with a fragment case
+ // as there is no Document to release the ref.
+ ASSERT(!m_document);
+}
+
+void DocumentParser::detach()
+{
+ m_document = 0;
+}
+
};
diff --git a/WebCore/dom/DocumentParser.h b/WebCore/dom/DocumentParser.h
index e942d1f..3c28856 100644
--- a/WebCore/dom/DocumentParser.h
+++ b/WebCore/dom/DocumentParser.h
@@ -24,19 +24,18 @@
#ifndef DocumentParser_h
#define DocumentParser_h
-#include <wtf/Noncopyable.h>
+#include <wtf/RefCounted.h>
namespace WebCore {
class Document;
class DocumentWriter;
-class LegacyHTMLTreeBuilder;
class SegmentedString;
class ScriptableDocumentParser;
-class DocumentParser : public Noncopyable {
+class DocumentParser : public RefCounted<DocumentParser> {
public:
- virtual ~DocumentParser() { }
+ virtual ~DocumentParser();
virtual ScriptableDocumentParser* asScriptableDocumentParser() { return 0; }
@@ -56,17 +55,27 @@ public:
virtual void finish() = 0;
virtual bool finishWasCalled() = 0;
- virtual void stopParsing() { m_parserStopped = true; }
// FIXME: processingData() is only used by DocumentLoader::isLoadingInAPISense
// and is very unclear as to what it actually means. The LegacyHTMLDocumentParser
// used to implements it.
virtual bool processingData() const { return false; }
- // FIXME: Exposed for HTMLFormControlElement::removedFromTree. HTML DOM
- // code should not need to reach into implementation details of the parser.
- virtual LegacyHTMLTreeBuilder* htmlTreeBuilder() const { return 0; }
-
- Document* document() const { return m_document; }
+ // document() will return 0 after detach() is called.
+ Document* document() const { ASSERT(m_document); return m_document; }
+ bool isDetached() const { return !m_document; }
+
+ // Document is expected to detach the parser before releasing its ref.
+ // After detach, m_document is cleared. The parser will unwind its
+ // callstacks, but not produce any more nodes.
+ // It is impossible for the parser to touch the rest of WebCore after
+ // detach is called.
+ virtual void detach();
+
+ // stopParsing() is used when a load is canceled/stopped.
+ // stopParsing() is currently different from detach(), but shouldn't be.
+ // It should NOT be ok to call any methods on DocumentParser after either
+ // detach() or stopParsing() but right now only detach() will ASSERT.
+ virtual void stopParsing() { m_parserStopped = true; }
protected:
DocumentParser(Document*);
@@ -74,9 +83,12 @@ protected:
// The parser has buffers, so parsing may continue even after
// it stops receiving data. We use m_parserStopped to stop the parser
// even when it has buffered data.
+ // FIXME: m_document = 0 could be changed to mean "parser stopped".
bool m_parserStopped;
+private:
// Every DocumentParser needs a pointer back to the document.
+ // m_document will be 0 after the parser is stopped.
Document* m_document;
};
diff --git a/WebCore/dom/Element.cpp b/WebCore/dom/Element.cpp
index 849b900..2d44f62 100644
--- a/WebCore/dom/Element.cpp
+++ b/WebCore/dom/Element.cpp
@@ -1213,6 +1213,11 @@ void Element::setAttributeNS(const AtomicString& namespaceURI, const AtomicStrin
if (!Document::parseQualifiedName(qualifiedName, prefix, localName, ec))
return;
+ if (namespaceURI.isNull() && !prefix.isNull()) {
+ ec = NAMESPACE_ERR;
+ return;
+ }
+
QualifiedName qName(prefix, localName, namespaceURI);
if (scriptingPermission == FragmentScriptingNotAllowed && (isEventHandlerAttribute(qName) || isAttributeToRemove(qName, value)))
@@ -1293,9 +1298,6 @@ void Element::focus(bool restorePreviousSelection)
if (doc->focusedNode() == this)
return;
- if (!supportsFocus())
- return;
-
// If the stylesheets have already been loaded we can reliably check isFocusable.
// If not, we continue and set the focused node on the focus controller below so
// that it can be updated soon after attach.
@@ -1305,6 +1307,9 @@ void Element::focus(bool restorePreviousSelection)
return;
}
+ if (!supportsFocus())
+ return;
+
RefPtr<Node> protect;
if (Page* page = doc->page()) {
// Focus and change event handlers can cause us to lose our last ref.
diff --git a/WebCore/dom/EventNames.h b/WebCore/dom/EventNames.h
index 4c5a08a..85fe69b 100644
--- a/WebCore/dom/EventNames.h
+++ b/WebCore/dom/EventNames.h
@@ -103,6 +103,9 @@ namespace WebCore {
macro(textInput) \
macro(unload) \
macro(updateready) \
+ macro(write) \
+ macro(writeend) \
+ macro(writestart) \
macro(zoom) \
\
macro(DOMActivate) \
diff --git a/WebCore/dom/EventTarget.cpp b/WebCore/dom/EventTarget.cpp
index 42a153a..effd2a2 100644
--- a/WebCore/dom/EventTarget.cpp
+++ b/WebCore/dom/EventTarget.cpp
@@ -162,12 +162,22 @@ FileReader* EventTarget::toFileReader()
return 0;
}
#endif
+#if ENABLE(FILE_WRITER)
+FileWriter* EventTarget::toFileWriter()
+{
+ return 0;
+}
+#endif
#if ENABLE(INDEXED_DATABASE)
IDBRequest* EventTarget::toIDBRequest()
{
return 0;
}
+IDBTransaction* EventTarget::toIDBTransaction()
+{
+ return 0;
+}
#endif
bool EventTarget::addEventListener(const AtomicString& eventType, PassRefPtr<EventListener> listener, bool useCapture)
diff --git a/WebCore/dom/EventTarget.h b/WebCore/dom/EventTarget.h
index b4aa542..b2985f7 100644
--- a/WebCore/dom/EventTarget.h
+++ b/WebCore/dom/EventTarget.h
@@ -48,7 +48,9 @@ namespace WebCore {
class EventListener;
class EventSource;
class FileReader;
+ class FileWriter;
class IDBRequest;
+ class IDBTransaction;
class MessagePort;
class Node;
class Notification;
@@ -122,9 +124,13 @@ namespace WebCore {
#if ENABLE(BLOB)
virtual FileReader* toFileReader();
#endif
+#if ENABLE(FILE_WRITER)
+ virtual FileWriter* toFileWriter();
+#endif
#if ENABLE(INDEXED_DATABASE)
virtual IDBRequest* toIDBRequest();
+ virtual IDBTransaction* toIDBTransaction();
#endif
virtual ScriptExecutionContext* scriptExecutionContext() const = 0;
diff --git a/WebCore/dom/Node.cpp b/WebCore/dom/Node.cpp
index 98fb2e5..2c63b62 100644
--- a/WebCore/dom/Node.cpp
+++ b/WebCore/dom/Node.cpp
@@ -646,14 +646,8 @@ const AtomicString& Node::virtualNamespaceURI() const
return nullAtom;
}
-ContainerNode* Node::legacyParserAddChild(PassRefPtr<Node>)
+void Node::deprecatedParserAddChild(PassRefPtr<Node>)
{
- return 0;
-}
-
-void Node::parserAddChild(PassRefPtr<Node>)
-{
- ASSERT_NOT_REACHED();
}
bool Node::isContentEditable() const
@@ -1235,11 +1229,6 @@ bool Node::contains(const Node* node) const
return this == node || node->isDescendantOf(this);
}
-bool Node::childAllowed(Node* newChild)
-{
- return childTypeAllowed(newChild->nodeType());
-}
-
void Node::attach()
{
ASSERT(!attached());
@@ -2377,9 +2366,7 @@ void Node::getSubresourceURLs(ListHashSet<KURL>& urls) const
ContainerNode* Node::eventParentNode()
{
- Node* parent = parentNode();
- ASSERT(!parent || parent->isContainerNode());
- return static_cast<ContainerNode*>(parent);
+ return parentNode();
}
Node* Node::enclosingLinkEventParentOrSelf()
@@ -2668,7 +2655,7 @@ static inline SVGElementInstance* eventTargetAsSVGElementInstance(Node* referenc
if (!n->isShadowNode() || !n->isSVGElement())
continue;
- Node* shadowTreeParentElement = n->shadowParentNode();
+ ContainerNode* shadowTreeParentElement = n->shadowParentNode();
ASSERT(shadowTreeParentElement->hasTagName(SVGNames::useTag));
if (SVGElementInstance* instance = static_cast<SVGUseElement*>(shadowTreeParentElement)->instanceForShadowTreeElement(referenceNode))
diff --git a/WebCore/dom/Node.h b/WebCore/dom/Node.h
index a1a8878..e4e2b4a 100644
--- a/WebCore/dom/Node.h
+++ b/WebCore/dom/Node.h
@@ -86,8 +86,7 @@ enum StyleChangeType {
SyntheticStyleChange = 3 << nodeStyleChangeShift
};
-// this class implements nodes, which can have a parent but no children:
-class Node : public EventTarget, public TreeShared<Node>, public ScriptWrappable {
+class Node : public EventTarget, public TreeShared<ContainerNode>, public ScriptWrappable {
friend class Document;
public:
enum NodeType {
@@ -134,7 +133,7 @@ public:
virtual String nodeValue() const;
virtual void setNodeValue(const String&, ExceptionCode&);
virtual NodeType nodeType() const = 0;
- Node* parentNode() const { return parent(); }
+ ContainerNode* parentNode() const { return parent(); }
Element* parentElement() const;
Node* previousSibling() const { return m_previous; }
Node* nextSibling() const { return m_next; }
@@ -209,7 +208,7 @@ public:
virtual bool isCharacterDataNode() const { return false; }
bool isDocumentNode() const;
virtual bool isShadowNode() const { return false; }
- virtual Node* shadowParentNode() { return 0; }
+ virtual ContainerNode* shadowParentNode() { return 0; }
Node* shadowAncestorNode();
Node* shadowTreeRootNode();
bool isInShadowTree();
@@ -259,14 +258,9 @@ public:
Element* rootEditableElement() const;
bool inSameContainingBlockFlowElement(Node*);
-
- // Used by the parser. Checks against the DTD, unlike DOM operations like appendChild().
- // Also does not dispatch DOM mutation events.
- // Returns the appropriate container node for future insertions as you parse, or 0 for failure.
- virtual ContainerNode* legacyParserAddChild(PassRefPtr<Node>);
- // addChild is tied into the logic of the LegacyHTMLTreeBuilder. We need
- // a "clean" version to use for the HTML5 version of the HTMLTreeBuilder.
- virtual void parserAddChild(PassRefPtr<Node>);
+
+ // FIXME: All callers of this function are almost certainly wrong!
+ virtual void deprecatedParserAddChild(PassRefPtr<Node>);
// Called by the parser when this element's close tag is reached,
// signaling that all child tags have been parsed and added.
@@ -427,11 +421,9 @@ public:
bool isDescendantOf(const Node*) const;
bool contains(const Node*) const;
- // These two methods are mutually exclusive. The former is used to do strict error-checking
- // when adding children via the public DOM API (e.g., appendChild()). The latter is called only when parsing,
- // to sanity-check against the DTD for error recovery.
+ // This method is used to do strict error-checking when adding children via
+ // the public DOM API (e.g., appendChild()).
void checkAddChild(Node* newChild, ExceptionCode&); // Error-checking when adding via the DOM API
- virtual bool childAllowed(Node* newChild); // Error-checking during parsing that checks the DTD
void checkReplaceChild(Node* newChild, Node* oldChild, ExceptionCode&);
virtual bool canReplaceChild(Node* newChild, Node* oldChild);
@@ -606,8 +598,8 @@ public:
*/
virtual bool disabled() const;
- using TreeShared<Node>::ref;
- using TreeShared<Node>::deref;
+ using TreeShared<ContainerNode>::ref;
+ using TreeShared<ContainerNode>::deref;
virtual EventTargetData* eventTargetData();
virtual EventTargetData* ensureEventTargetData();
diff --git a/WebCore/dom/Position.h b/WebCore/dom/Position.h
index 9f2ee24..552d675 100644
--- a/WebCore/dom/Position.h
+++ b/WebCore/dom/Position.h
@@ -26,9 +26,9 @@
#ifndef Position_h
#define Position_h
+#include "ContainerNode.h"
#include "TextAffinity.h"
#include "TextDirection.h"
-#include "Node.h" // for position creation functions
#include <wtf/Assertions.h>
#include <wtf/PassRefPtr.h>
#include <wtf/RefPtr.h>
diff --git a/WebCore/dom/RawDataDocumentParser.h b/WebCore/dom/RawDataDocumentParser.h
index 2eb3d0a..093ddaf 100644
--- a/WebCore/dom/RawDataDocumentParser.h
+++ b/WebCore/dom/RawDataDocumentParser.h
@@ -31,17 +31,16 @@
namespace WebCore {
class RawDataDocumentParser : public DocumentParser {
-public:
+protected:
RawDataDocumentParser(Document* document)
: DocumentParser(document)
{
}
-protected:
virtual void finish()
{
- if (!m_parserStopped)
- m_document->finishedParsing();
+ if (!m_parserStopped && !isDetached())
+ document()->finishedParsing();
}
private:
diff --git a/WebCore/dom/ScriptableDocumentParser.h b/WebCore/dom/ScriptableDocumentParser.h
index f5f2e42..e2b3f09 100644
--- a/WebCore/dom/ScriptableDocumentParser.h
+++ b/WebCore/dom/ScriptableDocumentParser.h
@@ -52,9 +52,6 @@ public:
XSSAuditor* xssAuditor() const { return m_xssAuditor; }
void setXSSAuditor(XSSAuditor* auditor) { m_xssAuditor = auditor; }
- // Exposed for LegacyHTMLTreeBuilder::reportErrorToConsole
- virtual bool processingContentWrittenByScript() const { return false; }
-
protected:
ScriptableDocumentParser(Document*, bool viewSourceMode = false);
diff --git a/WebCore/dom/SelectElement.cpp b/WebCore/dom/SelectElement.cpp
index e9958a2..0ca6cb3 100644
--- a/WebCore/dom/SelectElement.cpp
+++ b/WebCore/dom/SelectElement.cpp
@@ -554,6 +554,7 @@ void SelectElement::menuListDefaultEventHandler(SelectElementData& data, Element
handled = true;
}
#else
+ UNUSED_PARAM(htmlForm);
const Vector<Element*>& listItems = data.listItems(element);
int listIndex = optionToListIndex(data, element, selectedIndex(data, element));
diff --git a/WebCore/dom/TreeWalker.cpp b/WebCore/dom/TreeWalker.cpp
index 9c46fb3..6a8ca87 100644
--- a/WebCore/dom/TreeWalker.cpp
+++ b/WebCore/dom/TreeWalker.cpp
@@ -153,6 +153,7 @@ Node* TreeWalker::previousSibling(ScriptState* state)
case NodeFilter::FILTER_SKIP:
if (sibling->lastChild()) {
sibling = sibling->lastChild();
+ node = sibling;
continue;
}
break;
@@ -189,6 +190,7 @@ Node* TreeWalker::nextSibling(ScriptState* state)
case NodeFilter::FILTER_SKIP:
if (sibling->firstChild()) {
sibling = sibling->firstChild();
+ node = sibling;
continue;
}
break;
diff --git a/WebCore/dom/XMLDocumentParser.cpp b/WebCore/dom/XMLDocumentParser.cpp
index 3d2f324..c6d9f89 100644
--- a/WebCore/dom/XMLDocumentParser.cpp
+++ b/WebCore/dom/XMLDocumentParser.cpp
@@ -132,7 +132,7 @@ void XMLDocumentParser::append(const SegmentedString& s)
if (m_sawXSLTransform || !m_sawFirstElement)
m_originalSourceForTransform += parseString;
- if (m_parserStopped || m_sawXSLTransform)
+ if (isDetached() || m_parserStopped || m_sawXSLTransform)
return;
if (m_parserPaused) {
@@ -170,16 +170,14 @@ void XMLDocumentParser::handleError(ErrorType type, const char* m, int lineNumbe
stopParsing();
}
-bool XMLDocumentParser::enterText()
+void XMLDocumentParser::enterText()
{
#if !USE(QXMLSTREAM)
ASSERT(m_bufferedText.size() == 0);
#endif
RefPtr<Node> newNode = Text::create(document(), "");
- if (!m_currentNode->legacyParserAddChild(newNode.get()))
- return false;
+ m_currentNode->deprecatedParserAddChild(newNode.get());
pushCurrentNode(newNode.get());
- return true;
}
#if !USE(QXMLSTREAM)
@@ -211,8 +209,18 @@ void XMLDocumentParser::exitText()
popCurrentNode();
}
+void XMLDocumentParser::detach()
+{
+ clearCurrentNodeStack();
+ ScriptableDocumentParser::detach();
+}
+
void XMLDocumentParser::end()
{
+ // XMLDocumentParserLibxml2 will do bad things to the document if doEnd() is called.
+ // I don't believe XMLDocumentParserQt needs doEnd called in the fragment case.
+ ASSERT(!m_parsingFragment);
+
doEnd();
// doEnd() could process a script tag, thus pausing parsing.
@@ -227,12 +235,16 @@ void XMLDocumentParser::end()
}
clearCurrentNodeStack();
- if (!m_parsingFragment)
- document()->finishedParsing();
+ document()->finishedParsing();
}
void XMLDocumentParser::finish()
{
+ // FIXME: We should ASSERT(!m_parserStopped) here, since it does not
+ // makes sense to call any methods on DocumentParser once it's been stopped.
+ // However, FrameLoader::stop calls Document::finishParsing unconditionally
+ // which in turn calls m_parser->finish().
+
if (m_parserPaused)
m_finishCalled = true;
else
@@ -338,6 +350,9 @@ void XMLDocumentParser::notifyFinished(CachedResource* unusedResource)
ScriptElement* scriptElement = toScriptElement(e.get());
ASSERT(scriptElement);
+ // JavaScript can detach this parser, make sure it's kept alive even if detached.
+ RefPtr<XMLDocumentParser> protect(this);
+
if (errorOccurred)
scriptElement->dispatchErrorEvent();
else {
@@ -347,7 +362,7 @@ void XMLDocumentParser::notifyFinished(CachedResource* unusedResource)
m_scriptElement = 0;
- if (!m_requestingScript)
+ if (!isDetached() && !m_requestingScript)
resumeParsing();
}
@@ -364,4 +379,25 @@ void XMLDocumentParser::pauseParsing()
m_parserPaused = true;
}
+bool XMLDocumentParser::parseDocumentFragment(const String& chunk, DocumentFragment* fragment, Element* contextElement, FragmentScriptingPermission scriptingPermission)
+{
+ if (!chunk.length())
+ return true;
+
+ // FIXME: We need to implement the HTML5 XML Fragment parsing algorithm:
+ // http://www.whatwg.org/specs/web-apps/current-work/multipage/the-xhtml-syntax.html#xml-fragment-parsing-algorithm
+ // For now we have a hack for script/style innerHTML support:
+ if (contextElement && (contextElement->hasLocalName(HTMLNames::scriptTag) || contextElement->hasLocalName(HTMLNames::styleTag))) {
+ fragment->parserAddChild(fragment->document()->createTextNode(chunk));
+ return true;
+ }
+
+ RefPtr<XMLDocumentParser> parser = XMLDocumentParser::create(fragment, contextElement, scriptingPermission);
+ bool wellFormed = parser->appendFragmentSource(chunk);
+ // Do not call finish(). Current finish() and doEnd() implementations touch the main Document/loader
+ // and can cause crashes in the fragment case.
+ parser->detach(); // Allows ~DocumentParser to assert it was detached before destruction.
+ return wellFormed; // appendFragmentSource()'s wellFormed is more permissive than wellFormed().
}
+
+} // namespace WebCore
diff --git a/WebCore/dom/XMLDocumentParser.h b/WebCore/dom/XMLDocumentParser.h
index 141adf7..4211e4e 100644
--- a/WebCore/dom/XMLDocumentParser.h
+++ b/WebCore/dom/XMLDocumentParser.h
@@ -181,8 +181,15 @@ namespace WebCore {
class XMLDocumentParser : public ScriptableDocumentParser, public CachedResourceClient {
public:
- XMLDocumentParser(Document*, FrameView* = 0);
- XMLDocumentParser(DocumentFragment*, Element*, FragmentScriptingPermission);
+ static PassRefPtr<XMLDocumentParser> create(Document* document, FrameView* view)
+ {
+ return adoptRef(new XMLDocumentParser(document, view));
+ }
+ static PassRefPtr<XMLDocumentParser> create(DocumentFragment* fragment, Element* element, FragmentScriptingPermission permission)
+ {
+ return adoptRef(new XMLDocumentParser(fragment, element, permission));
+ }
+
~XMLDocumentParser();
// Exposed for callbacks:
@@ -199,14 +206,19 @@ namespace WebCore {
bool isWMLDocument() const;
#endif
- static bool parseDocumentFragment(const String&, DocumentFragment*, Element* parent = 0, FragmentScriptingPermission = FragmentScriptingAllowed);
+ static bool parseDocumentFragment(const String&, DocumentFragment*, Element* parent = 0, FragmentScriptingPermission = FragmentScriptingAllowed);
// WMLErrorHandling uses these functions.
virtual bool wellFormed() const { return !m_sawError; }
virtual int lineNumber() const;
virtual int columnNumber() const;
+ static bool supportsXMLVersion(const String&);
+
private:
+ XMLDocumentParser(Document*, FrameView* = 0);
+ XMLDocumentParser(DocumentFragment*, Element*, FragmentScriptingPermission);
+
// From DocumentParser
virtual void insert(const SegmentedString&);
virtual void append(const SegmentedString&);
@@ -214,6 +226,7 @@ namespace WebCore {
virtual bool finishWasCalled();
virtual bool isWaitingForScripts() const;
virtual void stopParsing();
+ virtual void detach();
// from CachedResourceClient
virtual void notifyFinished(CachedResource*);
@@ -223,6 +236,8 @@ namespace WebCore {
void pauseParsing();
void resumeParsing();
+ bool appendFragmentSource(const String&);
+
#if USE(QXMLSTREAM)
private:
void parse();
@@ -260,7 +275,7 @@ public:
void insertErrorMessageBlock();
- bool enterText();
+ void enterText();
void exitText();
void doWrite(const String&);
diff --git a/WebCore/dom/XMLDocumentParserLibxml2.cpp b/WebCore/dom/XMLDocumentParserLibxml2.cpp
index 1309827..37da83c 100644
--- a/WebCore/dom/XMLDocumentParserLibxml2.cpp
+++ b/WebCore/dom/XMLDocumentParserLibxml2.cpp
@@ -522,6 +522,11 @@ PassRefPtr<XMLParserContext> XMLParserContext::createMemoryParser(xmlSAXHandlerP
// --------------------------------
+bool XMLDocumentParser::supportsXMLVersion(const String& version)
+{
+ return version == "1.0";
+}
+
XMLDocumentParser::XMLDocumentParser(Document* document, FrameView* frameView)
: ScriptableDocumentParser(document)
, m_view(frameView)
@@ -616,13 +621,18 @@ XMLParserContext::~XMLParserContext()
XMLDocumentParser::~XMLDocumentParser()
{
- clearCurrentNodeStack();
+ // The XMLDocumentParser will always be detached before being destroyed.
+ ASSERT(m_currentNodeStack.isEmpty());
+ ASSERT(!m_currentNode);
+
+ // FIXME: m_pendingScript handling should be moved into XMLDocumentParser.cpp!
if (m_pendingScript)
m_pendingScript->removeClient(this);
}
void XMLDocumentParser::doWrite(const String& parseString)
{
+ ASSERT(!isDetached());
if (!m_context)
initializeParserContext();
@@ -631,6 +641,10 @@ void XMLDocumentParser::doWrite(const String& parseString)
// libXML throws an error if you try to switch the encoding for an empty string.
if (parseString.length()) {
+ // JavaScript may cause the parser to detach during xmlParseChunk
+ // keep this alive until this function is done.
+ RefPtr<XMLDocumentParser> protect(this);
+
// Hack around libxml2's lack of encoding overide support by manually
// resetting the encoding to UTF-16 before every chunk. Otherwise libxml
// will detect <?xml version="1.0" encoding="<encoding name>"?> blocks
@@ -641,14 +655,18 @@ void XMLDocumentParser::doWrite(const String& parseString)
XMLDocumentParserScope scope(document()->docLoader());
xmlParseChunk(context->context(), reinterpret_cast<const char*>(parseString.characters()), sizeof(UChar) * parseString.length(), 0);
+
+ // JavaScript (which may be run under the xmlParseChunk callstack) may
+ // cause the parser to be stopped or detached.
+ if (isDetached() || m_parserStopped)
+ return;
}
+ // FIXME: Why is this here? And why is it after we process the passed source?
if (document()->decoder() && document()->decoder()->sawError()) {
// If the decoder saw an error, report it as fatal (stops parsing)
handleError(fatal, "Encoding error", context->context()->input->line, context->context()->input->col);
}
-
- return;
}
static inline String toString(const xmlChar* str, unsigned len)
@@ -790,10 +808,7 @@ void XMLDocumentParser::startElementNs(const xmlChar* xmlLocalName, const xmlCha
if (scriptElement)
m_scriptStartLine = lineNumber();
- if (!m_currentNode->legacyParserAddChild(newElement.get())) {
- stopParsing();
- return;
- }
+ m_currentNode->deprecatedParserAddChild(newElement.get());
pushCurrentNode(newElement.get());
if (m_view && !newElement->attached())
@@ -855,6 +870,13 @@ void XMLDocumentParser::endElementNs()
else
#endif
{
+ // FIXME: Script execution should be shared should be shared between
+ // the libxml2 and Qt XMLDocumentParser implementations.
+
+ // JavaScript can detach the parser. Make sure this is not released
+ // before the end of this method.
+ RefPtr<XMLDocumentParser> protect(this);
+
String scriptHref = scriptElement->sourceAttributeValue();
if (!scriptHref.isEmpty()) {
// we have a src attribute
@@ -871,6 +893,10 @@ void XMLDocumentParser::endElementNs()
m_scriptElement = 0;
} else
m_view->frame()->script()->executeScript(ScriptSourceCode(scriptElement->scriptContent(), document()->url(), m_scriptStartLine));
+
+ // JavaScript may have detached the parser
+ if (isDetached())
+ return;
}
m_requestingScript = false;
popCurrentNode();
@@ -886,8 +912,9 @@ void XMLDocumentParser::characters(const xmlChar* s, int len)
return;
}
- if (m_currentNode->isTextNode() || enterText())
- m_bufferedText.append(s, len);
+ if (!m_currentNode->isTextNode())
+ enterText();
+ m_bufferedText.append(s, len);
}
void XMLDocumentParser::error(ErrorType type, const char* message, va_list args)
@@ -935,8 +962,7 @@ void XMLDocumentParser::processingInstruction(const xmlChar* target, const xmlCh
pi->setCreatedByParser(true);
- if (!m_currentNode->legacyParserAddChild(pi.get()))
- return;
+ m_currentNode->deprecatedParserAddChild(pi.get());
if (m_view && !pi->attached())
pi->attach();
@@ -962,8 +988,7 @@ void XMLDocumentParser::cdataBlock(const xmlChar* s, int len)
exitText();
RefPtr<Node> newNode = CDATASection::create(document(), toString(s, len));
- if (!m_currentNode->legacyParserAddChild(newNode.get()))
- return;
+ m_currentNode->deprecatedParserAddChild(newNode.get());
if (m_view && !newNode->attached())
newNode->attach();
}
@@ -981,7 +1006,7 @@ void XMLDocumentParser::comment(const xmlChar* s)
exitText();
RefPtr<Node> newNode = Comment::create(document(), toString(s));
- m_currentNode->legacyParserAddChild(newNode.get());
+ m_currentNode->deprecatedParserAddChild(newNode.get());
if (m_view && !newNode->attached())
newNode->attach();
}
@@ -1045,7 +1070,7 @@ void XMLDocumentParser::internalSubset(const xmlChar* name, const xmlChar* exter
}
#endif
- document()->legacyParserAddChild(DocumentType::create(document(), toString(name), toString(externalID), toString(systemID)));
+ document()->parserAddChild(DocumentType::create(document(), toString(name), toString(externalID), toString(systemID)));
}
}
@@ -1274,8 +1299,10 @@ void XMLDocumentParser::initializeParserContext(const char* chunk)
XMLDocumentParserScope scope(document()->docLoader());
if (m_parsingFragment)
m_context = XMLParserContext::createMemoryParser(&sax, this, chunk);
- else
+ else {
+ ASSERT(!chunk);
m_context = XMLParserContext::createStringParser(&sax, this);
+ }
}
void XMLDocumentParser::doEnd()
@@ -1347,6 +1374,7 @@ void XMLDocumentParser::stopParsing()
void XMLDocumentParser::resumeParsing()
{
+ ASSERT(!isDetached());
ASSERT(m_parserPaused);
m_parserPaused = false;
@@ -1371,29 +1399,29 @@ void XMLDocumentParser::resumeParsing()
end();
}
-// FIXME: This method should be possible to implement using the DocumentParser
-// API, instead of needing to grab at libxml2 state directly.
-bool XMLDocumentParser::parseDocumentFragment(const String& chunk, DocumentFragment* fragment, Element* parent, FragmentScriptingPermission scriptingPermission)
+bool XMLDocumentParser::appendFragmentSource(const String& chunk)
{
- if (!chunk.length())
- return true;
-
- XMLDocumentParser parser(fragment, parent, scriptingPermission);
+ ASSERT(!m_context);
+ ASSERT(m_parsingFragment);
CString chunkAsUtf8 = chunk.utf8();
- parser.initializeParserContext(chunkAsUtf8.data());
-
- xmlParseContent(parser.context());
-
- parser.endDocument();
+ initializeParserContext(chunkAsUtf8.data());
+ xmlParseContent(context());
+ endDocument(); // Close any open text nodes.
+ // FIXME: If this code is actually needed, it should probably move to finish()
+ // XMLDocumentParserQt has a similar check (m_stream.error() == QXmlStreamReader::PrematureEndOfDocumentError) in doEnd().
// Check if all the chunk has been processed.
- long bytesProcessed = xmlByteConsumed(parser.context());
- if (bytesProcessed == -1 || ((unsigned long)bytesProcessed) != chunkAsUtf8.length())
+ long bytesProcessed = xmlByteConsumed(context());
+ if (bytesProcessed == -1 || ((unsigned long)bytesProcessed) != chunkAsUtf8.length()) {
+ // FIXME: I don't believe we can hit this case without also having seen an error.
+ // If we hit this ASSERT, we've found a test case which demonstrates the need for this code.
+ ASSERT(m_sawError);
return false;
+ }
// No error if the chunk is well formed or it is not but we have no error.
- return parser.context()->wellFormed || xmlCtxtGetLastError(parser.context()) == 0;
+ return context()->wellFormed || !xmlCtxtGetLastError(context());
}
// --------------------------------
diff --git a/WebCore/dom/XMLDocumentParserQt.cpp b/WebCore/dom/XMLDocumentParserQt.cpp
index 715856c..606770f 100644
--- a/WebCore/dom/XMLDocumentParserQt.cpp
+++ b/WebCore/dom/XMLDocumentParserQt.cpp
@@ -78,6 +78,11 @@ QString EntityResolver::resolveUndeclaredEntity(const QString &name)
// --------------------------------
+bool XMLDocumentParser::supportsXMLVersion(const String& version)
+{
+ return version == "1.0";
+}
+
XMLDocumentParser::XMLDocumentParser(Document* document, FrameView* frameView)
: ScriptableDocumentParser(document)
, m_view(frameView)
@@ -254,18 +259,13 @@ void XMLDocumentParser::resumeParsing()
end();
}
-bool XMLDocumentParser::parseDocumentFragment(const String& chunk, DocumentFragment* fragment, Element* parent, FragmentScriptingPermission scriptingPermission)
+bool XMLDocumentParser::appendFragmentSource(const String& source)
{
- if (!chunk.length())
- return true;
-
- XMLDocumentParser parser(fragment, parent, scriptingPermission);
-
- parser.append(String("<qxmlstreamdummyelement>"));
- parser.append(chunk);
- parser.append(String("</qxmlstreamdummyelement>"));
- parser.finish();
- return !parser.hasError();
+ ASSERT(!m_sawFirstElement);
+ append(String("<qxmlstreamdummyelement>"));
+ append(source);
+ append(String("</qxmlstreamdummyelement>"));
+ return !hasError();
}
// --------------------------------
@@ -410,12 +410,12 @@ void XMLDocumentParser::parse()
) {
QString entity = m_stream.name().toString();
UChar c = decodeNamedEntity(entity.toUtf8().constData());
- if (m_currentNode->isTextNode() || enterText()) {
- ExceptionCode ec = 0;
- String str(&c, 1);
- //qDebug()<<" ------- adding entity "<<str;
- static_cast<Text*>(m_currentNode)->appendData(str, ec);
- }
+ if (!m_currentNode->isTextNode())
+ enterText();
+ ExceptionCode ec = 0;
+ String str(&c, 1);
+ // qDebug()<<" ------- adding entity "<<str;
+ static_cast<Text*>(m_currentNode)->appendData(str, ec);
}
}
break;
@@ -518,10 +518,7 @@ void XMLDocumentParser::parseStartElement()
if (scriptElement)
m_scriptStartLine = lineNumber();
- if (!m_currentNode->legacyParserAddChild(newElement.get())) {
- stopParsing();
- return;
- }
+ m_currentNode->deprecatedParserAddChild(newElement.get());
pushCurrentNode(newElement.get());
if (m_view && !newElement->attached())
@@ -599,10 +596,10 @@ void XMLDocumentParser::parseEndElement()
void XMLDocumentParser::parseCharacters()
{
- if (m_currentNode->isTextNode() || enterText()) {
- ExceptionCode ec = 0;
- static_cast<Text*>(m_currentNode)->appendData(m_stream.text(), ec);
- }
+ if (!m_currentNode->isTextNode())
+ enterText();
+ ExceptionCode ec = 0;
+ static_cast<Text*>(m_currentNode)->appendData(m_stream.text(), ec);
}
void XMLDocumentParser::parseProcessingInstruction()
@@ -619,8 +616,7 @@ void XMLDocumentParser::parseProcessingInstruction()
pi->setCreatedByParser(true);
- if (!m_currentNode->legacyParserAddChild(pi.get()))
- return;
+ m_currentNode->deprecatedParserAddChild(pi.get());
if (m_view && !pi->attached())
pi->attach();
@@ -638,8 +634,8 @@ void XMLDocumentParser::parseCdata()
exitText();
RefPtr<Node> newNode = CDATASection::create(document(), m_stream.text());
- if (!m_currentNode->legacyParserAddChild(newNode.get()))
- return;
+
+ m_currentNode->deprecatedParserAddChild(newNode.get());
if (m_view && !newNode->attached())
newNode->attach();
}
@@ -649,7 +645,8 @@ void XMLDocumentParser::parseComment()
exitText();
RefPtr<Node> newNode = Comment::create(document(), m_stream.text());
- m_currentNode->legacyParserAddChild(newNode.get());
+
+ m_currentNode->deprecatedParserAddChild(newNode.get());
if (m_view && !newNode->attached())
newNode->attach();
}
@@ -708,7 +705,7 @@ void XMLDocumentParser::parseDtd()
handleError(fatal, "Invalid DTD Public ID", lineNumber(), columnNumber());
#endif
if (!m_parsingFragment)
- document()->legacyParserAddChild(DocumentType::create(document(), name, publicId, systemId));
+ document()->parserAddChild(DocumentType::create(document(), name, publicId, systemId));
}
}
diff --git a/WebCore/editing/ApplyStyleCommand.cpp b/WebCore/editing/ApplyStyleCommand.cpp
index bfbfab8..0a02e7a 100644
--- a/WebCore/editing/ApplyStyleCommand.cpp
+++ b/WebCore/editing/ApplyStyleCommand.cpp
@@ -90,6 +90,23 @@ public:
String fontFace() { return m_applyFontFace; }
String fontSize() { return m_applyFontSize; }
+ bool operator==(const StyleChange& other)
+ {
+ return m_cssStyle == other.m_cssStyle
+ && m_applyBold == other.m_applyBold
+ && m_applyItalic == other.m_applyItalic
+ && m_applyUnderline == other.m_applyUnderline
+ && m_applyLineThrough == other.m_applyLineThrough
+ && m_applySubscript == other.m_applySubscript
+ && m_applySuperscript == other.m_applySuperscript
+ && m_applyFontColor == other.m_applyFontColor
+ && m_applyFontFace == other.m_applyFontFace
+ && m_applyFontSize == other.m_applyFontSize;
+ }
+ bool operator!=(const StyleChange& other)
+ {
+ return !(*this == other);
+ }
private:
void init(PassRefPtr<CSSStyleDeclaration>, const Position&);
void reconcileTextDecorationProperties(CSSMutableStyleDeclaration*);
@@ -1103,14 +1120,17 @@ void ApplyStyleCommand::applyInlineStyleToRange(CSSMutableStyleDeclaration* styl
Node* runStart = node;
// Find the end of the run.
Node* sibling = node->nextSibling();
- while (sibling && sibling != pastEndNode && (!sibling->isElementNode() || sibling->hasTagName(brTag)) && !isBlock(sibling)) {
+ StyleChange startChange(style, Position(node, 0));
+ while (sibling && sibling != pastEndNode && !sibling->contains(pastEndNode)
+ && (!isBlock(sibling) || sibling->hasTagName(brTag))
+ && StyleChange(style, Position(sibling, 0)) == startChange) {
node = sibling;
sibling = node->nextSibling();
}
// Recompute next, since node has changed.
- next = node->traverseNextNode();
+ next = node->traverseNextSibling();
// Apply the style to the run.
- addInlineStyleIfNeeded(style, runStart, node);
+ addInlineStyleIfNeeded(style, runStart, node, m_removeOnly ? DoNotAddStyledElement : AddStyledElement);
}
}
}
@@ -1344,7 +1364,7 @@ HTMLElement* ApplyStyleCommand::highestAncestorWithConflictingInlineStyle(CSSMut
return result;
}
-PassRefPtr<CSSMutableStyleDeclaration> ApplyStyleCommand::extractInlineStyleToPushDown(Node* node, const Vector<int>& properties)
+PassRefPtr<CSSMutableStyleDeclaration> ApplyStyleCommand::extractInlineStyleToPushDown(Node* node, bool isStyledElement, const Vector<int>& properties)
{
ASSERT(node);
ASSERT(node->isElementNode());
@@ -1353,13 +1373,17 @@ PassRefPtr<CSSMutableStyleDeclaration> ApplyStyleCommand::extractInlineStyleToPu
if (!node->isHTMLElement())
return 0;
- HTMLElement *element = static_cast<HTMLElement *>(node);
+ HTMLElement* element = static_cast<HTMLElement*>(node);
RefPtr<CSSMutableStyleDeclaration> style = element->inlineStyleDecl();
+ if (isStyledElement) {
+ removeNodePreservingChildren(element);
+ return style.release();
+ }
+
if (!style)
return 0;
style = style->copyPropertiesInSet(properties.data(), properties.size());
-
for (size_t i = 0; i < properties.size(); i++) {
RefPtr<CSSValue> property = style->getPropertyCSSValue(properties[i]);
if (property)
@@ -1429,7 +1453,10 @@ void ApplyStyleCommand::applyInlineStyleToPushDown(Node* node, CSSMutableStyleDe
return;
// FIXME: addInlineStyleIfNeeded may override the style of node
- addInlineStyleIfNeeded(style, node, node);
+ // We can't wrap node with the styled element here because new styled element will never be removed if we did.
+ // If we modified the child pointer in pushDownInlineStyleAroundNode to point to new style element
+ // then we fall into an infinite loop where we keep removing and adding styled element wrapping node.
+ addInlineStyleIfNeeded(style, node, node, DoNotAddStyledElement);
}
void ApplyStyleCommand::pushDownInlineStyleAroundNode(CSSMutableStyleDeclaration* style, Node* targetNode)
@@ -1450,14 +1477,33 @@ void ApplyStyleCommand::pushDownInlineStyleAroundNode(CSSMutableStyleDeclaration
ASSERT(current->isHTMLElement());
ASSERT(current->contains(targetNode));
Node* child = current->firstChild();
- RefPtr<CSSMutableStyleDeclaration> styleToPushDown = extractInlineStyleToPushDown(current, properties);
+ Node* lastChild = current->lastChild();
+ RefPtr<StyledElement> styledElement;
+ if (current->isStyledElement() && m_styledInlineElement && current->hasTagName(m_styledInlineElement->tagQName()))
+ styledElement = static_cast<StyledElement*>(current);
+ RefPtr<CSSMutableStyleDeclaration> styleToPushDown = extractInlineStyleToPushDown(current, styledElement, properties);
// The inner loop will go through children on each level
+ // FIXME: we should aggregate inline child elements together so that we don't wrap each child separately.
while (child) {
Node* nextChild = child->nextSibling();
+ if (child != targetNode && styledElement) {
+ // If child has children, wrap children of child by a clone of the styled element to avoid infinite loop.
+ // Otherwise, wrap the child by the styled element, and we won't fall into an infinite loop.
+ RefPtr<Element> wrapper = styledElement->cloneElementWithoutChildren();
+ ExceptionCode ec = 0;
+ wrapper->removeAttribute(styleAttr, ec);
+ ASSERT(!ec);
+ if (child->firstChild())
+ surroundNodeRangeWithElement(child->firstChild(), child->lastChild(), wrapper);
+ else
+ surroundNodeRangeWithElement(child, child, wrapper);
+ }
+
// Apply text decoration to all nodes containing targetNode and their siblings but NOT to targetNode
- if (child != targetNode)
+ // But if we've removed styledElement then go ahead and always apply the style.
+ if (child != targetNode || styledElement)
applyInlineStyleToPushDown(child, styleToPushDown.get());
// We found the next node for the outer loop (contains targetNode)
@@ -1465,6 +1511,8 @@ void ApplyStyleCommand::pushDownInlineStyleAroundNode(CSSMutableStyleDeclaration
if (child == targetNode || child->contains(targetNode))
current = child;
+ if (child == lastChild || child->contains(lastChild))
+ break;
child = nextChild;
}
}
@@ -1737,11 +1785,9 @@ void ApplyStyleCommand::surroundNodeRangeWithElement(Node* startNode, Node* endN
Node* node = startNode;
while (1) {
- Node* next = node->traverseNextNode();
- if (node->childNodeCount() == 0 && node->renderer() && node->renderer()->isInline()) {
- removeNode(node);
- appendNode(node, element);
- }
+ Node* next = node->nextSibling();
+ removeNode(node);
+ appendNode(node, element);
if (node == endNode)
break;
node = next;
@@ -1779,11 +1825,8 @@ void ApplyStyleCommand::addBlockStyle(const StyleChange& styleChange, HTMLElemen
setNodeAttribute(block, styleAttr, cssText);
}
-void ApplyStyleCommand::addInlineStyleIfNeeded(CSSMutableStyleDeclaration *style, Node *startNode, Node *endNode)
+void ApplyStyleCommand::addInlineStyleIfNeeded(CSSMutableStyleDeclaration *style, Node *startNode, Node *endNode, EAddStyledElement addStyledElement)
{
- if (m_removeOnly)
- return;
-
StyleChange styleChange(style, Position(startNode, 0));
// Font tags need to go outside of CSS so that CSS font sizes override leagcy font sizes.
@@ -1823,7 +1866,7 @@ void ApplyStyleCommand::addInlineStyleIfNeeded(CSSMutableStyleDeclaration *style
else if (styleChange.applySuperscript())
surroundNodeRangeWithElement(startNode, endNode, createHTMLElement(document(), supTag));
- if (m_styledInlineElement)
+ if (m_styledInlineElement && addStyledElement == AddStyledElement)
surroundNodeRangeWithElement(startNode, endNode, m_styledInlineElement->cloneElementWithoutChildren());
}
diff --git a/WebCore/editing/ApplyStyleCommand.h b/WebCore/editing/ApplyStyleCommand.h
index f4ecc7c..abe4909 100644
--- a/WebCore/editing/ApplyStyleCommand.h
+++ b/WebCore/editing/ApplyStyleCommand.h
@@ -43,6 +43,7 @@ class ApplyStyleCommand : public CompositeEditCommand {
public:
enum EPropertyLevel { PropertyDefault, ForceBlockProperties };
enum InlineStyleRemovalMode { RemoveAttributesAndElements, RemoveNone };
+ enum EAddStyledElement { AddStyledElement, DoNotAddStyledElement };
static PassRefPtr<ApplyStyleCommand> create(Document* document, CSSStyleDeclaration* style, EditAction action = EditActionChangeAttributes, EPropertyLevel level = PropertyDefault)
{
@@ -79,7 +80,7 @@ private:
bool removeHTMLBidiEmbeddingStyle(CSSMutableStyleDeclaration*, HTMLElement*, InlineStyleRemovalMode = RemoveAttributesAndElements);
bool removeCSSStyle(CSSMutableStyleDeclaration*, HTMLElement*, InlineStyleRemovalMode = RemoveAttributesAndElements);
HTMLElement* highestAncestorWithConflictingInlineStyle(CSSMutableStyleDeclaration*, Node*);
- PassRefPtr<CSSMutableStyleDeclaration> extractInlineStyleToPushDown(Node*, const Vector<int>&);
+ PassRefPtr<CSSMutableStyleDeclaration> extractInlineStyleToPushDown(Node*, bool isStyledElement, const Vector<int>&);
void applyInlineStyleToPushDown(Node*, CSSMutableStyleDeclaration *style);
void pushDownInlineStyleAroundNode(CSSMutableStyleDeclaration*, Node*);
void removeInlineStyle(PassRefPtr<CSSMutableStyleDeclaration>, const Position& start, const Position& end);
@@ -92,7 +93,7 @@ private:
void applyInlineStyle(CSSMutableStyleDeclaration*);
void applyInlineStyleToRange(CSSMutableStyleDeclaration*, const Position& start, const Position& end);
void addBlockStyle(const StyleChange&, HTMLElement*);
- void addInlineStyleIfNeeded(CSSMutableStyleDeclaration*, Node* start, Node* end);
+ void addInlineStyleIfNeeded(CSSMutableStyleDeclaration*, Node* start, Node* end, EAddStyledElement addStyledElement = AddStyledElement);
void splitTextAtStart(const Position& start, const Position& end);
void splitTextAtEnd(const Position& start, const Position& end);
void splitTextElementAtStart(const Position& start, const Position& end);
diff --git a/WebCore/editing/CompositeEditCommand.cpp b/WebCore/editing/CompositeEditCommand.cpp
index f50929a..aa37193 100644
--- a/WebCore/editing/CompositeEditCommand.cpp
+++ b/WebCore/editing/CompositeEditCommand.cpp
@@ -730,30 +730,6 @@ void CompositeEditCommand::pushAnchorElementDown(Node* anchorNode)
removeNodePreservingChildren(anchorNode);
}
-// We must push partially selected anchors down before creating or removing
-// links from a selection to create fully selected chunks that can be removed.
-// ApplyStyleCommand doesn't do this for us because styles can be nested.
-// Anchors cannot be nested.
-void CompositeEditCommand::pushPartiallySelectedAnchorElementsDown()
-{
- VisibleSelection originalSelection = endingSelection();
- VisiblePosition visibleStart(originalSelection.start());
- VisiblePosition visibleEnd(originalSelection.end());
-
- Node* startAnchor = enclosingAnchorElement(originalSelection.start());
- VisiblePosition startOfStartAnchor(Position(startAnchor, 0));
- if (startAnchor && startOfStartAnchor != visibleStart)
- pushAnchorElementDown(startAnchor);
-
- Node* endAnchor = enclosingAnchorElement(originalSelection.end());
- VisiblePosition endOfEndAnchor(Position(endAnchor, 0));
- if (endAnchor && endOfEndAnchor != visibleEnd)
- pushAnchorElementDown(endAnchor);
-
- ASSERT(originalSelection.start().node()->inDocument() && originalSelection.end().node()->inDocument());
- setEndingSelection(originalSelection);
-}
-
// Clone the paragraph between start and end under blockElement,
// preserving the hierarchy up to outerNode.
diff --git a/WebCore/editing/CompositeEditCommand.h b/WebCore/editing/CompositeEditCommand.h
index 9d69925..f839a72 100644
--- a/WebCore/editing/CompositeEditCommand.h
+++ b/WebCore/editing/CompositeEditCommand.h
@@ -99,7 +99,6 @@ protected:
PassRefPtr<Node> moveParagraphContentsToNewBlockIfNecessary(const Position&);
void pushAnchorElementDown(Node*);
- void pushPartiallySelectedAnchorElementsDown();
void moveParagraph(const VisiblePosition&, const VisiblePosition&, const VisiblePosition&, bool preserveSelection = false, bool preserveStyle = true);
void moveParagraphs(const VisiblePosition&, const VisiblePosition&, const VisiblePosition&, bool preserveSelection = false, bool preserveStyle = true);
diff --git a/WebCore/editing/CreateLinkCommand.cpp b/WebCore/editing/CreateLinkCommand.cpp
index d7048fe..fe7af4a 100644
--- a/WebCore/editing/CreateLinkCommand.cpp
+++ b/WebCore/editing/CreateLinkCommand.cpp
@@ -46,10 +46,9 @@ void CreateLinkCommand::doApply()
RefPtr<HTMLAnchorElement> anchorElement = HTMLAnchorElement::create(document());
anchorElement->setHref(m_url);
- if (endingSelection().isRange()) {
- pushPartiallySelectedAnchorElementsDown();
+ if (endingSelection().isRange())
applyStyledElement(anchorElement.get());
- } else {
+ else {
insertNodeAt(anchorElement.get(), endingSelection().start());
RefPtr<Text> textNode = Text::create(document(), m_url);
appendNode(textNode.get(), anchorElement.get());
diff --git a/WebCore/editing/DeleteSelectionCommand.cpp b/WebCore/editing/DeleteSelectionCommand.cpp
index 5e025eb..e57895c 100644
--- a/WebCore/editing/DeleteSelectionCommand.cpp
+++ b/WebCore/editing/DeleteSelectionCommand.cpp
@@ -735,8 +735,8 @@ void DeleteSelectionCommand::doApply()
// use the current ending selection.
if (!m_hasSelectionToDelete)
m_selectionToDelete = endingSelection();
-
- if (!m_selectionToDelete.isRange())
+
+ if (!m_selectionToDelete.isNonOrphanedRange())
return;
// If the deletion is occurring in a text field, and we're not deleting to replace the selection, then let the frame call across the bridge to notify the form delegate.
diff --git a/WebCore/editing/Editor.cpp b/WebCore/editing/Editor.cpp
index 196384a..3dd6e27 100644
--- a/WebCore/editing/Editor.cpp
+++ b/WebCore/editing/Editor.cpp
@@ -326,6 +326,11 @@ void Editor::pasteAsFragment(PassRefPtr<DocumentFragment> pastingFragment, bool
target->dispatchEvent(TextEvent::createForFragmentPaste(m_frame->domWindow(), pastingFragment, smartReplace, matchStyle), ec);
}
+void Editor::pasteAsPlainTextBypassingDHTML()
+{
+ pasteAsPlainTextWithPasteboard(Pasteboard::generalPasteboard());
+}
+
void Editor::pasteAsPlainTextWithPasteboard(Pasteboard* pasteboard)
{
String text = pasteboard->plainText(m_frame);
@@ -992,12 +997,12 @@ void Editor::reappliedEditing(PassRefPtr<EditCommand> cmd)
Editor::Editor(Frame* frame)
: m_frame(frame)
- , m_deleteButtonController(new DeleteButtonController(frame))
+ , m_deleteButtonController(adoptPtr(new DeleteButtonController(frame)))
, m_ignoreCompositionSelectionChange(false)
, m_shouldStartNewKillRingSequence(false)
// This is off by default, since most editors want this behavior (this matches IE but not FF).
, m_shouldStyleWithCSS(false)
- , m_killRing(new KillRing)
+ , m_killRing(adoptPtr(new KillRing))
{
}
@@ -1563,7 +1568,7 @@ void Editor::ignoreSpelling()
RefPtr<Range> selectedRange = frame()->selection()->toNormalizedRange();
if (selectedRange)
- frame()->document()->removeMarkers(selectedRange.get(), DocumentMarker::Spelling);
+ frame()->document()->markers()->removeMarkers(selectedRange.get(), DocumentMarker::Spelling);
String text = frame()->selectedText();
ASSERT(text.length());
@@ -1629,7 +1634,7 @@ static String findFirstMisspellingInRange(EditorClient* client, Range* searchRan
// Store marker for misspelled word.
ExceptionCode ec = 0;
- misspellingRange->startContainer(ec)->document()->addMarker(misspellingRange.get(), DocumentMarker::Spelling);
+ misspellingRange->startContainer(ec)->document()->markers()->addMarker(misspellingRange.get(), DocumentMarker::Spelling);
ASSERT(!ec);
// Bail out if we're marking only the first misspelling, and not all instances.
@@ -1692,7 +1697,7 @@ static int findFirstGrammarDetailInRange(const Vector<GrammarDetail>& grammarDet
if (markAll) {
RefPtr<Range> badGrammarRange = TextIterator::subrange(searchRange, badGrammarPhraseLocation - startOffset + detail->location, detail->length);
ExceptionCode ec = 0;
- badGrammarRange->startContainer(ec)->document()->addMarker(badGrammarRange.get(), DocumentMarker::Grammar, detail->userDescription);
+ badGrammarRange->startContainer(ec)->document()->markers()->addMarker(badGrammarRange.get(), DocumentMarker::Grammar, detail->userDescription);
ASSERT(!ec);
}
@@ -2063,7 +2068,7 @@ void Editor::advanceToNextMisspelling(bool startBeforeSelection)
frame()->revealSelection();
client()->updateSpellingUIWithGrammarString(badGrammarPhrase, grammarDetail);
- frame()->document()->addMarker(badGrammarRange.get(), DocumentMarker::Grammar, grammarDetail.userDescription);
+ frame()->document()->markers()->addMarker(badGrammarRange.get(), DocumentMarker::Grammar, grammarDetail.userDescription);
#endif
} else if (!misspelledWord.isEmpty()) {
// We found a misspelling, but not any earlier bad grammar. Select the misspelling, update the spelling panel, and store
@@ -2074,7 +2079,7 @@ void Editor::advanceToNextMisspelling(bool startBeforeSelection)
frame()->revealSelection();
client()->updateSpellingUIWithMisspelledWord(misspelledWord);
- frame()->document()->addMarker(misspellingRange.get(), DocumentMarker::Spelling);
+ frame()->document()->markers()->addMarker(misspellingRange.get(), DocumentMarker::Spelling);
}
}
@@ -2543,7 +2548,7 @@ void Editor::markAllMisspellingsAndBadGrammarInRanges(bool markSpelling, Range*
if (markSpelling && result->type == TextCheckingTypeSpelling && resultLocation >= spellingRangeStartOffset && resultLocation + resultLength <= spellingRangeEndOffset) {
ASSERT(resultLength > 0 && resultLocation >= 0);
RefPtr<Range> misspellingRange = TextIterator::subrange(spellingRange, resultLocation - spellingRangeStartOffset, resultLength);
- misspellingRange->startContainer(ec)->document()->addMarker(misspellingRange.get(), DocumentMarker::Spelling);
+ misspellingRange->startContainer(ec)->document()->markers()->addMarker(misspellingRange.get(), DocumentMarker::Spelling);
} else if (markGrammar && result->type == TextCheckingTypeGrammar && resultLocation < grammarRangeEndOffset && resultLocation + resultLength > grammarRangeStartOffset) {
ASSERT(resultLength > 0 && resultLocation >= 0);
for (unsigned j = 0; j < result->details.size(); j++) {
@@ -2551,7 +2556,7 @@ void Editor::markAllMisspellingsAndBadGrammarInRanges(bool markSpelling, Range*
ASSERT(detail->length > 0 && detail->location >= 0);
if (resultLocation + detail->location >= grammarRangeStartOffset && resultLocation + detail->location + detail->length <= grammarRangeEndOffset) {
RefPtr<Range> badGrammarRange = TextIterator::subrange(grammarRange, resultLocation + detail->location - grammarRangeStartOffset, detail->length);
- grammarRange->startContainer(ec)->document()->addMarker(badGrammarRange.get(), DocumentMarker::Grammar, detail->userDescription);
+ grammarRange->startContainer(ec)->document()->markers()->addMarker(badGrammarRange.get(), DocumentMarker::Grammar, detail->userDescription);
}
}
} else if (performTextCheckingReplacements && resultLocation + resultLength <= spellingRangeEndOffset && resultLocation + resultLength >= spellingRangeStartOffset
@@ -2581,7 +2586,7 @@ void Editor::markAllMisspellingsAndBadGrammarInRanges(bool markSpelling, Range*
Node* node = rangeToReplace->startContainer();
int startOffset = rangeToReplace->startOffset();
int endOffset = startOffset + replacementLength;
- Vector<DocumentMarker> markers = node->document()->markersForNode(node);
+ Vector<DocumentMarker> markers = node->document()->markers()->markersForNode(node);
size_t markerCount = markers.size();
for (size_t i = 0; i < markerCount; ++i) {
const DocumentMarker& marker = markers[i];
@@ -2618,7 +2623,7 @@ void Editor::markAllMisspellingsAndBadGrammarInRanges(bool markSpelling, Range*
if (result->type == TextCheckingTypeCorrection) {
// Add a marker so that corrections can easily be undone and won't be re-corrected.
RefPtr<Range> replacedRange = TextIterator::subrange(paragraphRange.get(), resultLocation, replacementLength);
- replacedRange->startContainer()->document()->addMarker(replacedRange.get(), DocumentMarker::Replacement, replacedString);
+ replacedRange->startContainer()->document()->markers()->addMarker(replacedRange.get(), DocumentMarker::Replacement, replacedString);
}
}
}
@@ -2656,7 +2661,7 @@ void Editor::changeBackToReplacedString(const String& replacedString)
RefPtr<Range> paragraphRange = paragraphAlignedRangeForRange(selection.get(), selectionOffset, paragraphString);
replaceSelectionWithText(replacedString, false, false);
RefPtr<Range> changedRange = TextIterator::subrange(paragraphRange.get(), selectionOffset, replacedString.length());
- changedRange->startContainer()->document()->addMarker(changedRange.get(), DocumentMarker::Replacement, String());
+ changedRange->startContainer()->document()->markers()->addMarker(changedRange.get(), DocumentMarker::Replacement, String());
}
#endif
@@ -2937,6 +2942,10 @@ PassRefPtr<Range> Editor::nextVisibleRange(Range* currentRange, const String& ta
void Editor::changeSelectionAfterCommand(const VisibleSelection& newSelection, bool closeTyping, bool clearTypingStyle)
{
+ // If the new selection is orphaned, then don't update the selection.
+ if (newSelection.start().isOrphan() || newSelection.end().isOrphan())
+ return;
+
// If there is no selection change, don't bother sending shouldChangeSelection, but still call setSelection,
// because there is work that it must do in this situation.
// The old selection can be invalid here and calling shouldChangeSelection can produce some strange calls.
diff --git a/WebCore/editing/Editor.h b/WebCore/editing/Editor.h
index 06e7513..83aef7e 100644
--- a/WebCore/editing/Editor.h
+++ b/WebCore/editing/Editor.h
@@ -299,6 +299,9 @@ public:
void pasteAsFragment(PassRefPtr<DocumentFragment>, bool smartReplace, bool matchStyle);
void pasteAsPlainText(const String&, bool smartReplace);
+ // This is only called on the mac where paste is implemented primarily at the WebKit level.
+ void pasteAsPlainTextBypassingDHTML();
+
Node* findEventTargetFrom(const VisibleSelection& selection) const;
private:
Frame* m_frame;
diff --git a/WebCore/editing/FormatBlockCommand.cpp b/WebCore/editing/FormatBlockCommand.cpp
index d92f365..221aecf 100644
--- a/WebCore/editing/FormatBlockCommand.cpp
+++ b/WebCore/editing/FormatBlockCommand.cpp
@@ -70,7 +70,7 @@ bool FormatBlockCommand::modifyRange()
void FormatBlockCommand::doApply()
{
- if (endingSelection().isNone())
+ if (!endingSelection().isNonOrphanedCaretOrRange())
return;
if (!endingSelection().rootEditableElement())
diff --git a/WebCore/editing/IndentOutdentCommand.cpp b/WebCore/editing/IndentOutdentCommand.cpp
index f041aa7..d4ffe7f 100644
--- a/WebCore/editing/IndentOutdentCommand.cpp
+++ b/WebCore/editing/IndentOutdentCommand.cpp
@@ -329,7 +329,7 @@ void IndentOutdentCommand::outdentRegion(const VisiblePosition& startOfSelection
void IndentOutdentCommand::doApply()
{
- if (endingSelection().isNone())
+ if (!endingSelection().isNonOrphanedCaretOrRange())
return;
if (!endingSelection().rootEditableElement())
diff --git a/WebCore/editing/InsertLineBreakCommand.cpp b/WebCore/editing/InsertLineBreakCommand.cpp
index f815d98..dbe4b39 100644
--- a/WebCore/editing/InsertLineBreakCommand.cpp
+++ b/WebCore/editing/InsertLineBreakCommand.cpp
@@ -90,7 +90,7 @@ void InsertLineBreakCommand::doApply()
{
deleteSelection();
VisibleSelection selection = endingSelection();
- if (selection.isNone())
+ if (!selection.isNonOrphanedCaretOrRange())
return;
VisiblePosition caret(selection.visibleStart());
diff --git a/WebCore/editing/InsertListCommand.cpp b/WebCore/editing/InsertListCommand.cpp
index 59a8bce..f90d5d3 100644
--- a/WebCore/editing/InsertListCommand.cpp
+++ b/WebCore/editing/InsertListCommand.cpp
@@ -37,6 +37,14 @@ namespace WebCore {
using namespace HTMLNames;
+static Node* enclosingListChild(Node* node, Node* listNode)
+{
+ Node* listChild = enclosingListChild(node);
+ while (listChild && enclosingList(listChild) != listNode)
+ listChild = enclosingListChild(listChild->parentNode());
+ return listChild;
+}
+
PassRefPtr<HTMLElement> InsertListCommand::insertList(Document* document, Type type)
{
RefPtr<InsertListCommand> insertCommand = create(document, type);
@@ -97,9 +105,9 @@ InsertListCommand::InsertListCommand(Document* document, Type type)
void InsertListCommand::doApply()
{
- if (endingSelection().isNone())
+ if (!endingSelection().isNonOrphanedCaretOrRange())
return;
-
+
if (!endingSelection().rootEditableElement())
return;
@@ -138,7 +146,19 @@ void InsertListCommand::doApply()
if (!startOfLastParagraph.deepEquivalent().node()->inDocument())
return;
setEndingSelection(startOfCurrentParagraph);
+
+ // Save and restore endOfSelection and startOfLastParagraph when necessary
+ // since moveParagraph and movePragraphWithClones can remove nodes.
+ // FIXME: This is an inefficient way to keep selection alive because indexForVisiblePosition walks from
+ // the beginning of the document to the endOfSelection everytime this code is executed.
+ // But not using index is hard because there are so many ways we can lose selection inside doApplyForSingleParagraph.
+ int indexForEndOfSelection = indexForVisiblePosition(endOfSelection);
doApplyForSingleParagraph(forceCreateList, listTag, currentSelection.get());
+ if (endOfSelection.isNull() || endOfSelection.isOrphan() || startOfLastParagraph.isNull() || startOfLastParagraph.isOrphan()) {
+ RefPtr<Range> lastSelectionRange = TextIterator::rangeFromLocationAndLength(document()->documentElement(), indexForEndOfSelection, 0, true);
+ endOfSelection = lastSelectionRange->startPosition();
+ startOfLastParagraph = startOfParagraph(endOfSelection);
+ }
// Fetch the start of the selection after moving the first paragraph,
// because moving the paragraph will invalidate the original start.
@@ -186,12 +206,35 @@ void InsertListCommand::doApplyForSingleParagraph(bool forceCreateList, const Qu
// If the entire list is selected, then convert the whole list.
if (switchListType && isNodeVisiblyContainedWithin(listNode.get(), currentSelection)) {
+ bool rangeStartIsInList = visiblePositionBeforeNode(listNode.get()) == currentSelection->startPosition();
+ bool rangeEndIsInList = visiblePositionAfterNode(listNode.get()) == currentSelection->endPosition();
+
RefPtr<HTMLElement> newList = createHTMLElement(document(), listTag);
insertNodeBefore(newList, listNode);
- Node* outerBlock = listChildNode->isBlockFlow() ? listChildNode : listNode.get();
+
+ Node* firstChildInList = enclosingListChild(VisiblePosition(Position(listNode, 0)).deepEquivalent().node(), listNode.get());
+ Node* outerBlock = firstChildInList->isBlockFlow() ? firstChildInList : listNode.get();
+
moveParagraphWithClones(firstPositionInNode(listNode.get()), lastPositionInNode(listNode.get()), newList.get(), outerBlock);
+
+ // Manually remove listNode because moveParagraphWithClones sometimes leaves it behind in the document.
+ // See the bug 33668 and editing/execCommand/insert-list-orphaned-item-with-nested-lists.html.
+ // FIXME: This might be a bug in moveParagraphWithClones or deleteSelection.
+ if (listNode && listNode->inDocument())
+ removeNode(listNode);
+
newList = mergeWithNeighboringLists(newList);
+
+ // Restore the start and the end of current selection if they started inside listNode
+ // because moveParagraphWithClones could have removed them.
+ ExceptionCode ec;
+ if (rangeStartIsInList && newList)
+ currentSelection->setStart(newList, 0, ec);
+ if (rangeEndIsInList && newList)
+ currentSelection->setEnd(newList, lastOffsetInNode(newList.get()), ec);
+
setEndingSelection(VisiblePosition(firstPositionInNode(newList.get())));
+
return;
}
@@ -202,14 +245,6 @@ void InsertListCommand::doApplyForSingleParagraph(bool forceCreateList, const Qu
m_listElement = listifyParagraph(endingSelection().visibleStart(), listTag);
}
-static Node* enclosingListChild(Node* node, Node* listNode)
-{
- Node* listChild = enclosingListChild(node);
- if (enclosingList(listChild) != listNode)
- return 0;
- return listChild;
-}
-
void InsertListCommand::unlistifyParagraph(const VisiblePosition& originalStart, HTMLElement* listNode, Node* listChildNode)
{
Node* nextListChild;
@@ -278,7 +313,8 @@ static Element* adjacentEnclosingList(const VisiblePosition& pos, const VisibleP
if (!listNode->hasTagName(listTag)
|| listNode->contains(pos.deepEquivalent().node())
- || previousCell != currentCell)
+ || previousCell != currentCell
+ || enclosingList(listNode) != enclosingList(pos.deepEquivalent().node()))
return 0;
return listNode;
@@ -288,6 +324,9 @@ PassRefPtr<HTMLElement> InsertListCommand::listifyParagraph(const VisiblePositio
{
VisiblePosition start = startOfParagraph(originalStart);
VisiblePosition end = endOfParagraph(start);
+
+ if (start.isNull() || end.isNull())
+ return 0;
// Check for adjoining lists.
RefPtr<HTMLElement> listItemElement = createListItemElement(document());
diff --git a/WebCore/editing/InsertParagraphSeparatorCommand.cpp b/WebCore/editing/InsertParagraphSeparatorCommand.cpp
index a3dfa83..1804bf4 100644
--- a/WebCore/editing/InsertParagraphSeparatorCommand.cpp
+++ b/WebCore/editing/InsertParagraphSeparatorCommand.cpp
@@ -148,7 +148,7 @@ PassRefPtr<Element> InsertParagraphSeparatorCommand::cloneHierarchyUnderNewBlock
void InsertParagraphSeparatorCommand::doApply()
{
bool splitText = false;
- if (endingSelection().isNone())
+ if (!endingSelection().isNonOrphanedCaretOrRange())
return;
Position insertionPosition = endingSelection().start();
diff --git a/WebCore/editing/InsertTextCommand.cpp b/WebCore/editing/InsertTextCommand.cpp
index 52eb12f..cfaf219 100644
--- a/WebCore/editing/InsertTextCommand.cpp
+++ b/WebCore/editing/InsertTextCommand.cpp
@@ -111,7 +111,7 @@ void InsertTextCommand::input(const String& text, bool selectInsertedText)
ASSERT(text.find('\n') == notFound);
- if (endingSelection().isNone())
+ if (!endingSelection().isNonOrphanedCaretOrRange())
return;
// Delete the current selection.
diff --git a/WebCore/editing/MoveSelectionCommand.cpp b/WebCore/editing/MoveSelectionCommand.cpp
index 62f638f..3a1cae0 100644
--- a/WebCore/editing/MoveSelectionCommand.cpp
+++ b/WebCore/editing/MoveSelectionCommand.cpp
@@ -40,7 +40,7 @@ MoveSelectionCommand::MoveSelectionCommand(PassRefPtr<DocumentFragment> fragment
void MoveSelectionCommand::doApply()
{
VisibleSelection selection = endingSelection();
- ASSERT(selection.isRange());
+ ASSERT(selection.isNonOrphanedRange());
Position pos = m_position;
if (pos.isNull())
diff --git a/WebCore/editing/RemoveFormatCommand.cpp b/WebCore/editing/RemoveFormatCommand.cpp
index e456df6..257172b 100644
--- a/WebCore/editing/RemoveFormatCommand.cpp
+++ b/WebCore/editing/RemoveFormatCommand.cpp
@@ -49,7 +49,10 @@ RemoveFormatCommand::RemoveFormatCommand(Document* document)
void RemoveFormatCommand::doApply()
{
Frame* frame = document()->frame();
-
+
+ if (!frame->selection()->selection().isNonOrphanedCaretOrRange())
+ return;
+
// Make a plain text string from the selection to remove formatting like tables and lists.
String string = plainText(frame->selection()->selection().toNormalizedRange().get());
diff --git a/WebCore/editing/ReplaceSelectionCommand.cpp b/WebCore/editing/ReplaceSelectionCommand.cpp
index 2f0bddf..d497f30 100644
--- a/WebCore/editing/ReplaceSelectionCommand.cpp
+++ b/WebCore/editing/ReplaceSelectionCommand.cpp
@@ -782,7 +782,7 @@ void ReplaceSelectionCommand::doApply()
VisibleSelection selection = endingSelection();
ASSERT(selection.isCaretOrRange());
ASSERT(selection.start().node());
- if (selection.isNone() || !selection.start().node())
+ if (!selection.isNonOrphanedCaretOrRange() || !selection.start().node())
return;
bool selectionIsPlainText = !selection.isContentRichlyEditable();
diff --git a/WebCore/editing/SelectionController.cpp b/WebCore/editing/SelectionController.cpp
index 9ca375b..3672e3e 100644
--- a/WebCore/editing/SelectionController.cpp
+++ b/WebCore/editing/SelectionController.cpp
@@ -70,7 +70,7 @@ SelectionController::SelectionController(Frame* frame, bool isDragCaretControlle
, m_xPosForVerticalArrowNavigation(NoXPosForVerticalArrowNavigation)
, m_granularity(CharacterGranularity)
, m_caretBlinkTimer(this, &SelectionController::caretBlinkTimerFired)
- , m_needsLayout(true)
+ , m_caretRectNeedsUpdate(true)
, m_absCaretBoundsDirty(true)
, m_isDragCaretController(isDragCaretController)
, m_isCaretBlinkingSuspended(false)
@@ -116,7 +116,7 @@ void SelectionController::setSelection(const VisibleSelection& s, bool closeTypi
if (m_isDragCaretController) {
invalidateCaretRect();
m_selection = s;
- m_needsLayout = true;
+ m_caretRectNeedsUpdate = true;
invalidateCaretRect();
return;
}
@@ -150,7 +150,7 @@ void SelectionController::setSelection(const VisibleSelection& s, bool closeTypi
m_selection = s;
- m_needsLayout = true;
+ m_caretRectNeedsUpdate = true;
if (!s.isNone())
m_frame->setFocusedNodeIfNeeded();
@@ -705,7 +705,7 @@ bool SelectionController::modify(EAlteration alter, EDirection direction, TextGr
m_granularity = CharacterGranularity;
- setNeedsLayout();
+ setCaretRectNeedsUpdate();
setIsDirectional(alter == AlterationExtend);
@@ -886,12 +886,12 @@ void SelectionController::setExtent(const Position &pos, EAffinity affinity, boo
setSelection(VisibleSelection(m_selection.base(), pos, affinity), true, true, userTriggered);
}
-void SelectionController::setNeedsLayout(bool flag)
+void SelectionController::setCaretRectNeedsUpdate(bool flag)
{
- m_needsLayout = flag;
+ m_caretRectNeedsUpdate = flag;
}
-void SelectionController::layout()
+void SelectionController::updateCaretRect()
{
if (isNone() || !m_selection.start().node()->inDocument() || !m_selection.end().node()->inDocument()) {
m_caretRect = IntRect();
@@ -934,7 +934,7 @@ void SelectionController::layout()
}
}
- m_needsLayout = false;
+ m_caretRectNeedsUpdate = false;
}
RenderObject* SelectionController::caretRenderer() const
@@ -952,10 +952,10 @@ RenderObject* SelectionController::caretRenderer() const
return paintedByBlock ? renderer : renderer->containingBlock();
}
-IntRect SelectionController::localCaretRect() const
+IntRect SelectionController::localCaretRect()
{
- if (m_needsLayout)
- const_cast<SelectionController*>(this)->layout();
+ if (m_caretRectNeedsUpdate)
+ updateCaretRect();
return m_caretRect;
}
@@ -987,11 +987,14 @@ static IntRect repaintRectForCaret(IntRect caret)
IntRect SelectionController::caretRepaintRect() const
{
- return absoluteBoundsForLocalRect(repaintRectForCaret(localCaretRect()));
+ return absoluteBoundsForLocalRect(repaintRectForCaret(localCaretRectForPainting()));
}
bool SelectionController::recomputeCaretRect()
{
+ if (!m_caretRectNeedsUpdate)
+ return false;
+
if (!m_frame)
return false;
@@ -999,9 +1002,6 @@ bool SelectionController::recomputeCaretRect()
if (!v)
return false;
- if (!m_needsLayout)
- return false;
-
IntRect oldRect = m_caretRect;
IntRect newRect = localCaretRect();
if (oldRect == newRect && !m_absCaretBoundsDirty)
@@ -1060,7 +1060,7 @@ void SelectionController::invalidateCaretRect()
// changes which may have been done.
// And, we need to leave this layout here so the caret moves right
// away after clicking.
- m_needsLayout = true;
+ m_caretRectNeedsUpdate = true;
if (!caretRectChanged) {
RenderView* view = toRenderView(d->renderer());
@@ -1079,7 +1079,7 @@ void SelectionController::paintCaret(GraphicsContext* context, int tx, int ty, c
if (!m_selection.isCaret())
return;
- IntRect drawingRect = localCaretRect();
+ IntRect drawingRect = localCaretRectForPainting();
drawingRect.move(tx, ty);
IntRect caret = intersection(drawingRect, clipRect);
if (caret.isEmpty())
diff --git a/WebCore/editing/SelectionController.h b/WebCore/editing/SelectionController.h
index 5d2ee9f..5fa2769 100644
--- a/WebCore/editing/SelectionController.h
+++ b/WebCore/editing/SelectionController.h
@@ -100,10 +100,12 @@ public:
RenderObject* caretRenderer() const;
// Caret rect local to the caret's renderer
- IntRect localCaretRect() const;
+ IntRect localCaretRect();
+ IntRect localCaretRectForPainting() const { return m_caretRect; }
+
// Bounds of (possibly transformed) caret in absolute coords
IntRect absoluteCaretBounds();
- void setNeedsLayout(bool flag = true);
+ void setCaretRectNeedsUpdate(bool flag = true);
void setIsDirectional(bool);
void willBeModified(EAlteration, EDirection);
@@ -167,7 +169,7 @@ private:
VisiblePosition modifyMovingLeft(TextGranularity);
VisiblePosition modifyMovingBackward(TextGranularity);
- void layout();
+ void updateCaretRect();
IntRect caretRepaintRect() const;
bool shouldRepaintCaret(const RenderView* view) const;
@@ -197,7 +199,7 @@ private:
IntRect m_absCaretBounds; // absolute bounding rect for the caret
IntRect m_absoluteCaretRepaintBounds;
- bool m_needsLayout; // true if m_caretRect and m_absCaretBounds need to be calculated
+ bool m_caretRectNeedsUpdate; // true if m_caretRect and m_absCaretBounds need to be calculated
bool m_absCaretBoundsDirty;
bool m_isDirectional;
bool m_isDragCaretController;
diff --git a/WebCore/editing/SplitTextNodeCommand.cpp b/WebCore/editing/SplitTextNodeCommand.cpp
index 9a7e3b3..1f38902 100644
--- a/WebCore/editing/SplitTextNodeCommand.cpp
+++ b/WebCore/editing/SplitTextNodeCommand.cpp
@@ -60,7 +60,7 @@ void SplitTextNodeCommand::doApply()
m_text1 = Text::create(document(), prefixText);
ASSERT(m_text1);
- document()->copyMarkers(m_text2.get(), 0, m_offset, m_text1.get(), 0);
+ document()->markers()->copyMarkers(m_text2.get(), 0, m_offset, m_text1.get(), 0);
insertText1AndTrimText2();
}
@@ -78,7 +78,7 @@ void SplitTextNodeCommand::doUnapply()
m_text2->insertData(0, prefixText, ec);
ASSERT(!ec);
- document()->copyMarkers(m_text1.get(), 0, prefixText.length(), m_text2.get(), 0);
+ document()->markers()->copyMarkers(m_text1.get(), 0, prefixText.length(), m_text2.get(), 0);
m_text1->remove(ec);
}
diff --git a/WebCore/editing/TextIterator.cpp b/WebCore/editing/TextIterator.cpp
index 39013c1..57f9a3c 100644
--- a/WebCore/editing/TextIterator.cpp
+++ b/WebCore/editing/TextIterator.cpp
@@ -2223,7 +2223,7 @@ UChar* plainTextToMallocAllocatedBuffer(const Range* r, unsigned& bufferLength,
static const unsigned cMaxSegmentSize = 1 << 16;
bufferLength = 0;
typedef pair<UChar*, unsigned> TextSegment;
- Vector<TextSegment>* textSegments = 0;
+ OwnPtr<Vector<TextSegment> > textSegments;
Vector<UChar> textBuffer;
textBuffer.reserveInitialCapacity(cMaxSegmentSize);
for (TextIterator it(r, isDisplayString ? TextIteratorDefaultBehavior : TextIteratorEmitsTextsWithoutTranscoding); !it.atEnd(); it.advance()) {
@@ -2233,7 +2233,7 @@ UChar* plainTextToMallocAllocatedBuffer(const Range* r, unsigned& bufferLength,
goto exit;
memcpy(newSegmentBuffer, textBuffer.data(), textBuffer.size() * sizeof(UChar));
if (!textSegments)
- textSegments = new Vector<TextSegment>;
+ textSegments = adoptPtr(new Vector<TextSegment>);
textSegments->append(make_pair(newSegmentBuffer, (unsigned)textBuffer.size()));
textBuffer.clear();
}
@@ -2267,7 +2267,6 @@ exit:
unsigned size = textSegments->size();
for (unsigned i = 0; i < size; ++i)
free(textSegments->at(i).first);
- delete textSegments;
}
if (isDisplayString && r->ownerDocument())
diff --git a/WebCore/editing/TypingCommand.cpp b/WebCore/editing/TypingCommand.cpp
index bab3111..ac865e5 100644
--- a/WebCore/editing/TypingCommand.cpp
+++ b/WebCore/editing/TypingCommand.cpp
@@ -244,7 +244,7 @@ void TypingCommand::closeTyping(EditCommand* cmd)
void TypingCommand::doApply()
{
- if (endingSelection().isNone())
+ if (!endingSelection().isNonOrphanedCaretOrRange())
return;
if (m_commandType == DeleteKey)
diff --git a/WebCore/editing/UnlinkCommand.cpp b/WebCore/editing/UnlinkCommand.cpp
index 7234a3b..0518838 100644
--- a/WebCore/editing/UnlinkCommand.cpp
+++ b/WebCore/editing/UnlinkCommand.cpp
@@ -38,10 +38,8 @@ UnlinkCommand::UnlinkCommand(Document* document)
void UnlinkCommand::doApply()
{
// FIXME: If a caret is inside a link, we should remove it, but currently we don't.
- if (!endingSelection().isRange())
+ if (!endingSelection().isNonOrphanedRange())
return;
-
- pushPartiallySelectedAnchorElementsDown();
removeStyledElement(HTMLAnchorElement::create(document()));
}
diff --git a/WebCore/editing/VisibleSelection.h b/WebCore/editing/VisibleSelection.h
index 4ce2b92..ffdb6f8 100644
--- a/WebCore/editing/VisibleSelection.h
+++ b/WebCore/editing/VisibleSelection.h
@@ -73,6 +73,8 @@ public:
bool isCaret() const { return selectionType() == CaretSelection; }
bool isRange() const { return selectionType() == RangeSelection; }
bool isCaretOrRange() const { return selectionType() != NoSelection; }
+ bool isNonOrphanedRange() const { return isRange() && !start().isOrphan() && !end().isOrphan(); }
+ bool isNonOrphanedCaretOrRange() const { return isCaretOrRange() && !start().isOrphan() && !end().isOrphan(); }
bool isBaseFirst() const { return m_baseIsFirst; }
diff --git a/WebCore/editing/htmlediting.h b/WebCore/editing/htmlediting.h
index 8612440..aaf6ef2 100644
--- a/WebCore/editing/htmlediting.h
+++ b/WebCore/editing/htmlediting.h
@@ -218,9 +218,8 @@ bool canMergeLists(Element* firstList, Element* secondList);
// -------------------------------------------------------------------------
// VisibleSelection
// -------------------------------------------------------------------------
-
-// Functions returning VisibleSelection
+// Functions returning VisibleSelection
VisibleSelection avoidIntersectionWithNode(const VisibleSelection&, Node*);
VisibleSelection selectionForParagraphIteration(const VisibleSelection&);
diff --git a/WebCore/editing/markup.cpp b/WebCore/editing/markup.cpp
index b1ec07c..1baf1bc 100644
--- a/WebCore/editing/markup.cpp
+++ b/WebCore/editing/markup.cpp
@@ -26,6 +26,7 @@
#include "config.h"
#include "markup.h"
+#include "ApplyStyleCommand.h"
#include "CDATASection.h"
#include "CharacterNames.h"
#include "Comment.h"
@@ -45,6 +46,7 @@
#include "DocumentType.h"
#include "Editor.h"
#include "Frame.h"
+#include "HTMLBodyElement.h"
#include "HTMLElement.h"
#include "HTMLNames.h"
#include "InlineTextBox.h"
@@ -52,13 +54,12 @@
#include "Logging.h"
#include "ProcessingInstruction.h"
#include "Range.h"
-#include "VisibleSelection.h"
#include "TextIterator.h"
+#include "VisibleSelection.h"
#include "XMLNSNames.h"
#include "htmlediting.h"
#include "visible_units.h"
#include <wtf/StdLibExtras.h>
-#include "ApplyStyleCommand.h"
using namespace std;
@@ -66,7 +67,7 @@ namespace WebCore {
using namespace HTMLNames;
-static inline bool shouldSelfClose(const Node *node);
+static bool propertyMissingOrEqualToNone(CSSStyleDeclaration*, int propertyID);
class AttributeChange {
public:
@@ -91,10 +92,139 @@ private:
String m_value;
};
-static void appendAttributeValue(Vector<UChar>& result, const String& attr, bool escapeNBSP)
+typedef HashMap<AtomicStringImpl*, AtomicStringImpl*> Namespaces;
+
+class MarkupAccumulator {
+public:
+ enum RangeFullySelectsNode { DoesFullySelectNode, DoesNotFullySelectNode };
+
+ MarkupAccumulator(Vector<Node*>* nodes, EAbsoluteURLs shouldResolveURLs, EAnnotateForInterchange shouldAnnotate, const Range* range = 0)
+ : m_nodes(nodes)
+ , m_shouldResolveURLs(shouldResolveURLs)
+ , m_shouldAnnotate(shouldAnnotate)
+ , m_range(range)
+ {
+ }
+ void appendString(const String&);
+ void appendStartTag(Node*, Namespaces* = 0);
+ void appendEndTag(Node*);
+ void wrapWithNode(Node*, bool convertBlocksToInlines = false, RangeFullySelectsNode = DoesFullySelectNode);
+ void wrapWithStyleNode(CSSStyleDeclaration*, Document*, bool isBlock = false);
+ String takeResults();
+
+private:
+ void appendAttributeValue(Vector<UChar>& result, const String& attribute, bool escapeNBSP);
+ String escapeContentText(const String&, bool escapeNBSP);
+ void appendQuotedURLAttributeValue(Vector<UChar>& result, const String& urlString);
+ String stringValueForRange(const Node*, const Range*);
+ pair<const UChar*, size_t> ucharRange(const Node*, const Range *);
+ void appendUCharRange(Vector<UChar>& result, const pair<const UChar*, size_t>& range);
+ String renderedText(const Node*, const Range*);
+ bool shouldAddNamespaceElement(const Element*);
+ bool shouldAddNamespaceAttribute(const Attribute*, Namespaces&);
+ void appendNamespace(Vector<UChar>& result, const AtomicString& prefix, const AtomicString& namespaceURI, Namespaces&);
+ void appendText(Vector<UChar>& out, Text*);
+ void appendComment(Vector<UChar>& out, const String& comment);
+ void appendDocumentType(Vector<UChar>& result, const DocumentType*);
+ void appendProcessingInstruction(Vector<UChar>& out, const String& target, const String& data);
+ void removeExteriorStyles(CSSMutableStyleDeclaration*);
+ void appendElement(Vector<UChar>& out, Element* element, bool addDisplayInline, Namespaces*, RangeFullySelectsNode);
+ void appendCDATASection(Vector<UChar>& out, const String& section);
+ void appendStartMarkup(Vector<UChar>& result, const Node*, bool convertBlocksToInlines, Namespaces*, RangeFullySelectsNode);
+ bool shouldSelfClose(const Node*);
+ void appendEndMarkup(Vector<UChar>& result, const Node*);
+
+ bool shouldResolveURLs() { return m_shouldResolveURLs == AbsoluteURLs; }
+ bool shouldAnnotate() { return m_shouldAnnotate == AnnotateForInterchange; }
+
+ Vector<Node*>* const m_nodes;
+ const bool m_shouldResolveURLs;
+ const EAnnotateForInterchange m_shouldAnnotate;
+ const Range* const m_range;
+ Vector<String> m_reversedPrecedingMarkup;
+ Vector<String> m_succeedingMarkup;
+};
+
+void MarkupAccumulator::appendString(const String& string)
+{
+ m_succeedingMarkup.append(string);
+}
+
+void MarkupAccumulator::appendStartTag(Node* node, Namespaces* namespaces)
+{
+ Vector<UChar> markup;
+ appendStartMarkup(markup, node, false, namespaces, DoesFullySelectNode);
+ m_succeedingMarkup.append(String::adopt(markup));
+ if (m_nodes)
+ m_nodes->append(node);
+}
+
+void MarkupAccumulator::appendEndTag(Node* node)
+{
+ Vector<UChar> markup;
+ appendEndMarkup(markup, node);
+ m_succeedingMarkup.append(String::adopt(markup));
+}
+
+void MarkupAccumulator::wrapWithNode(Node* node, bool convertBlocksToInlines, RangeFullySelectsNode rangeFullySelectsNode)
+{
+ Vector<UChar> markup;
+ appendStartMarkup(markup, node, convertBlocksToInlines, 0, rangeFullySelectsNode);
+ m_reversedPrecedingMarkup.append(String::adopt(markup));
+ appendEndTag(node);
+ if (m_nodes)
+ m_nodes->append(node);
+}
+
+void MarkupAccumulator::wrapWithStyleNode(CSSStyleDeclaration* style, Document* document, bool isBlock)
+{
+ // All text-decoration-related elements should have been treated as special ancestors
+ // If we ever hit this ASSERT, we should export StyleChange in ApplyStyleCommand and use it here
+ ASSERT(propertyMissingOrEqualToNone(style, CSSPropertyTextDecoration) && propertyMissingOrEqualToNone(style, CSSPropertyWebkitTextDecorationsInEffect));
+ DEFINE_STATIC_LOCAL(const String, divStyle, ("<div style=\""));
+ DEFINE_STATIC_LOCAL(const String, divClose, ("</div>"));
+ DEFINE_STATIC_LOCAL(const String, styleSpanOpen, ("<span class=\"" AppleStyleSpanClass "\" style=\""));
+ DEFINE_STATIC_LOCAL(const String, styleSpanClose, ("</span>"));
+ Vector<UChar> openTag;
+ append(openTag, isBlock ? divStyle : styleSpanOpen);
+ appendAttributeValue(openTag, style->cssText(), document->isHTMLDocument());
+ openTag.append('\"');
+ openTag.append('>');
+ m_reversedPrecedingMarkup.append(String::adopt(openTag));
+ m_succeedingMarkup.append(isBlock ? divClose : styleSpanClose);
+}
+
+// FIXME: This is a very inefficient way of accumulating the markup.
+// We're converting results of appendStartMarkup and appendEndMarkup from Vector<UChar> to String
+// and then back to Vector<UChar> and again to String here.
+String MarkupAccumulator::takeResults()
+{
+ size_t length = 0;
+
+ size_t preCount = m_reversedPrecedingMarkup.size();
+ for (size_t i = 0; i < preCount; ++i)
+ length += m_reversedPrecedingMarkup[i].length();
+
+ size_t postCount = m_succeedingMarkup.size();
+ for (size_t i = 0; i < postCount; ++i)
+ length += m_succeedingMarkup[i].length();
+
+ Vector<UChar> result;
+ result.reserveInitialCapacity(length);
+
+ for (size_t i = preCount; i > 0; --i)
+ append(result, m_reversedPrecedingMarkup[i - 1]);
+
+ for (size_t i = 0; i < postCount; ++i)
+ append(result, m_succeedingMarkup[i]);
+
+ return String::adopt(result);
+}
+
+void MarkupAccumulator::appendAttributeValue(Vector<UChar>& result, const String& attribute, bool escapeNBSP)
{
- const UChar* uchars = attr.characters();
- unsigned len = attr.length();
+ const UChar* uchars = attribute.characters();
+ unsigned len = attribute.length();
unsigned lastCopiedFrom = 0;
DEFINE_STATIC_LOCAL(const String, ampEntity, ("&amp;"));
@@ -106,33 +236,32 @@ static void appendAttributeValue(Vector<UChar>& result, const String& attr, bool
for (unsigned i = 0; i < len; ++i) {
UChar c = uchars[i];
switch (c) {
- case '&':
- result.append(uchars + lastCopiedFrom, i - lastCopiedFrom);
- append(result, ampEntity);
- lastCopiedFrom = i + 1;
- break;
- case '<':
- result.append(uchars + lastCopiedFrom, i - lastCopiedFrom);
- append(result, ltEntity);
- lastCopiedFrom = i + 1;
- break;
- case '>':
- result.append(uchars + lastCopiedFrom, i - lastCopiedFrom);
- append(result, gtEntity);
- lastCopiedFrom = i + 1;
- break;
- case '"':
- result.append(uchars + lastCopiedFrom, i - lastCopiedFrom);
- append(result, quotEntity);
- lastCopiedFrom = i + 1;
- break;
- case noBreakSpace:
- if (escapeNBSP) {
- result.append(uchars + lastCopiedFrom, i - lastCopiedFrom);
- append(result, nbspEntity);
- lastCopiedFrom = i + 1;
- }
+ case '&':
+ result.append(uchars + lastCopiedFrom, i - lastCopiedFrom);
+ append(result, ampEntity);
+ lastCopiedFrom = i + 1;
+ break;
+ case '<':
+ result.append(uchars + lastCopiedFrom, i - lastCopiedFrom);
+ append(result, ltEntity);
+ lastCopiedFrom = i + 1;
+ break;
+ case '>':
+ result.append(uchars + lastCopiedFrom, i - lastCopiedFrom);
+ append(result, gtEntity);
+ lastCopiedFrom = i + 1;
+ break;
+ case '"':
+ result.append(uchars + lastCopiedFrom, i - lastCopiedFrom);
+ append(result, quotEntity);
+ lastCopiedFrom = i + 1;
+ break;
+ case noBreakSpace:
+ if (!escapeNBSP)
break;
+ result.append(uchars + lastCopiedFrom, i - lastCopiedFrom);
+ append(result, nbspEntity);
+ lastCopiedFrom = i + 1;
}
}
@@ -153,42 +282,42 @@ static void appendEscapedContent(Vector<UChar>& result, pair<const UChar*, size_
for (unsigned i = 0; i < len; ++i) {
UChar c = uchars[i];
switch (c) {
- case '&':
- result.append(uchars + lastCopiedFrom, i - lastCopiedFrom);
- append(result, ampEntity);
- lastCopiedFrom = i + 1;
- break;
- case '<':
- result.append(uchars + lastCopiedFrom, i - lastCopiedFrom);
- append(result, ltEntity);
- lastCopiedFrom = i + 1;
- break;
- case '>':
- result.append(uchars + lastCopiedFrom, i - lastCopiedFrom);
- append(result, gtEntity);
- lastCopiedFrom = i + 1;
- break;
- case noBreakSpace:
- if (escapeNBSP) {
- result.append(uchars + lastCopiedFrom, i - lastCopiedFrom);
- append(result, nbspEntity);
- lastCopiedFrom = i + 1;
- }
+ case '&':
+ result.append(uchars + lastCopiedFrom, i - lastCopiedFrom);
+ append(result, ampEntity);
+ lastCopiedFrom = i + 1;
+ break;
+ case '<':
+ result.append(uchars + lastCopiedFrom, i - lastCopiedFrom);
+ append(result, ltEntity);
+ lastCopiedFrom = i + 1;
+ break;
+ case '>':
+ result.append(uchars + lastCopiedFrom, i - lastCopiedFrom);
+ append(result, gtEntity);
+ lastCopiedFrom = i + 1;
+ break;
+ case noBreakSpace:
+ if (!escapeNBSP)
break;
+ result.append(uchars + lastCopiedFrom, i - lastCopiedFrom);
+ append(result, nbspEntity);
+ lastCopiedFrom = i + 1;
+ break;
}
}
result.append(uchars + lastCopiedFrom, len - lastCopiedFrom);
}
-static String escapeContentText(const String& in, bool escapeNBSP)
+String MarkupAccumulator::escapeContentText(const String& in, bool escapeNBSP)
{
Vector<UChar> buffer;
appendEscapedContent(buffer, make_pair(in.characters(), in.length()), escapeNBSP);
return String::adopt(buffer);
}
-
-static void appendQuotedURLAttributeValue(Vector<UChar>& result, const String& urlString)
+
+void MarkupAccumulator::appendQuotedURLAttributeValue(Vector<UChar>& result, const String& urlString)
{
UChar quoteChar = '\"';
String strippedURLString = urlString.stripWhiteSpace();
@@ -211,8 +340,8 @@ static void appendQuotedURLAttributeValue(Vector<UChar>& result, const String& u
appendAttributeValue(result, urlString, false);
result.append(quoteChar);
}
-
-static String stringValueForRange(const Node* node, const Range* range)
+
+String MarkupAccumulator::stringValueForRange(const Node* node, const Range* range)
{
if (!range)
return node->nodeValue();
@@ -226,7 +355,7 @@ static String stringValueForRange(const Node* node, const Range* range)
return str;
}
-static inline pair<const UChar*, size_t> ucharRange(const Node *node, const Range *range)
+pair<const UChar*, size_t> MarkupAccumulator::ucharRange(const Node* node, const Range* range)
{
String str = node->nodeValue();
const UChar* characters = str.characters();
@@ -245,13 +374,13 @@ static inline pair<const UChar*, size_t> ucharRange(const Node *node, const Rang
return make_pair(characters, length);
}
-
-static inline void appendUCharRange(Vector<UChar>& result, const pair<const UChar*, size_t> range)
+
+void MarkupAccumulator::appendUCharRange(Vector<UChar>& result, const pair<const UChar*, size_t>& range)
{
result.append(range.first, range.second);
}
-
-static String renderedText(const Node* node, const Range* range)
+
+String MarkupAccumulator::renderedText(const Node* node, const Range* range)
{
if (!node->isTextNode())
return String();
@@ -304,44 +433,44 @@ static void removeDefaultStyles(CSSMutableStyleDeclaration* style, Document* doc
prepareEditingStyleToApplyAt(style, Position(document->documentElement(), 0));
}
-static bool shouldAddNamespaceElem(const Element* elem)
+bool MarkupAccumulator::shouldAddNamespaceElement(const Element* element)
{
// Don't add namespace attribute if it is already defined for this elem.
- const AtomicString& prefix = elem->prefix();
+ const AtomicString& prefix = element->prefix();
AtomicString attr = !prefix.isEmpty() ? "xmlns:" + prefix : "xmlns";
- return !elem->hasAttribute(attr);
+ return !element->hasAttribute(attr);
}
-static bool shouldAddNamespaceAttr(const Attribute* attr, HashMap<AtomicStringImpl*, AtomicStringImpl*>& namespaces)
+bool MarkupAccumulator::shouldAddNamespaceAttribute(const Attribute* attribute, Namespaces& namespaces)
{
namespaces.checkConsistency();
// Don't add namespace attributes twice
- if (attr->name() == XMLNSNames::xmlnsAttr) {
- namespaces.set(emptyAtom.impl(), attr->value().impl());
+ if (attribute->name() == XMLNSNames::xmlnsAttr) {
+ namespaces.set(emptyAtom.impl(), attribute->value().impl());
return false;
}
- QualifiedName xmlnsPrefixAttr(xmlnsAtom, attr->localName(), XMLNSNames::xmlnsNamespaceURI);
- if (attr->name() == xmlnsPrefixAttr) {
- namespaces.set(attr->localName().impl(), attr->value().impl());
+ QualifiedName xmlnsPrefixAttr(xmlnsAtom, attribute->localName(), XMLNSNames::xmlnsNamespaceURI);
+ if (attribute->name() == xmlnsPrefixAttr) {
+ namespaces.set(attribute->localName().impl(), attribute->value().impl());
return false;
}
return true;
}
-static void appendNamespace(Vector<UChar>& result, const AtomicString& prefix, const AtomicString& ns, HashMap<AtomicStringImpl*, AtomicStringImpl*>& namespaces)
+void MarkupAccumulator::appendNamespace(Vector<UChar>& result, const AtomicString& prefix, const AtomicString& namespaceURI, Namespaces& namespaces)
{
namespaces.checkConsistency();
- if (ns.isEmpty())
+ if (namespaceURI.isEmpty())
return;
// Use emptyAtoms's impl() for both null and empty strings since the HashMap can't handle 0 as a key
AtomicStringImpl* pre = prefix.isEmpty() ? emptyAtom.impl() : prefix.impl();
AtomicStringImpl* foundNS = namespaces.get(pre);
- if (foundNS != ns.impl()) {
- namespaces.set(pre, ns.impl());
+ if (foundNS != namespaceURI.impl()) {
+ namespaces.set(pre, namespaceURI.impl());
result.append(' ');
append(result, xmlnsAtom.string());
if (!prefix.isEmpty()) {
@@ -351,12 +480,42 @@ static void appendNamespace(Vector<UChar>& result, const AtomicString& prefix, c
result.append('=');
result.append('"');
- appendAttributeValue(result, ns, false);
+ appendAttributeValue(result, namespaceURI, false);
result.append('"');
}
}
-static void appendDocumentType(Vector<UChar>& result, const DocumentType* n)
+void MarkupAccumulator::appendText(Vector<UChar>& out, Text* text)
+{
+ const QualifiedName* parentName = 0;
+ if (text->parentElement())
+ parentName = &static_cast<Element*>(text->parentElement())->tagQName();
+
+ if (parentName && (*parentName == scriptTag || *parentName == styleTag || *parentName == xmpTag)) {
+ appendUCharRange(out, ucharRange(text, m_range));
+ return;
+ }
+
+ if (!shouldAnnotate() || (parentName && *parentName == textareaTag)) {
+ appendEscapedContent(out, ucharRange(text, m_range), text->document()->isHTMLDocument());
+ return;
+ }
+
+ bool useRenderedText = !enclosingNodeWithTag(Position(text, 0), selectTag);
+ String markup = escapeContentText(useRenderedText ? renderedText(text, m_range) : stringValueForRange(text, m_range), false);
+ markup = convertHTMLTextToInterchangeFormat(markup, text);
+ append(out, markup);
+}
+
+void MarkupAccumulator::appendComment(Vector<UChar>& out, const String& comment)
+{
+ // FIXME: Comment content is not escaped, but XMLSerializer (and possibly other callers) should raise an exception if it includes "-->".
+ append(out, "<!--");
+ append(out, comment);
+ append(out, "-->");
+}
+
+void MarkupAccumulator::appendDocumentType(Vector<UChar>& result, const DocumentType* n)
{
if (n->name().isEmpty())
return;
@@ -385,183 +544,167 @@ static void appendDocumentType(Vector<UChar>& result, const DocumentType* n)
append(result, ">");
}
-static void removeExteriorStyles(CSSMutableStyleDeclaration* style)
+void MarkupAccumulator::appendProcessingInstruction(Vector<UChar>& out, const String& target, const String& data)
{
- style->removeProperty(CSSPropertyFloat);
+ // FIXME: PI data is not escaped, but XMLSerializer (and possibly other callers) this should raise an exception if it includes "?>".
+ append(out, "<?");
+ append(out, target);
+ append(out, " ");
+ append(out, data);
+ append(out, "?>");
}
-enum RangeFullySelectsNode { DoesFullySelectNode, DoesNotFullySelectNode };
-
-static void appendStartMarkup(Vector<UChar>& result, const Node* node, const Range* range, EAnnotateForInterchange annotate, EAbsoluteURLs absoluteURLs, bool convertBlocksToInlines, HashMap<AtomicStringImpl*, AtomicStringImpl*>* namespaces, RangeFullySelectsNode rangeFullySelectsNode = DoesFullySelectNode)
+void MarkupAccumulator::removeExteriorStyles(CSSMutableStyleDeclaration* style)
{
- if (namespaces)
- namespaces->checkConsistency();
+ style->removeProperty(CSSPropertyFloat);
+}
- bool documentIsHTML = node->document()->isHTMLDocument();
- switch (node->nodeType()) {
- case Node::TEXT_NODE: {
- if (Node* parent = node->parentNode()) {
- if (parent->hasTagName(scriptTag)
- || parent->hasTagName(styleTag)
- || parent->hasTagName(xmpTag)) {
- appendUCharRange(result, ucharRange(node, range));
- break;
- } else if (parent->hasTagName(textareaTag)) {
- appendEscapedContent(result, ucharRange(node, range), documentIsHTML);
- break;
- }
- }
- if (!annotate) {
- appendEscapedContent(result, ucharRange(node, range), documentIsHTML);
- break;
- }
-
- bool useRenderedText = !enclosingNodeWithTag(Position(const_cast<Node*>(node), 0), selectTag);
- String markup = escapeContentText(useRenderedText ? renderedText(node, range) : stringValueForRange(node, range), false);
- markup = convertHTMLTextToInterchangeFormat(markup, static_cast<const Text*>(node));
- append(result, markup);
- break;
- }
- case Node::COMMENT_NODE:
- // FIXME: Comment content is not escaped, but XMLSerializer (and possibly other callers) should raise an exception if it includes "-->".
- append(result, "<!--");
- append(result, static_cast<const Comment*>(node)->data());
- append(result, "-->");
- break;
- case Node::DOCUMENT_NODE:
- case Node::DOCUMENT_FRAGMENT_NODE:
- break;
- case Node::DOCUMENT_TYPE_NODE:
- appendDocumentType(result, static_cast<const DocumentType*>(node));
- break;
- case Node::PROCESSING_INSTRUCTION_NODE: {
- // FIXME: PI data is not escaped, but XMLSerializer (and possibly other callers) this should raise an exception if it includes "?>".
- const ProcessingInstruction* n = static_cast<const ProcessingInstruction*>(node);
- append(result, "<?");
- append(result, n->target());
- append(result, " ");
- append(result, n->data());
- append(result, "?>");
- break;
+void MarkupAccumulator::appendElement(Vector<UChar>& out, Element* element, bool addDisplayInline, Namespaces* namespaces, RangeFullySelectsNode rangeFullySelectsNode)
+{
+ bool documentIsHTML = element->document()->isHTMLDocument();
+ out.append('<');
+ append(out, element->nodeNamePreservingCase());
+ if (!documentIsHTML && namespaces && shouldAddNamespaceElement(element))
+ appendNamespace(out, element->prefix(), element->namespaceURI(), *namespaces);
+
+ NamedNodeMap* attributes = element->attributes();
+ unsigned length = attributes->length();
+ for (unsigned int i = 0; i < length; i++) {
+ Attribute* attribute = attributes->attributeItem(i);
+ // We'll handle the style attribute separately, below.
+ if (attribute->name() == styleAttr && element->isHTMLElement() && (shouldAnnotate() || addDisplayInline))
+ continue;
+ out.append(' ');
+
+ if (documentIsHTML)
+ append(out, attribute->name().localName());
+ else
+ append(out, attribute->name().toString());
+
+ out.append('=');
+
+ if (element->isURLAttribute(attribute)) {
+ // We don't want to complete file:/// URLs because it may contain sensitive information
+ // about the user's system.
+ if (shouldResolveURLs() && !element->document()->url().isLocalFile())
+ appendQuotedURLAttributeValue(out, element->document()->completeURL(attribute->value()).string());
+ else
+ appendQuotedURLAttributeValue(out, attribute->value().string());
+ } else {
+ out.append('\"');
+ appendAttributeValue(out, attribute->value(), documentIsHTML);
+ out.append('\"');
}
- case Node::ELEMENT_NODE: {
- result.append('<');
- const Element* el = static_cast<const Element*>(node);
- bool convert = convertBlocksToInlines && isBlock(const_cast<Node*>(node));
- append(result, el->nodeNamePreservingCase());
- NamedNodeMap *attrs = el->attributes();
- unsigned length = attrs->length();
- if (!documentIsHTML && namespaces && shouldAddNamespaceElem(el))
- appendNamespace(result, el->prefix(), el->namespaceURI(), *namespaces);
-
- for (unsigned int i = 0; i < length; i++) {
- Attribute *attr = attrs->attributeItem(i);
- // We'll handle the style attribute separately, below.
- if (attr->name() == styleAttr && el->isHTMLElement() && (annotate || convert))
- continue;
- result.append(' ');
-
- if (documentIsHTML)
- append(result, attr->name().localName());
- else
- append(result, attr->name().toString());
-
- result.append('=');
-
- if (el->isURLAttribute(attr)) {
- // We don't want to complete file:/// URLs because it may contain sensitive information
- // about the user's system.
- if (absoluteURLs == AbsoluteURLs && !node->document()->url().isLocalFile())
- appendQuotedURLAttributeValue(result, node->document()->completeURL(attr->value()).string());
- else
- appendQuotedURLAttributeValue(result, attr->value().string());
- } else {
- result.append('\"');
- appendAttributeValue(result, attr->value(), documentIsHTML);
- result.append('\"');
- }
- if (!documentIsHTML && namespaces && shouldAddNamespaceAttr(attr, *namespaces))
- appendNamespace(result, attr->prefix(), attr->namespaceURI(), *namespaces);
- }
-
- if (el->isHTMLElement() && (annotate || convert)) {
- Element* element = const_cast<Element*>(el);
- RefPtr<CSSMutableStyleDeclaration> style = static_cast<HTMLElement*>(element)->getInlineStyleDecl()->copy();
- if (annotate) {
- RefPtr<CSSMutableStyleDeclaration> styleFromMatchedRules = styleFromMatchedRulesForElement(const_cast<Element*>(el));
- // Styles from the inline style declaration, held in the variable "style", take precedence
- // over those from matched rules.
- styleFromMatchedRules->merge(style.get());
- style = styleFromMatchedRules;
-
- RefPtr<CSSComputedStyleDeclaration> computedStyleForElement = computedStyle(element);
- RefPtr<CSSMutableStyleDeclaration> fromComputedStyle = CSSMutableStyleDeclaration::create();
-
- {
- CSSMutableStyleDeclaration::const_iterator end = style->end();
- for (CSSMutableStyleDeclaration::const_iterator it = style->begin(); it != end; ++it) {
- const CSSProperty& property = *it;
- CSSValue* value = property.value();
- // The property value, if it's a percentage, may not reflect the actual computed value.
- // For example: style="height: 1%; overflow: visible;" in quirksmode
- // FIXME: There are others like this, see <rdar://problem/5195123> Slashdot copy/paste fidelity problem
- if (value->cssValueType() == CSSValue::CSS_PRIMITIVE_VALUE)
- if (static_cast<CSSPrimitiveValue*>(value)->primitiveType() == CSSPrimitiveValue::CSS_PERCENTAGE)
- if (RefPtr<CSSValue> computedPropertyValue = computedStyleForElement->getPropertyCSSValue(property.id()))
- fromComputedStyle->addParsedProperty(CSSProperty(property.id(), computedPropertyValue));
- }
- }
-
- style->merge(fromComputedStyle.get());
- }
- if (convert)
- style->setProperty(CSSPropertyDisplay, CSSValueInline, true);
- // If the node is not fully selected by the range, then we don't want to keep styles that affect its relationship to the nodes around it
- // only the ones that affect it and the nodes within it.
- if (rangeFullySelectsNode == DoesNotFullySelectNode)
- removeExteriorStyles(style.get());
- if (style->length() > 0) {
- DEFINE_STATIC_LOCAL(const String, stylePrefix, (" style=\""));
- append(result, stylePrefix);
- appendAttributeValue(result, style->cssText(), documentIsHTML);
- result.append('\"');
+ if (!documentIsHTML && namespaces && shouldAddNamespaceAttribute(attribute, *namespaces))
+ appendNamespace(out, attribute->prefix(), attribute->namespaceURI(), *namespaces);
+ }
+
+ if (element->isHTMLElement() && (shouldAnnotate() || addDisplayInline)) {
+ RefPtr<CSSMutableStyleDeclaration> style = static_cast<HTMLElement*>(element)->getInlineStyleDecl()->copy();
+ if (shouldAnnotate()) {
+ RefPtr<CSSMutableStyleDeclaration> styleFromMatchedRules = styleFromMatchedRulesForElement(const_cast<Element*>(element));
+ // Styles from the inline style declaration, held in the variable "style", take precedence
+ // over those from matched rules.
+ styleFromMatchedRules->merge(style.get());
+ style = styleFromMatchedRules;
+
+ RefPtr<CSSComputedStyleDeclaration> computedStyleForElement = computedStyle(element);
+ RefPtr<CSSMutableStyleDeclaration> fromComputedStyle = CSSMutableStyleDeclaration::create();
+
+ {
+ CSSMutableStyleDeclaration::const_iterator end = style->end();
+ for (CSSMutableStyleDeclaration::const_iterator it = style->begin(); it != end; ++it) {
+ const CSSProperty& property = *it;
+ CSSValue* value = property.value();
+ // The property value, if it's a percentage, may not reflect the actual computed value.
+ // For example: style="height: 1%; overflow: visible;" in quirksmode
+ // FIXME: There are others like this, see <rdar://problem/5195123> Slashdot copy/paste fidelity problem
+ if (value->cssValueType() == CSSValue::CSS_PRIMITIVE_VALUE)
+ if (static_cast<CSSPrimitiveValue*>(value)->primitiveType() == CSSPrimitiveValue::CSS_PERCENTAGE)
+ if (RefPtr<CSSValue> computedPropertyValue = computedStyleForElement->getPropertyCSSValue(property.id()))
+ fromComputedStyle->addParsedProperty(CSSProperty(property.id(), computedPropertyValue));
}
}
-
- if (shouldSelfClose(el)) {
- if (el->isHTMLElement())
- result.append(' '); // XHTML 1.0 <-> HTML compatibility.
- result.append('/');
- }
- result.append('>');
- break;
+ style->merge(fromComputedStyle.get());
}
- case Node::CDATA_SECTION_NODE: {
- // FIXME: CDATA content is not escaped, but XMLSerializer (and possibly other callers) should raise an exception if it includes "]]>".
- const CDATASection* n = static_cast<const CDATASection*>(node);
- append(result, "<![CDATA[");
- append(result, n->data());
- append(result, "]]>");
- break;
+ if (addDisplayInline)
+ style->setProperty(CSSPropertyDisplay, CSSValueInline, true);
+ // If the node is not fully selected by the range, then we don't want to keep styles that affect its relationship to the nodes around it
+ // only the ones that affect it and the nodes within it.
+ if (rangeFullySelectsNode == DoesNotFullySelectNode)
+ removeExteriorStyles(style.get());
+ if (style->length() > 0) {
+ DEFINE_STATIC_LOCAL(const String, stylePrefix, (" style=\""));
+ append(out, stylePrefix);
+ appendAttributeValue(out, style->cssText(), documentIsHTML);
+ out.append('\"');
}
- case Node::ATTRIBUTE_NODE:
- case Node::ENTITY_NODE:
- case Node::ENTITY_REFERENCE_NODE:
- case Node::NOTATION_NODE:
- case Node::XPATH_NAMESPACE_NODE:
- ASSERT_NOT_REACHED();
- break;
}
+
+ if (shouldSelfClose(element)) {
+ if (element->isHTMLElement())
+ out.append(' '); // XHTML 1.0 <-> HTML compatibility.
+ out.append('/');
+ }
+ out.append('>');
}
-static inline bool doesHTMLForbidEndTag(const Node *node)
+void MarkupAccumulator::appendCDATASection(Vector<UChar>& out, const String& section)
{
- if (node->isHTMLElement()) {
- const HTMLElement* htmlElt = static_cast<const HTMLElement*>(node);
- return (htmlElt->endTagRequirement() == TagStatusForbidden);
+ // FIXME: CDATA content is not escaped, but XMLSerializer (and possibly other callers) should raise an exception if it includes "]]>".
+ append(out, "<![CDATA[");
+ append(out, section);
+ append(out, "]]>");
+}
+
+void MarkupAccumulator::appendStartMarkup(Vector<UChar>& result, const Node* node, bool convertBlocksToInlines, Namespaces* namespaces, RangeFullySelectsNode rangeFullySelectsNode)
+{
+ if (namespaces)
+ namespaces->checkConsistency();
+
+ switch (node->nodeType()) {
+ case Node::TEXT_NODE:
+ appendText(result, static_cast<Text*>(const_cast<Node*>(node)));
+ break;
+ case Node::COMMENT_NODE:
+ appendComment(result, static_cast<const Comment*>(node)->data());
+ break;
+ case Node::DOCUMENT_NODE:
+ case Node::DOCUMENT_FRAGMENT_NODE:
+ break;
+ case Node::DOCUMENT_TYPE_NODE:
+ appendDocumentType(result, static_cast<const DocumentType*>(node));
+ break;
+ case Node::PROCESSING_INSTRUCTION_NODE:
+ appendProcessingInstruction(result, static_cast<const ProcessingInstruction*>(node)->target(), static_cast<const ProcessingInstruction*>(node)->data());
+ break;
+ case Node::ELEMENT_NODE:
+ appendElement(result, static_cast<Element*>(const_cast<Node*>(node)), convertBlocksToInlines && isBlock(const_cast<Node*>(node)), namespaces, rangeFullySelectsNode);
+ break;
+ case Node::CDATA_SECTION_NODE:
+ appendCDATASection(result, static_cast<const CDATASection*>(node)->data());
+ break;
+ case Node::ATTRIBUTE_NODE:
+ case Node::ENTITY_NODE:
+ case Node::ENTITY_REFERENCE_NODE:
+ case Node::NOTATION_NODE:
+ case Node::XPATH_NAMESPACE_NODE:
+ ASSERT_NOT_REACHED();
+ break;
}
- return false;
+}
+
+static inline bool elementCannotHaveEndTag(const Node *node)
+{
+ if (!node->isHTMLElement())
+ return false;
+
+ // FIXME: ieForbidsInsertHTML may not be the right function to call here
+ // ieForbidsInsertHTML is used to disallow setting innerHTML/outerHTML
+ // or createContextualFragment. It does not necessarily align with
+ // which elements should be serialized w/o end tags.
+ return static_cast<const HTMLElement*>(node)->ieForbidsInsertHTML();
}
// Rules of self-closure
@@ -569,20 +712,20 @@ static inline bool doesHTMLForbidEndTag(const Node *node)
// 2. Elements w/ children never self-close because they use a separate end tag.
// 3. HTML elements which do not have a "forbidden" end tag will close with a separate end tag.
// 4. Other elements self-close.
-static inline bool shouldSelfClose(const Node *node)
+bool MarkupAccumulator::shouldSelfClose(const Node* node)
{
if (node->document()->isHTMLDocument())
return false;
if (node->hasChildNodes())
return false;
- if (node->isHTMLElement() && !doesHTMLForbidEndTag(node))
+ if (node->isHTMLElement() && !elementCannotHaveEndTag(node))
return false;
return true;
}
-static void appendEndMarkup(Vector<UChar>& result, const Node* node)
+void MarkupAccumulator::appendEndMarkup(Vector<UChar>& result, const Node* node)
{
- if (!node->isElementNode() || shouldSelfClose(node) || (!node->hasChildNodes() && doesHTMLForbidEndTag(node)))
+ if (!node->isElementNode() || shouldSelfClose(node) || (!node->hasChildNodes() && elementCannotHaveEndTag(node)))
return;
result.append('<');
@@ -601,12 +744,12 @@ static void completeURLs(Node* node, const String& baseURL)
for (Node* n = node; n != end; n = n->traverseNextNode()) {
if (n->isElementNode()) {
Element* e = static_cast<Element*>(n);
- NamedNodeMap* attrs = e->attributes();
- unsigned length = attrs->length();
+ NamedNodeMap* attributes = e->attributes();
+ unsigned length = attributes->length();
for (unsigned i = 0; i < length; i++) {
- Attribute* attr = attrs->attributeItem(i);
- if (e->isURLAttribute(attr))
- changes.append(AttributeChange(e, attr->name(), KURL(parsedBaseURL, attr->value()).string()));
+ Attribute* attribute = attributes->attributeItem(i);
+ if (e->isURLAttribute(attribute))
+ changes.append(AttributeChange(e, attribute->name(), KURL(parsedBaseURL, attribute->value()).string()));
}
}
}
@@ -653,8 +796,8 @@ static bool propertyMissingOrEqualToNone(CSSStyleDeclaration* style, int propert
static bool isElementPresentational(const Node* node)
{
- if (node->hasTagName(uTag) || node->hasTagName(sTag) || node->hasTagName(strikeTag) ||
- node->hasTagName(iTag) || node->hasTagName(emTag) || node->hasTagName(bTag) || node->hasTagName(strongTag))
+ if (node->hasTagName(uTag) || node->hasTagName(sTag) || node->hasTagName(strikeTag)
+ || node->hasTagName(iTag) || node->hasTagName(emTag) || node->hasTagName(bTag) || node->hasTagName(strongTag))
return true;
RefPtr<CSSMutableStyleDeclaration> style = styleFromMatchedRulesAndInlineDecl(node);
if (!style)
@@ -667,17 +810,17 @@ static bool isSpecialAncestorBlock(Node* node)
if (!node || !isBlock(node))
return false;
- return node->hasTagName(listingTag) ||
- node->hasTagName(olTag) ||
- node->hasTagName(preTag) ||
- node->hasTagName(tableTag) ||
- node->hasTagName(ulTag) ||
- node->hasTagName(xmpTag) ||
- node->hasTagName(h1Tag) ||
- node->hasTagName(h2Tag) ||
- node->hasTagName(h3Tag) ||
- node->hasTagName(h4Tag) ||
- node->hasTagName(h5Tag);
+ return node->hasTagName(listingTag)
+ || node->hasTagName(olTag)
+ || node->hasTagName(preTag)
+ || node->hasTagName(tableTag)
+ || node->hasTagName(ulTag)
+ || node->hasTagName(xmpTag)
+ || node->hasTagName(h1Tag)
+ || node->hasTagName(h2Tag)
+ || node->hasTagName(h3Tag)
+ || node->hasTagName(h4Tag)
+ || node->hasTagName(h5Tag);
}
static bool shouldIncludeWrapperForFullySelectedRoot(Node* fullySelectedRoot, CSSMutableStyleDeclaration* style)
@@ -685,100 +828,10 @@ static bool shouldIncludeWrapperForFullySelectedRoot(Node* fullySelectedRoot, CS
if (fullySelectedRoot->isElementNode() && static_cast<Element*>(fullySelectedRoot)->hasAttribute(backgroundAttr))
return true;
- return style->getPropertyCSSValue(CSSPropertyBackgroundImage) ||
- style->getPropertyCSSValue(CSSPropertyBackgroundColor);
+ return style->getPropertyCSSValue(CSSPropertyBackgroundImage) || style->getPropertyCSSValue(CSSPropertyBackgroundColor);
}
-class MarkupAccumulatorWrapper {
-public:
- MarkupAccumulatorWrapper(Vector<Node*>* nodes)
- : m_nodes(nodes)
- {
- }
-
- void insertString(const String& s)
- {
- postMarkups.append(s);
- }
-
- void insertOpenTag(const Node* node, const Range* range, EAnnotateForInterchange annotate, EAbsoluteURLs absoluteURLs, bool convertBlocksToInlines = false, HashMap<AtomicStringImpl*, AtomicStringImpl*>* namespaces = 0, RangeFullySelectsNode rangeFullySelectsNode = DoesFullySelectNode)
- {
- Vector<UChar> result;
- appendStartMarkup(result, node, range, annotate, absoluteURLs, convertBlocksToInlines, namespaces, rangeFullySelectsNode);
- postMarkups.append(String::adopt(result));
- if (m_nodes)
- m_nodes->append(const_cast<Node*>(node));
- }
-
- void insertEndTag(const Node* node)
- {
- Vector<UChar> result;
- appendEndMarkup(result, node);
- postMarkups.append(String::adopt(result));
- }
-
- void wrapWithNode(const Node* node, const Range* range, EAnnotateForInterchange annotate, EAbsoluteURLs absoluteURLs, bool convertBlocksToInlines = false, HashMap<AtomicStringImpl*, AtomicStringImpl*>* namespaces = 0, RangeFullySelectsNode rangeFullySelectsNode = DoesFullySelectNode)
- {
- Vector<UChar> result;
- appendStartMarkup(result, node, range, annotate, absoluteURLs, convertBlocksToInlines, namespaces, rangeFullySelectsNode);
- preMarkups.append(String::adopt(result));
- insertEndTag(node);
- if (m_nodes)
- m_nodes->append(const_cast<Node*>(node));
- }
-
- void wrapWithStyleNode(CSSStyleDeclaration* style, Document* document, bool isBlock = false)
- {
- // All text-decoration-related elements should have been treated as special ancestors
- // If we ever hit this ASSERT, we should export StyleChange in ApplyStyleCommand and use it here
- ASSERT(propertyMissingOrEqualToNone(style, CSSPropertyTextDecoration) && propertyMissingOrEqualToNone(style, CSSPropertyWebkitTextDecorationsInEffect));
- DEFINE_STATIC_LOCAL(const String, divStyle, ("<div style=\""));
- DEFINE_STATIC_LOCAL(const String, divClose, ("</div>"));
- DEFINE_STATIC_LOCAL(const String, styleSpanOpen, ("<span class=\"" AppleStyleSpanClass "\" style=\""));
- DEFINE_STATIC_LOCAL(const String, styleSpanClose, ("</span>"));
- Vector<UChar> openTag;
- WTF::append(openTag, isBlock ? divStyle : styleSpanOpen);
- appendAttributeValue(openTag, style->cssText(), document->isHTMLDocument());
- openTag.append('\"');
- openTag.append('>');
- preMarkups.append(String::adopt(openTag));
- postMarkups.append(isBlock ? divClose : styleSpanClose);
- }
-
- // FIXME: This is a very inefficient way of accumulating the markup.
- // We're converting results of appendStartMarkup and appendEndMarkup from Vector<UChar> to String
- // and then back to Vector<UChar> and again to String here.
- String takeResults()
- {
- size_t length = 0;
-
- size_t preCount = preMarkups.size();
- for (size_t i = 0; i < preCount; ++i)
- length += preMarkups[i].length();
-
- size_t postCount = postMarkups.size();
- for (size_t i = 0; i < postCount; ++i)
- length += postMarkups[i].length();
-
- Vector<UChar> result;
- result.reserveInitialCapacity(length);
-
- for (size_t i = preCount; i > 0; --i)
- WTF::append(result, preMarkups[i - 1]);
-
- for (size_t i = 0; i < postCount; ++i)
- WTF::append(result, postMarkups[i]);
-
- return String::adopt(result);
- }
-
-private:
- Vector<Node*>* m_nodes;
- Vector<String> preMarkups;
- Vector<String> postMarkups;
-};
-
-static Node* serializeNodes(MarkupAccumulatorWrapper& accumulator, Node* startNode, Node* pastEnd, const Range* range, EAnnotateForInterchange annotate, EAbsoluteURLs absoluteURLs)
+static Node* serializeNodes(MarkupAccumulator& accumulator, Node* startNode, Node* pastEnd)
{
Vector<Node*> ancestorsToClose;
Node* next;
@@ -806,11 +859,11 @@ static Node* serializeNodes(MarkupAccumulatorWrapper& accumulator, Node* startNo
next = pastEnd;
} else {
// Add the node to the markup if we're not skipping the descendants
- accumulator.insertOpenTag(n, range, annotate, absoluteURLs);
+ accumulator.appendStartTag(n);
// If node has no children, close the tag now.
if (!n->childNodeCount()) {
- accumulator.insertEndTag(n);
+ accumulator.appendEndTag(n);
lastClosed = n;
} else {
openedTag = true;
@@ -827,7 +880,7 @@ static Node* serializeNodes(MarkupAccumulatorWrapper& accumulator, Node* startNo
if (next != pastEnd && next->isDescendantOf(ancestor))
break;
// Not at the end of the range, close ancestors up to sibling of next node.
- accumulator.insertEndTag(ancestor);
+ accumulator.appendEndTag(ancestor);
lastClosed = ancestor;
ancestorsToClose.removeLast();
}
@@ -842,7 +895,7 @@ static Node* serializeNodes(MarkupAccumulatorWrapper& accumulator, Node* startNo
continue;
// or b) ancestors that we never encountered during a pre-order traversal starting at startNode:
ASSERT(startNode->isDescendantOf(parent));
- accumulator.wrapWithNode(parent, range, annotate, absoluteURLs);
+ accumulator.wrapWithNode(parent);
lastClosed = parent;
}
}
@@ -854,7 +907,7 @@ static Node* serializeNodes(MarkupAccumulatorWrapper& accumulator, Node* startNo
// FIXME: Shouldn't we omit style info when annotate == DoNotAnnotateForInterchange?
// FIXME: At least, annotation and style info should probably not be included in range.markupString()
-String createMarkup(const Range* range, Vector<Node*>* nodes, EAnnotateForInterchange annotate, bool convertBlocksToInlines, EAbsoluteURLs absoluteURLs)
+String createMarkup(const Range* range, Vector<Node*>* nodes, EAnnotateForInterchange shouldAnnotate, bool convertBlocksToInlines, EAbsoluteURLs shouldResolveURLs)
{
DEFINE_STATIC_LOCAL(const String, interchangeNewlineString, ("<br class=\"" AppleInterchangeNewline "\">"));
@@ -878,30 +931,30 @@ String createMarkup(const Range* range, Vector<Node*>* nodes, EAnnotateForInterc
ExceptionCode ec = 0;
bool collapsed = updatedRange->collapsed(ec);
- ASSERT(ec == 0);
+ ASSERT(!ec);
if (collapsed)
return "";
Node* commonAncestor = updatedRange->commonAncestorContainer(ec);
- ASSERT(ec == 0);
+ ASSERT(!ec);
if (!commonAncestor)
return "";
document->updateLayoutIgnorePendingStylesheets();
- MarkupAccumulatorWrapper accumulator(nodes);
+ MarkupAccumulator accumulator(nodes, shouldResolveURLs, shouldAnnotate, updatedRange.get());
Node* pastEnd = updatedRange->pastLastNode();
Node* startNode = updatedRange->firstNode();
VisiblePosition visibleStart(updatedRange->startPosition(), VP_DEFAULT_AFFINITY);
VisiblePosition visibleEnd(updatedRange->endPosition(), VP_DEFAULT_AFFINITY);
- if (annotate && needInterchangeNewlineAfter(visibleStart)) {
+ if (shouldAnnotate == AnnotateForInterchange && needInterchangeNewlineAfter(visibleStart)) {
if (visibleStart == visibleEnd.previous()) {
if (deleteButton)
deleteButton->enable();
return interchangeNewlineString;
}
- accumulator.insertString(interchangeNewlineString);
+ accumulator.appendString(interchangeNewlineString);
startNode = visibleStart.next().deepEquivalent().node();
if (pastEnd && Range::compareBoundaryPoints(startNode, 0, pastEnd, 0) >= 0) {
@@ -911,13 +964,13 @@ String createMarkup(const Range* range, Vector<Node*>* nodes, EAnnotateForInterc
}
}
- Node* lastClosed = serializeNodes(accumulator, startNode, pastEnd, range, annotate, absoluteURLs);
+ Node* lastClosed = serializeNodes(accumulator, startNode, pastEnd);
// Include ancestors that aren't completely inside the range but are required to retain
// the structure and appearance of the copied markup.
Node* specialCommonAncestor = 0;
Node* commonAncestorBlock = commonAncestor ? enclosingBlock(commonAncestor) : 0;
- if (annotate && commonAncestorBlock) {
+ if (shouldAnnotate == AnnotateForInterchange && commonAncestorBlock) {
if (commonAncestorBlock->hasTagName(tbodyTag) || commonAncestorBlock->hasTagName(trTag)) {
Node* table = commonAncestorBlock->parentNode();
while (table && !table->hasTagName(tableTag))
@@ -929,7 +982,7 @@ String createMarkup(const Range* range, Vector<Node*>* nodes, EAnnotateForInterc
}
// Retain the Mail quote level by including all ancestor mail block quotes.
- if (lastClosed && annotate) {
+ if (lastClosed && shouldAnnotate == AnnotateForInterchange) {
for (Node *ancestor = lastClosed->parentNode(); ancestor; ancestor = ancestor->parentNode())
if (isMailBlockquote(ancestor))
specialCommonAncestor = ancestor;
@@ -958,7 +1011,7 @@ String createMarkup(const Range* range, Vector<Node*>* nodes, EAnnotateForInterc
// FIXME: Do this for all fully selected blocks, not just the body.
Node* fullySelectedRoot = body && areRangesEqual(VisibleSelection::selectionFromContentsOfNode(body).toNormalizedRange().get(), updatedRange.get()) ? body : 0;
RefPtr<CSSMutableStyleDeclaration> fullySelectedRootStyle = fullySelectedRoot ? styleFromMatchedRulesAndInlineDecl(fullySelectedRoot) : 0;
- if (annotate && fullySelectedRoot) {
+ if (shouldAnnotate == AnnotateForInterchange && fullySelectedRoot) {
if (shouldIncludeWrapperForFullySelectedRoot(fullySelectedRoot, fullySelectedRootStyle.get()))
specialCommonAncestor = fullySelectedRoot;
}
@@ -986,7 +1039,7 @@ String createMarkup(const Range* range, Vector<Node*>* nodes, EAnnotateForInterc
} else {
// Since this node and all the other ancestors are not in the selection we want to set RangeFullySelectsNode to DoesNotFullySelectNode
// so that styles that affect the exterior of the node are not included.
- accumulator.wrapWithNode(ancestor, updatedRange.get(), annotate, absoluteURLs, convertBlocksToInlines, 0, DoesNotFullySelectNode);
+ accumulator.wrapWithNode(ancestor, convertBlocksToInlines, MarkupAccumulator::DoesNotFullySelectNode);
}
if (nodes)
nodes->append(ancestor);
@@ -1032,8 +1085,8 @@ String createMarkup(const Range* range, Vector<Node*>* nodes, EAnnotateForInterc
}
// FIXME: The interchange newline should be placed in the block that it's in, not after all of the content, unconditionally.
- if (annotate && needInterchangeNewlineAfter(visibleEnd.previous()))
- accumulator.insertString(interchangeNewlineString);
+ if (shouldAnnotate == AnnotateForInterchange && needInterchangeNewlineAfter(visibleEnd.previous()))
+ accumulator.appendString(interchangeNewlineString);
if (deleteButton)
deleteButton->enable();
@@ -1043,8 +1096,12 @@ String createMarkup(const Range* range, Vector<Node*>* nodes, EAnnotateForInterc
PassRefPtr<DocumentFragment> createFragmentFromMarkup(Document* document, const String& markup, const String& baseURL, FragmentScriptingPermission scriptingPermission)
{
+ // We use a fake body element here to trick the HTML parser to using the
+ // InBody insertion mode. Really, all this code is wrong and need to be
+ // changed not to use deprecatedCreateContextualFragment.
+ RefPtr<HTMLBodyElement> fakeBody = HTMLBodyElement::create(document);
// FIXME: This should not use deprecatedCreateContextualFragment
- RefPtr<DocumentFragment> fragment = document->documentElement()->deprecatedCreateContextualFragment(markup, scriptingPermission);
+ RefPtr<DocumentFragment> fragment = fakeBody->deprecatedCreateContextualFragment(markup, scriptingPermission);
if (fragment && !baseURL.isEmpty() && baseURL != blankURL() && baseURL != document->baseURL())
completeURLs(fragment.get(), baseURL);
@@ -1052,28 +1109,28 @@ PassRefPtr<DocumentFragment> createFragmentFromMarkup(Document* document, const
return fragment.release();
}
-static void serializeNodesWithNamespaces(MarkupAccumulatorWrapper& accumulator, const Node* node, Node* nodeToSkip, EChildrenOnly childrenOnly, EAbsoluteURLs absoluteURLs, const HashMap<AtomicStringImpl*, AtomicStringImpl*>* namespaces)
+static void serializeNodesWithNamespaces(MarkupAccumulator& accumulator, Node* node, Node* nodeToSkip, EChildrenOnly childrenOnly, const Namespaces* namespaces)
{
if (node == nodeToSkip)
return;
- HashMap<AtomicStringImpl*, AtomicStringImpl*> namespaceHash;
+ Namespaces namespaceHash;
if (namespaces)
namespaceHash = *namespaces;
if (!childrenOnly)
- accumulator.insertOpenTag(node, 0, DoNotAnnotateForInterchange, absoluteURLs, false, &namespaceHash);
+ accumulator.appendStartTag(node, &namespaceHash);
- if (!(node->document()->isHTMLDocument() && doesHTMLForbidEndTag(node))) {
+ if (!(node->document()->isHTMLDocument() && elementCannotHaveEndTag(node))) {
for (Node* current = node->firstChild(); current; current = current->nextSibling())
- serializeNodesWithNamespaces(accumulator, current, nodeToSkip, IncludeNode, absoluteURLs, &namespaceHash);
+ serializeNodesWithNamespaces(accumulator, current, nodeToSkip, IncludeNode, &namespaceHash);
}
if (!childrenOnly)
- accumulator.insertEndTag(node);
+ accumulator.appendEndTag(node);
}
-String createMarkup(const Node* node, EChildrenOnly childrenOnly, Vector<Node*>* nodes, EAbsoluteURLs absoluteURLs)
+String createMarkup(const Node* node, EChildrenOnly childrenOnly, Vector<Node*>* nodes, EAbsoluteURLs shouldResolveURLs)
{
if (!node)
return "";
@@ -1085,8 +1142,8 @@ String createMarkup(const Node* node, EChildrenOnly childrenOnly, Vector<Node*>*
return "";
}
- MarkupAccumulatorWrapper accumulator(nodes);
- serializeNodesWithNamespaces(accumulator, node, deleteButtonContainerElement, childrenOnly, absoluteURLs, 0);
+ MarkupAccumulator accumulator(nodes, shouldResolveURLs, DoNotAnnotateForInterchange);
+ serializeNodesWithNamespaces(accumulator, const_cast<Node*>(node), deleteButtonContainerElement, childrenOnly, 0);
return accumulator.takeResults();
}
@@ -1097,7 +1154,7 @@ static void fillContainerFromString(ContainerNode* paragraph, const String& stri
ExceptionCode ec = 0;
if (string.isEmpty()) {
paragraph->appendChild(createBlockPlaceholderElement(document), ec);
- ASSERT(ec == 0);
+ ASSERT(!ec);
return;
}
@@ -1115,12 +1172,12 @@ static void fillContainerFromString(ContainerNode* paragraph, const String& stri
if (!s.isEmpty()) {
if (!tabText.isEmpty()) {
paragraph->appendChild(createTabSpanElement(document, tabText), ec);
- ASSERT(ec == 0);
+ ASSERT(!ec);
tabText = "";
}
RefPtr<Node> textNode = document->createTextNode(stringWithRebalancedWhitespace(s, first, i + 1 == numEntries));
paragraph->appendChild(textNode.release(), ec);
- ASSERT(ec == 0);
+ ASSERT(!ec);
}
// there is a tab after every entry, except the last entry
@@ -1129,7 +1186,7 @@ static void fillContainerFromString(ContainerNode* paragraph, const String& stri
tabText.append('\t');
else if (!tabText.isEmpty()) {
paragraph->appendChild(createTabSpanElement(document, tabText), ec);
- ASSERT(ec == 0);
+ ASSERT(!ec);
}
first = false;
@@ -1173,12 +1230,12 @@ PassRefPtr<DocumentFragment> createFragmentFromText(Range* context, const String
RenderObject* renderer = styleNode->renderer();
if (renderer && renderer->style()->preserveNewline()) {
fragment->appendChild(document->createTextNode(string), ec);
- ASSERT(ec == 0);
+ ASSERT(!ec);
if (string.endsWith("\n")) {
RefPtr<Element> element = createBreakElement(document);
element->setAttribute(classAttr, AppleInterchangeNewline);
fragment->appendChild(element.release(), ec);
- ASSERT(ec == 0);
+ ASSERT(!ec);
}
return fragment.release();
}
@@ -1217,7 +1274,7 @@ PassRefPtr<DocumentFragment> createFragmentFromText(Range* context, const String
fillContainerFromString(element.get(), s);
}
fragment->appendChild(element.release(), ec);
- ASSERT(ec == 0);
+ ASSERT(!ec);
}
return fragment.release();
}
@@ -1238,9 +1295,9 @@ PassRefPtr<DocumentFragment> createFragmentFromNodes(Document *document, const V
for (size_t i = 0; i < size; ++i) {
RefPtr<Element> element = createDefaultParagraphElement(document);
element->appendChild(nodes[i], ec);
- ASSERT(ec == 0);
+ ASSERT(!ec);
fragment->appendChild(element.release(), ec);
- ASSERT(ec == 0);
+ ASSERT(!ec);
}
if (document->frame())
diff --git a/WebCore/features.pri b/WebCore/features.pri
index 2a02465..1b9f704 100644
--- a/WebCore/features.pri
+++ b/WebCore/features.pri
@@ -4,6 +4,10 @@ CONFIG(minimal) {
DEFINES += ENABLE_NETSCAPE_PLUGIN_API=0
}
+CONFIG(production) {
+ DEFINES += ENABLE_XSLT=0
+}
+
## load mobilityconfig if mobility is available
load(mobilityconfig, true)
diff --git a/WebCore/history/HistoryItem.cpp b/WebCore/history/HistoryItem.cpp
index 3ee423b..42adcfb 100644
--- a/WebCore/history/HistoryItem.cpp
+++ b/WebCore/history/HistoryItem.cpp
@@ -150,7 +150,7 @@ inline HistoryItem::HistoryItem(const HistoryItem& item)
m_children.uncheckedAppend(item.m_children[i]->copy());
if (item.m_redirectURLs)
- m_redirectURLs.set(new Vector<String>(*item.m_redirectURLs));
+ m_redirectURLs = adoptPtr(new Vector<String>(*item.m_redirectURLs));
}
PassRefPtr<HistoryItem> HistoryItem::copy() const
@@ -480,6 +480,22 @@ void HistoryItem::clearChildren()
m_children.clear();
}
+bool HistoryItem::hasSameDocuments(HistoryItem* otherItem)
+{
+ if (documentSequenceNumber() != otherItem->documentSequenceNumber())
+ return false;
+
+ if (children().size() != otherItem->children().size())
+ return false;
+
+ for (size_t i = 0; i < children().size(); i++) {
+ if (!children()[i]->hasSameDocuments(otherItem->children()[i].get()))
+ return false;
+ }
+
+ return true;
+}
+
String HistoryItem::formContentType() const
{
return m_formContentType;
@@ -537,7 +553,7 @@ void HistoryItem::mergeAutoCompleteHints(HistoryItem* otherItem)
void HistoryItem::addRedirectURL(const String& url)
{
if (!m_redirectURLs)
- m_redirectURLs.set(new Vector<String>);
+ m_redirectURLs = adoptPtr(new Vector<String>);
// Our API allows us to store all the URLs in the redirect chain, but for
// now we only have a use for the final URL.
diff --git a/WebCore/history/HistoryItem.h b/WebCore/history/HistoryItem.h
index ef73c5e..dfdbc43 100644
--- a/WebCore/history/HistoryItem.h
+++ b/WebCore/history/HistoryItem.h
@@ -159,6 +159,8 @@ public:
const HistoryItemVector& children() const;
bool hasChildren() const;
void clearChildren();
+
+ bool hasSameDocuments(HistoryItem* otherItem);
// This should not be called directly for HistoryItems that are already included
// in GlobalHistory. The WebKit api for this is to use -[WebHistory setLastVisitedTimeInterval:forItem:] instead.
diff --git a/WebCore/html/FileReader.cpp b/WebCore/html/FileReader.cpp
index e99fdc4..d600d40 100644
--- a/WebCore/html/FileReader.cpp
+++ b/WebCore/html/FileReader.cpp
@@ -189,10 +189,10 @@ void FileReader::didGetSize(long long size)
m_streamProxy->openForRead(m_fileBlob->path(), start, m_totalBytes);
}
-void FileReader::didOpen(ExceptionCode ec)
+void FileReader::didOpen(bool success)
{
- if (ec) {
- didFail(ec);
+ if (!success) {
+ didFail(NOT_READABLE_ERR);
return;
}
diff --git a/WebCore/html/FileReader.h b/WebCore/html/FileReader.h
index 2237af5..ee15968 100644
--- a/WebCore/html/FileReader.h
+++ b/WebCore/html/FileReader.h
@@ -89,7 +89,7 @@ public:
// FileStreamClient
virtual void didStart();
virtual void didGetSize(long long);
- virtual void didOpen(ExceptionCode);
+ virtual void didOpen(bool);
virtual void didRead(int);
using RefCounted<FileReader>::ref;
diff --git a/WebCore/html/FileStreamProxy.cpp b/WebCore/html/FileStreamProxy.cpp
index f50b7e8..30813d3 100644
--- a/WebCore/html/FileStreamProxy.cpp
+++ b/WebCore/html/FileStreamProxy.cpp
@@ -37,7 +37,6 @@
#include "Blob.h"
#include "CrossThreadTask.h"
#include "FileStream.h"
-#include "FileStreamClient.h"
#include "FileThread.h"
#include "FileThreadTask.h"
#include "PlatformString.h"
@@ -46,8 +45,8 @@
namespace WebCore {
inline FileStreamProxy::FileStreamProxy(ScriptExecutionContext* context, FileStreamClient* client)
- : m_context(context)
- , m_client(client)
+ : AsyncFileStream(client)
+ , m_context(context)
, m_stream(FileStream::create())
{
}
@@ -91,7 +90,7 @@ void FileStreamProxy::startOnFileThread()
void FileStreamProxy::stop()
{
// Clear the client so that we won't be calling callbacks on the client.
- m_client = 0;
+ setClient(0);
fileThread()->unscheduleTasks(m_stream.get());
fileThread()->postTask(createFileThreadTask(this, &FileStreamProxy::stopOnFileThread));
@@ -126,10 +125,10 @@ void FileStreamProxy::getSizeOnFileThread(const String& path, double expectedMod
m_context->postTask(createCallbackTask(&didGetSize, this, size));
}
-static void didOpen(ScriptExecutionContext*, FileStreamProxy* proxy, ExceptionCode ec)
+static void didOpen(ScriptExecutionContext*, FileStreamProxy* proxy, bool success)
{
if (proxy->client())
- proxy->client()->didOpen(ec);
+ proxy->client()->didOpen(success);
}
void FileStreamProxy::openForRead(const String& path, long long offset, long long length)
@@ -139,8 +138,8 @@ void FileStreamProxy::openForRead(const String& path, long long offset, long lon
void FileStreamProxy::openForReadOnFileThread(const String& path, long long offset, long long length)
{
- ExceptionCode ec = m_stream->openForRead(path, offset, length);
- m_context->postTask(createCallbackTask(&didOpen, this, ec));
+ bool success = m_stream->openForRead(path, offset, length);
+ m_context->postTask(createCallbackTask(&didOpen, this, success));
}
void FileStreamProxy::openForWrite(const String& path)
@@ -150,8 +149,8 @@ void FileStreamProxy::openForWrite(const String& path)
void FileStreamProxy::openForWriteOnFileThread(const String& path)
{
- ExceptionCode ec = m_stream->openForWrite(path);
- m_context->postTask(createCallbackTask(&didOpen, this, ec));
+ bool success = m_stream->openForWrite(path);
+ m_context->postTask(createCallbackTask(&didOpen, this, success));
}
void FileStreamProxy::close()
@@ -187,21 +186,21 @@ static void didWrite(ScriptExecutionContext*, FileStreamProxy* proxy, int bytesW
proxy->client()->didWrite(bytesWritten);
}
-void FileStreamProxy::write(Blob* blob, long long position, int length)
+void FileStreamProxy::write(const KURL& blobURL, long long position, int length)
{
- fileThread()->postTask(createFileThreadTask(this, &FileStreamProxy::writeOnFileThread, blob, position, length));
+ fileThread()->postTask(createFileThreadTask(this, &FileStreamProxy::writeOnFileThread, blobURL, position, length));
}
-void FileStreamProxy::writeOnFileThread(Blob* blob, long long position, int length)
+void FileStreamProxy::writeOnFileThread(const KURL& blobURL, long long position, int length)
{
- int bytesWritten = m_stream->write(blob, position, length);
+ int bytesWritten = m_stream->write(blobURL, position, length);
m_context->postTask(createCallbackTask(&didWrite, this, bytesWritten));
}
-static void didTruncate(ScriptExecutionContext*, FileStreamProxy* proxy, ExceptionCode ec)
+static void didTruncate(ScriptExecutionContext*, FileStreamProxy* proxy, bool success)
{
if (proxy->client())
- proxy->client()->didTruncate(ec);
+ proxy->client()->didTruncate(success);
}
void FileStreamProxy::truncate(long long position)
@@ -211,8 +210,8 @@ void FileStreamProxy::truncate(long long position)
void FileStreamProxy::truncateOnFileThread(long long position)
{
- ExceptionCode ec = m_stream->truncate(position);
- m_context->postTask(createCallbackTask(&didTruncate, this, ec));
+ bool success = m_stream->truncate(position);
+ m_context->postTask(createCallbackTask(&didTruncate, this, success));
}
} // namespace WebCore
diff --git a/WebCore/html/FileStreamProxy.h b/WebCore/html/FileStreamProxy.h
index 1d03a58..35a3af8 100644
--- a/WebCore/html/FileStreamProxy.h
+++ b/WebCore/html/FileStreamProxy.h
@@ -34,6 +34,7 @@
#if ENABLE(BLOB) || ENABLE(FILE_WRITER)
+#include "AsyncFileStream.h"
#include <wtf/Forward.h>
#include <wtf/PassRefPtr.h>
#include <wtf/RefCounted.h>
@@ -41,31 +42,28 @@
namespace WebCore {
-class Blob;
class FileStream;
-class FileStreamClient;
class FileThread;
+class KURL;
class ScriptExecutionContext;
// A proxy module that asynchronously calls corresponding FileStream methods on the file thread. Note: you must call stop() first and then release the reference to destruct the FileStreamProxy instance.
-class FileStreamProxy : public RefCounted<FileStreamProxy> {
+class FileStreamProxy : public AsyncFileStream {
public:
static PassRefPtr<FileStreamProxy> create(ScriptExecutionContext*, FileStreamClient*);
virtual ~FileStreamProxy();
- void getSize(const String& path, double expectedModificationTime);
- void openForRead(const String& path, long long offset, long long length);
- void openForWrite(const String& path);
- void close();
- void read(char* buffer, int length);
- void write(Blob*, long long position, int length);
- void truncate(long long position);
+ virtual void getSize(const String& path, double expectedModificationTime);
+ virtual void openForRead(const String& path, long long offset, long long length);
+ virtual void openForWrite(const String& path);
+ virtual void close();
+ virtual void read(char* buffer, int length);
+ virtual void write(const KURL& blobURL, long long position, int length);
+ virtual void truncate(long long position);
// Stops the proxy and scedules it to be destructed. All the pending tasks will be aborted and the file stream will be closed.
// Note: the caller should deref the instance immediately after calling stop().
- void stop();
-
- FileStreamClient* client() const { return m_client; }
+ virtual void stop();
private:
FileStreamProxy(ScriptExecutionContext*, FileStreamClient*);
@@ -80,11 +78,10 @@ private:
void openForWriteOnFileThread(const String& path);
void closeOnFileThread();
void readOnFileThread(char* buffer, int length);
- void writeOnFileThread(Blob*, long long position, int length);
+ void writeOnFileThread(const KURL& blobURL, long long position, int length);
void truncateOnFileThread(long long position);
RefPtr<ScriptExecutionContext> m_context;
- FileStreamClient* m_client;
RefPtr<FileStream> m_stream;
};
diff --git a/WebCore/html/FileThreadTask.h b/WebCore/html/FileThreadTask.h
index 3443457..8a8ffcb 100644
--- a/WebCore/html/FileThreadTask.h
+++ b/WebCore/html/FileThreadTask.h
@@ -47,7 +47,7 @@ public:
static PassOwnPtr<FileThreadTaskImpl> create(T* instance, Method method)
{
- return new FileThreadTaskImpl(instance, method);
+ return adoptPtr(new FileThreadTaskImpl(instance, method));
}
private:
@@ -75,7 +75,7 @@ public:
static PassOwnPtr<FileThreadTaskImpl> create(T* instance, Method method, Param1 parameter1)
{
- return new FileThreadTaskImpl(instance, method, parameter1);
+ return adoptPtr(new FileThreadTaskImpl(instance, method, parameter1));
}
private:
@@ -106,7 +106,7 @@ public:
static PassOwnPtr<FileThreadTaskImpl> create(T* instance, Method method, Param1 parameter1, Param2 parameter2)
{
- return new FileThreadTaskImpl(instance, method, parameter1, parameter2);
+ return adoptPtr(new FileThreadTaskImpl(instance, method, parameter1, parameter2));
}
private:
@@ -140,7 +140,7 @@ public:
static PassOwnPtr<FileThreadTaskImpl> create(T* instance, Method method, Param1 parameter1, Param2 parameter2, Param3 parameter3)
{
- return new FileThreadTaskImpl(instance, method, parameter1, parameter2, parameter3);
+ return adoptPtr(new FileThreadTaskImpl(instance, method, parameter1, parameter2, parameter3));
}
private:
diff --git a/WebCore/platform/graphics/chromium/TransformLayerChromium.cpp b/WebCore/html/FileWriter.cpp
index 6427eeb..7d112e2 100644
--- a/WebCore/platform/graphics/chromium/TransformLayerChromium.cpp
+++ b/WebCore/html/FileWriter.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2010 Google Inc. All rights reserved.
+ * Copyright (C) 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
@@ -30,21 +30,57 @@
#include "config.h"
-#if USE(ACCELERATED_COMPOSITING)
+#if ENABLE(FILE_WRITER)
-#include "TransformLayerChromium.h"
+#include "FileWriter.h"
namespace WebCore {
-PassRefPtr<TransformLayerChromium> TransformLayerChromium::create(GraphicsLayerChromium* owner)
+FileWriter::FileWriter(ScriptExecutionContext* context)
+ : ActiveDOMObject(context, this)
{
- return adoptRef(new TransformLayerChromium(owner));
}
-TransformLayerChromium::TransformLayerChromium(GraphicsLayerChromium* owner)
- : LayerChromium(owner)
+FileWriter::~FileWriter()
{
}
+bool FileWriter::hasPendingActivity() const
+{
+ return false;
+}
+
+bool FileWriter::canSuspend() const
+{
+ // FIXME: It is not currently possible to suspend a FileWriter, so pages with FileWriter can not go into page cache.
+ return false;
+}
+
+void FileWriter::stop()
+{
+}
+
+void FileWriter::write(Blob*)
+{
}
-#endif // USE(ACCELERATED_COMPOSITING)
+
+void FileWriter::seek(long long)
+{
+}
+
+void FileWriter::truncate(long long)
+{
+}
+
+void FileWriter::abort()
+{
+}
+
+FileWriter::ReadyState FileWriter::readyState() const
+{
+ return EMPTY;
+}
+
+} // namespace WebCore
+
+#endif // ENABLE(FILE_WRITER)
diff --git a/WebCore/html/FileWriter.h b/WebCore/html/FileWriter.h
new file mode 100644
index 0000000..fd5babf
--- /dev/null
+++ b/WebCore/html/FileWriter.h
@@ -0,0 +1,112 @@
+/*
+ * Copyright (C) 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 FileWriter_h
+#define FileWriter_h
+
+#if ENABLE(FILE_WRITER)
+
+#include "ActiveDOMObject.h"
+#include "EventTarget.h"
+#include <wtf/PassRefPtr.h>
+#include <wtf/RefCounted.h>
+#include <wtf/RefPtr.h>
+
+namespace WebCore {
+
+class Blob;
+class FileError;
+class ScriptExecutionContext;
+
+// FIXME: This is an empty, do-nothing placeholder for implementation yet to come.
+class FileWriter : public RefCounted<FileWriter>, public ActiveDOMObject, public EventTarget {
+public:
+ static PassRefPtr<FileWriter> create(ScriptExecutionContext* context)
+ {
+ return adoptRef(new FileWriter(context));
+ }
+
+ enum ReadyState {
+ EMPTY = 0,
+ WRITING = 1,
+ DONE = 2
+ };
+
+ void write(Blob*);
+ void seek(long long position);
+ void truncate(long long length);
+ void abort();
+
+ ReadyState readyState() const;
+ FileError* error() const { return m_error; };
+ long long position() const { return 0; };
+ long long length() const { return 0; };
+
+ // ActiveDOMObject
+ virtual bool canSuspend() const;
+ virtual void stop();
+ virtual bool hasPendingActivity() const;
+
+ // EventTarget
+ virtual FileWriter* toFileWriter() { return this; }
+ virtual ScriptExecutionContext* scriptExecutionContext() const { return ActiveDOMObject::scriptExecutionContext(); }
+
+ using RefCounted<FileWriter>::ref;
+ using RefCounted<FileWriter>::deref;
+
+ DEFINE_ATTRIBUTE_EVENT_LISTENER(writestart);
+ DEFINE_ATTRIBUTE_EVENT_LISTENER(progress);
+ DEFINE_ATTRIBUTE_EVENT_LISTENER(write);
+ DEFINE_ATTRIBUTE_EVENT_LISTENER(abort);
+ DEFINE_ATTRIBUTE_EVENT_LISTENER(error);
+ DEFINE_ATTRIBUTE_EVENT_LISTENER(writeend);
+
+private:
+ FileWriter(ScriptExecutionContext*);
+
+ virtual ~FileWriter();
+
+ friend class RefCounted<FileWriter>;
+
+ // EventTarget
+ virtual void refEventTarget() { ref(); }
+ virtual void derefEventTarget() { deref(); }
+ virtual EventTargetData* eventTargetData() { return &m_eventTargetData; }
+ virtual EventTargetData* ensureEventTargetData() { return &m_eventTargetData; }
+
+ RefPtr<FileError*> m_error;
+ EventTargetData m_eventTargetData;
+};
+
+} // namespace WebCore
+
+#endif // ENABLE(FILE_WRITER)
+
+#endif // FileWriter_h
diff --git a/WebCore/html/FileWriter.idl b/WebCore/html/FileWriter.idl
new file mode 100644
index 0000000..bb95ee1
--- /dev/null
+++ b/WebCore/html/FileWriter.idl
@@ -0,0 +1,62 @@
+/*
+ * Copyright (C) 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.
+ */
+
+module html {
+ interface [
+ Conditional=FILE_WRITER,
+ CallWith=ScriptExecutionContext,
+ EventTarget,
+ NoStaticTables
+ ] FileWriter {
+ // ready states
+ const unsigned short INIT = 0;
+ const unsigned short WRITING = 1;
+ const unsigned short DONE = 2;
+ readonly attribute unsigned short readyState;
+
+ // async write/modify methods
+ void write(in Blob data) raises (FileException);
+ void seek(in long long position) raises (FileException);
+ void truncate(in long long size) raises (FileException);
+
+ void abort() raises (FileException);
+
+ readonly attribute FileError error;
+ readonly attribute long long position;
+ readonly attribute long long length;
+
+ attribute EventListener onwritestart;
+ attribute EventListener onprogress;
+ attribute EventListener onwrite;
+ attribute EventListener onabort;
+ attribute EventListener onerror;
+ attribute EventListener onwriteend;
+ };
+}
diff --git a/WebCore/html/HTMLAnchorElement.h b/WebCore/html/HTMLAnchorElement.h
index 4f7b4fd..a5ef167 100644
--- a/WebCore/html/HTMLAnchorElement.h
+++ b/WebCore/html/HTMLAnchorElement.h
@@ -97,8 +97,6 @@ protected:
virtual void parseMappedAttribute(Attribute*);
private:
- virtual HTMLTagStatus endTagRequirement() const { return TagStatusRequired; }
- virtual int tagPriority() const { return 1; }
virtual bool supportsFocus() const;
virtual bool isMouseFocusable() const;
virtual bool isKeyboardFocusable(KeyboardEvent*) const;
diff --git a/WebCore/html/HTMLAppletElement.h b/WebCore/html/HTMLAppletElement.h
index e0e4ec9..1499279 100644
--- a/WebCore/html/HTMLAppletElement.h
+++ b/WebCore/html/HTMLAppletElement.h
@@ -34,8 +34,6 @@ public:
private:
HTMLAppletElement(const QualifiedName&, Document*);
- virtual int tagPriority() const { return 1; }
-
virtual void parseMappedAttribute(Attribute*);
virtual bool rendererIsNeeded(RenderStyle*);
diff --git a/WebCore/html/HTMLAreaElement.cpp b/WebCore/html/HTMLAreaElement.cpp
index 2d714ba..3547cd9 100644
--- a/WebCore/html/HTMLAreaElement.cpp
+++ b/WebCore/html/HTMLAreaElement.cpp
@@ -72,7 +72,7 @@ void HTMLAreaElement::parseMappedAttribute(Attribute* attr)
bool HTMLAreaElement::mapMouseEvent(int x, int y, const IntSize& size, HitTestResult& result)
{
if (m_lastSize != size) {
- m_region.set(new Path(getRegion(size)));
+ m_region = adoptPtr(new Path(getRegion(size)));
m_lastSize = size;
}
diff --git a/WebCore/html/HTMLAreaElement.h b/WebCore/html/HTMLAreaElement.h
index ce711b2..10784c3 100644
--- a/WebCore/html/HTMLAreaElement.h
+++ b/WebCore/html/HTMLAreaElement.h
@@ -50,8 +50,6 @@ public:
private:
HTMLAreaElement(const QualifiedName&, Document*);
- virtual HTMLTagStatus endTagRequirement() const { return TagStatusForbidden; }
- virtual int tagPriority() const { return 0; }
virtual void parseMappedAttribute(Attribute*);
virtual bool supportsFocus() const;
virtual String target() const;
diff --git a/WebCore/html/HTMLAudioElement.h b/WebCore/html/HTMLAudioElement.h
index e453486..a12cd4b 100644
--- a/WebCore/html/HTMLAudioElement.h
+++ b/WebCore/html/HTMLAudioElement.h
@@ -43,7 +43,6 @@ private:
HTMLAudioElement(const QualifiedName&, Document*);
virtual bool isVideo() const { return false; }
- virtual int tagPriority() const { return 5; }
};
} //namespace
diff --git a/WebCore/html/HTMLBRElement.h b/WebCore/html/HTMLBRElement.h
index 3bb5af1..05df8f6 100644
--- a/WebCore/html/HTMLBRElement.h
+++ b/WebCore/html/HTMLBRElement.h
@@ -36,9 +36,6 @@ public:
private:
HTMLBRElement(const QualifiedName&, Document*);
- virtual HTMLTagStatus endTagRequirement() const { return TagStatusForbidden; }
- virtual int tagPriority() const { return 0; }
-
virtual bool mapToEntry(const QualifiedName&, MappedAttributeEntry&) const;
virtual void parseMappedAttribute(Attribute*);
diff --git a/WebCore/html/HTMLBaseElement.h b/WebCore/html/HTMLBaseElement.h
index 6c2d2d8..aa1454f 100644
--- a/WebCore/html/HTMLBaseElement.h
+++ b/WebCore/html/HTMLBaseElement.h
@@ -34,9 +34,6 @@ public:
private:
HTMLBaseElement(const QualifiedName&, Document*);
- virtual HTMLTagStatus endTagRequirement() const { return TagStatusForbidden; }
- virtual int tagPriority() const { return 0; }
-
virtual String target() const { return m_target; }
virtual void parseMappedAttribute(Attribute*);
diff --git a/WebCore/html/HTMLBaseFontElement.h b/WebCore/html/HTMLBaseFontElement.h
index 5651a61..7573045 100644
--- a/WebCore/html/HTMLBaseFontElement.h
+++ b/WebCore/html/HTMLBaseFontElement.h
@@ -33,9 +33,6 @@ public:
private:
HTMLBaseFontElement(const QualifiedName&, Document*);
-
- virtual HTMLTagStatus endTagRequirement() const { return TagStatusForbidden; }
- virtual int tagPriority() const { return 0; }
};
} // namespace
diff --git a/WebCore/html/HTMLBlockquoteElement.h b/WebCore/html/HTMLBlockquoteElement.h
index 3f46d63..194fe54 100644
--- a/WebCore/html/HTMLBlockquoteElement.h
+++ b/WebCore/html/HTMLBlockquoteElement.h
@@ -34,9 +34,6 @@ public:
private:
HTMLBlockquoteElement(const QualifiedName&, Document*);
-
- virtual HTMLTagStatus endTagRequirement() const { return TagStatusRequired; }
- virtual int tagPriority() const { return 5; }
};
} // namespace WebCore
diff --git a/WebCore/html/HTMLBodyElement.h b/WebCore/html/HTMLBodyElement.h
index 7b32549..d6ef185 100644
--- a/WebCore/html/HTMLBodyElement.h
+++ b/WebCore/html/HTMLBodyElement.h
@@ -69,9 +69,6 @@ public:
private:
HTMLBodyElement(const QualifiedName&, Document*);
- virtual HTMLTagStatus endTagRequirement() const { return TagStatusRequired; }
- virtual int tagPriority() const { return 10; }
-
virtual bool mapToEntry(const QualifiedName&, MappedAttributeEntry&) const;
virtual void parseMappedAttribute(Attribute*);
diff --git a/WebCore/html/HTMLCanvasElement.cpp b/WebCore/html/HTMLCanvasElement.cpp
index 84ab227..7463551 100644
--- a/WebCore/html/HTMLCanvasElement.cpp
+++ b/WebCore/html/HTMLCanvasElement.cpp
@@ -97,28 +97,6 @@ HTMLCanvasElement::~HTMLCanvasElement()
m_observer->canvasDestroyed(this);
}
-#if ENABLE(DASHBOARD_SUPPORT)
-
-HTMLTagStatus HTMLCanvasElement::endTagRequirement() const
-{
- Settings* settings = document()->settings();
- if (settings && settings->usesDashboardBackwardCompatibilityMode())
- return TagStatusForbidden;
-
- return HTMLElement::endTagRequirement();
-}
-
-int HTMLCanvasElement::tagPriority() const
-{
- Settings* settings = document()->settings();
- if (settings && settings->usesDashboardBackwardCompatibilityMode())
- return 0;
-
- return HTMLElement::tagPriority();
-}
-
-#endif
-
void HTMLCanvasElement::parseMappedAttribute(Attribute* attr)
{
const QualifiedName& attrName = attr->name();
@@ -168,7 +146,7 @@ CanvasRenderingContext* HTMLCanvasElement::getContext(const String& type, Canvas
if (Settings* settings = document()->settings())
usesDashbardCompatibilityMode = settings->usesDashboardBackwardCompatibilityMode();
#endif
- m_context = new CanvasRenderingContext2D(this, document()->inCompatMode(), usesDashbardCompatibilityMode);
+ m_context = adoptPtr(new CanvasRenderingContext2D(this, document()->inCompatMode(), usesDashbardCompatibilityMode));
#if ENABLE(ACCELERATED_2D_CANVAS) && USE(ACCELERATED_COMPOSITING)
if (m_context) {
// Need to make sure a RenderLayer and compositing layer get created for the Canvas
@@ -272,15 +250,11 @@ void HTMLCanvasElement::paint(GraphicsContext* context, const IntRect& r)
if (context->paintingDisabled())
return;
-#if ENABLE(3D_CANVAS)
- WebGLRenderingContext* context3D = 0;
- if (m_context && m_context->is3d()) {
- context3D = static_cast<WebGLRenderingContext*>(m_context.get());
- if (!context3D->paintsIntoCanvasBuffer())
+ if (m_context) {
+ if (!m_context->paintsIntoCanvasBuffer())
return;
- context3D->paintRenderingResultsToCanvas();
+ m_context->paintRenderingResultsToCanvas();
}
-#endif
if (hasCreatedImageBuffer()) {
ImageBuffer* imageBuffer = buffer();
diff --git a/WebCore/html/HTMLCanvasElement.h b/WebCore/html/HTMLCanvasElement.h
index 3270667..c9b258d 100644
--- a/WebCore/html/HTMLCanvasElement.h
+++ b/WebCore/html/HTMLCanvasElement.h
@@ -134,11 +134,6 @@ public:
private:
HTMLCanvasElement(const QualifiedName&, Document*);
-#if ENABLE(DASHBOARD_SUPPORT)
- virtual HTMLTagStatus endTagRequirement() const;
- virtual int tagPriority() const;
-#endif
-
virtual void parseMappedAttribute(Attribute*);
virtual RenderObject* createRenderer(RenderArena*, RenderStyle*);
diff --git a/WebCore/html/HTMLConstructionSite.cpp b/WebCore/html/HTMLConstructionSite.cpp
index a25c7d9..8735cd2 100644
--- a/WebCore/html/HTMLConstructionSite.cpp
+++ b/WebCore/html/HTMLConstructionSite.cpp
@@ -39,7 +39,6 @@
#include "HTMLScriptElement.h"
#include "HTMLToken.h"
#include "HTMLTokenizer.h"
-#include "LegacyHTMLTreeBuilder.h"
#include "LocalizedStrings.h"
#if ENABLE(MATHML)
#include "MathMLNames.h"
@@ -83,7 +82,7 @@ bool causesFosterParenting(const QualifiedName& tagName)
} // namespace
template<typename ChildType>
-PassRefPtr<ChildType> HTMLConstructionSite::attach(Node* parent, PassRefPtr<ChildType> prpChild)
+PassRefPtr<ChildType> HTMLConstructionSite::attach(ContainerNode* parent, PassRefPtr<ChildType> prpChild)
{
RefPtr<ChildType> child = prpChild;
@@ -92,7 +91,7 @@ PassRefPtr<ChildType> HTMLConstructionSite::attach(Node* parent, PassRefPtr<Chil
// doesn't. It feels like we're missing a concept somehow.
if (shouldFosterParent()) {
fosterParent(child.get());
- ASSERT(child->attached() || !child->parent()->attached());
+ ASSERT(child->attached() || !child->parent() || !child->parent()->attached());
return child.release();
}
@@ -118,10 +117,7 @@ void HTMLConstructionSite::attachAtSite(const AttachmentSite& site, PassRefPtr<N
RefPtr<Node> child = prpChild;
if (site.nextChild) {
- // FIXME: We need an insertElement which does not send mutation events.
- ExceptionCode ec = 0;
- site.parent->insertBefore(child, site.nextChild, ec);
- ASSERT(!ec);
+ site.parent->parserInsertBefore(child, site.nextChild);
if (site.parent->attached() && !child->attached())
child->attach();
return;
@@ -146,6 +142,11 @@ HTMLConstructionSite::~HTMLConstructionSite()
{
}
+void HTMLConstructionSite::detach()
+{
+ m_document = 0;
+}
+
void HTMLConstructionSite::setForm(HTMLFormElement* form)
{
// This method should only be needed for HTMLTreeBuilder in the fragment case.
@@ -160,6 +161,7 @@ PassRefPtr<HTMLFormElement> HTMLConstructionSite::takeForm()
void HTMLConstructionSite::dispatchDocumentElementAvailableIfNeeded()
{
+ ASSERT(m_document);
if (m_document->frame() && !m_isParsingFragment)
m_document->frame()->loader()->dispatchDocumentElementAvailable();
}
@@ -287,7 +289,8 @@ void HTMLConstructionSite::insertFormattingElement(AtomicHTMLToken& token)
void HTMLConstructionSite::insertScriptElement(AtomicHTMLToken& token)
{
RefPtr<HTMLScriptElement> element = HTMLScriptElement::create(scriptTag, m_document, true);
- element->setAttributeMap(token.takeAtributes(), m_fragmentScriptingPermission);
+ if (m_fragmentScriptingPermission == FragmentScriptingAllowed)
+ element->setAttributeMap(token.takeAtributes(), m_fragmentScriptingPermission);
m_openElements.push(attachToCurrent(element.release()));
}
@@ -429,7 +432,7 @@ void HTMLConstructionSite::findFosterSite(AttachmentSite& site)
HTMLElementStack::ElementRecord* lastTableElementRecord = m_openElements.topmost(tableTag.localName());
if (lastTableElementRecord) {
Element* lastTableElement = lastTableElementRecord->element();
- if (Node* parent = lastTableElement->parent()) {
+ if (ContainerNode* parent = lastTableElement->parent()) {
site.parent = parent;
site.nextChild = lastTableElement;
return;
diff --git a/WebCore/html/HTMLConstructionSite.h b/WebCore/html/HTMLConstructionSite.h
index 16ba56b..2e746b4 100644
--- a/WebCore/html/HTMLConstructionSite.h
+++ b/WebCore/html/HTMLConstructionSite.h
@@ -45,6 +45,8 @@ public:
HTMLConstructionSite(Document*, FragmentScriptingPermission, bool isParsingFragment);
~HTMLConstructionSite();
+ void detach();
+
void insertDoctype(AtomicHTMLToken&);
void insertComment(AtomicHTMLToken&);
void insertCommentOnDocument(AtomicHTMLToken&);
@@ -109,12 +111,12 @@ public:
private:
struct AttachmentSite {
- Node* parent;
+ ContainerNode* parent;
Node* nextChild;
};
template<typename ChildType>
- PassRefPtr<ChildType> attach(Node* parent, PassRefPtr<ChildType> child);
+ PassRefPtr<ChildType> attach(ContainerNode* parent, PassRefPtr<ChildType> child);
PassRefPtr<Element> attachToCurrent(PassRefPtr<Element>);
void attachAtSite(const AttachmentSite&, PassRefPtr<Node> child);
diff --git a/WebCore/html/HTMLDListElement.h b/WebCore/html/HTMLDListElement.h
index 260aa42..25697a1 100644
--- a/WebCore/html/HTMLDListElement.h
+++ b/WebCore/html/HTMLDListElement.h
@@ -33,9 +33,6 @@ public:
private:
HTMLDListElement(const QualifiedName&, Document*);
-
- virtual HTMLTagStatus endTagRequirement() const { return TagStatusRequired; }
- virtual int tagPriority() const { return 5; }
};
} //namespace
diff --git a/WebCore/html/HTMLDataGridCellElement.h b/WebCore/html/HTMLDataGridCellElement.h
index 567ec23..60af155 100644
--- a/WebCore/html/HTMLDataGridCellElement.h
+++ b/WebCore/html/HTMLDataGridCellElement.h
@@ -53,10 +53,6 @@ public:
private:
HTMLDataGridCellElement(const QualifiedName&, Document*);
-
- virtual HTMLTagStatus endTagRequirement() const { return TagStatusForbidden; }
- virtual int tagPriority() const { return 0; }
-
};
} // namespace WebCore
diff --git a/WebCore/html/HTMLDataGridColElement.h b/WebCore/html/HTMLDataGridColElement.h
index 701bc42..5198190 100644
--- a/WebCore/html/HTMLDataGridColElement.h
+++ b/WebCore/html/HTMLDataGridColElement.h
@@ -60,8 +60,6 @@ public:
private:
HTMLDataGridColElement(const QualifiedName&, Document*);
- virtual HTMLTagStatus endTagRequirement() const { return TagStatusForbidden; }
- virtual int tagPriority() const { return 0; }
virtual void insertedIntoTree(bool /*deep*/);
virtual void removedFromTree(bool /*deep*/);
virtual void parseMappedAttribute(Attribute*);
diff --git a/WebCore/html/HTMLDataGridElement.cpp b/WebCore/html/HTMLDataGridElement.cpp
index 82edf8f..d9ffa27 100644
--- a/WebCore/html/HTMLDataGridElement.cpp
+++ b/WebCore/html/HTMLDataGridElement.cpp
@@ -55,13 +55,6 @@ HTMLDataGridElement::~HTMLDataGridElement()
m_columns->clearDataGrid();
}
-bool HTMLDataGridElement::checkDTD(const Node* newChild)
-{
- if (newChild->isTextNode())
- return static_cast<const Text*>(newChild)->containsOnlyWhitespace();
- return newChild->hasTagName(dcolTag) || newChild->hasTagName(drowTag);
-}
-
RenderObject* HTMLDataGridElement::createRenderer(RenderArena* arena, RenderStyle*)
{
return new (arena) RenderDataGrid(this);
diff --git a/WebCore/html/HTMLDataGridElement.h b/WebCore/html/HTMLDataGridElement.h
index e29bf98..c594623 100644
--- a/WebCore/html/HTMLDataGridElement.h
+++ b/WebCore/html/HTMLDataGridElement.h
@@ -56,9 +56,6 @@ public:
private:
HTMLDataGridElement(const QualifiedName&, Document*);
- virtual int tagPriority() const { return 6; } // Same as <select>s
- virtual bool checkDTD(const Node*);
-
virtual RenderObject* createRenderer(RenderArena*, RenderStyle*);
RefPtr<DataGridDataSource> m_dataSource;
diff --git a/WebCore/html/HTMLDataGridRowElement.cpp b/WebCore/html/HTMLDataGridRowElement.cpp
index 8e08c7c..74c88ba 100644
--- a/WebCore/html/HTMLDataGridRowElement.cpp
+++ b/WebCore/html/HTMLDataGridRowElement.cpp
@@ -45,13 +45,6 @@ PassRefPtr<HTMLDataGridRowElement> HTMLDataGridRowElement::create(const Qualifie
return adoptRef(new HTMLDataGridRowElement(name, document));
}
-bool HTMLDataGridRowElement::checkDTD(const Node* newChild)
-{
- if (newChild->isTextNode())
- return static_cast<const Text*>(newChild)->containsOnlyWhitespace();
- return newChild->hasTagName(drowTag) || newChild->hasTagName(dcellTag);
-}
-
bool HTMLDataGridRowElement::selected() const
{
return hasAttribute(selectedAttr);
diff --git a/WebCore/html/HTMLDataGridRowElement.h b/WebCore/html/HTMLDataGridRowElement.h
index 81be914..3ee5bc6 100644
--- a/WebCore/html/HTMLDataGridRowElement.h
+++ b/WebCore/html/HTMLDataGridRowElement.h
@@ -47,9 +47,6 @@ public:
private:
HTMLDataGridRowElement(const QualifiedName&, Document*);
-
- virtual int tagPriority() const { return 2; } // Same as <option>s.
- virtual bool checkDTD(const Node*);
};
} // namespace WebCore
diff --git a/WebCore/html/HTMLDataListElement.cpp b/WebCore/html/HTMLDataListElement.cpp
index 3404348..b73606d 100644
--- a/WebCore/html/HTMLDataListElement.cpp
+++ b/WebCore/html/HTMLDataListElement.cpp
@@ -47,11 +47,6 @@ PassRefPtr<HTMLDataListElement> HTMLDataListElement::create(const QualifiedName&
return adoptRef(new HTMLDataListElement(tagName, document));
}
-bool HTMLDataListElement::checkDTD(const Node* newChild)
-{
- return newChild->hasTagName(HTMLNames::optionTag) || HTMLElement::inInlineTagList(newChild);
-}
-
PassRefPtr<HTMLCollection> HTMLDataListElement::options()
{
return HTMLCollection::create(this, DataListOptions);
diff --git a/WebCore/html/HTMLDataListElement.h b/WebCore/html/HTMLDataListElement.h
index 3587234..97e608f 100644
--- a/WebCore/html/HTMLDataListElement.h
+++ b/WebCore/html/HTMLDataListElement.h
@@ -47,8 +47,6 @@ public:
private:
HTMLDataListElement(const QualifiedName&, Document*);
-
- virtual bool checkDTD(const Node*);
};
} // namespace WebCore
diff --git a/WebCore/html/HTMLDirectoryElement.h b/WebCore/html/HTMLDirectoryElement.h
index 0e440d4..afd3876 100644
--- a/WebCore/html/HTMLDirectoryElement.h
+++ b/WebCore/html/HTMLDirectoryElement.h
@@ -33,9 +33,6 @@ public:
private:
HTMLDirectoryElement(const QualifiedName&, Document*);
-
- virtual HTMLTagStatus endTagRequirement() const { return TagStatusRequired; }
- virtual int tagPriority() const { return 5; }
};
} //namespace
diff --git a/WebCore/html/HTMLDivElement.h b/WebCore/html/HTMLDivElement.h
index 30eddf3..2e2b417 100644
--- a/WebCore/html/HTMLDivElement.h
+++ b/WebCore/html/HTMLDivElement.h
@@ -36,9 +36,6 @@ protected:
HTMLDivElement(const QualifiedName&, Document*);
private:
- virtual HTMLTagStatus endTagRequirement() const { return TagStatusRequired; }
- virtual int tagPriority() const { return 5; }
-
virtual bool mapToEntry(const QualifiedName&, MappedAttributeEntry&) const;
virtual void parseMappedAttribute(Attribute*);
};
diff --git a/WebCore/html/HTMLDocument.cpp b/WebCore/html/HTMLDocument.cpp
index 4e26c02..5e11ad2 100644
--- a/WebCore/html/HTMLDocument.cpp
+++ b/WebCore/html/HTMLDocument.cpp
@@ -282,25 +282,20 @@ void HTMLDocument::releaseEvents()
{
}
-DocumentParser* HTMLDocument::createParser()
+PassRefPtr<DocumentParser> HTMLDocument::createParser()
{
bool reportErrors = false;
#if ENABLE(INSPECTOR)
if (Page* page = this->page())
- reportErrors = page->inspectorController()->windowVisible();
+ reportErrors = page->inspectorController()->hasFrontend();
#endif
- return new HTMLDocumentParser(this, reportErrors);
+ return HTMLDocumentParser::create(this, reportErrors);
}
// --------------------------------------------------------------------------
// not part of the DOM
// --------------------------------------------------------------------------
-bool HTMLDocument::childAllowed(Node *newChild)
-{
- return newChild->hasTagName(htmlTag) || newChild->isCommentNode() || (newChild->nodeType() == DOCUMENT_TYPE_NODE && !doctype());
-}
-
PassRefPtr<Element> HTMLDocument::createElement(const AtomicString& name, ExceptionCode& ec)
{
if (!isValidName(name)) {
diff --git a/WebCore/html/HTMLDocument.h b/WebCore/html/HTMLDocument.h
index 3b5fdfa..583cdcc 100644
--- a/WebCore/html/HTMLDocument.h
+++ b/WebCore/html/HTMLDocument.h
@@ -91,12 +91,10 @@ protected:
#endif
private:
- virtual bool childAllowed(Node*);
-
virtual PassRefPtr<Element> createElement(const AtomicString& tagName, ExceptionCode&);
virtual bool isFrameSet() const;
- virtual DocumentParser* createParser();
+ virtual PassRefPtr<DocumentParser> createParser();
virtual void determineParseMode();
void addItemToMap(HashCountedSet<AtomicStringImpl*>&, const AtomicString&);
diff --git a/WebCore/html/HTMLDocumentParser.cpp b/WebCore/html/HTMLDocumentParser.cpp
index bd2c590..a271603 100644
--- a/WebCore/html/HTMLDocumentParser.cpp
+++ b/WebCore/html/HTMLDocumentParser.cpp
@@ -99,10 +99,10 @@ HTMLTokenizer::State tokenizerStateForContextElement(Element* contextElement, bo
HTMLDocumentParser::HTMLDocumentParser(HTMLDocument* document, bool reportErrors)
: ScriptableDocumentParser(document)
- , m_tokenizer(new HTMLTokenizer)
- , m_scriptRunner(new HTMLScriptRunner(document, this))
- , m_treeBuilder(new HTMLTreeBuilder(m_tokenizer.get(), document, reportErrors))
- , m_parserScheduler(new HTMLParserScheduler(this))
+ , m_tokenizer(HTMLTokenizer::create())
+ , m_scriptRunner(HTMLScriptRunner::create(document, this))
+ , m_treeBuilder(HTMLTreeBuilder::create(m_tokenizer.get(), document, reportErrors))
+ , m_parserScheduler(HTMLParserScheduler::create(this))
, m_endWasDelayed(false)
, m_writeNestingLevel(0)
{
@@ -112,8 +112,8 @@ HTMLDocumentParser::HTMLDocumentParser(HTMLDocument* document, bool reportErrors
// minimize code duplication between these constructors.
HTMLDocumentParser::HTMLDocumentParser(DocumentFragment* fragment, Element* contextElement, FragmentScriptingPermission scriptingPermission)
: ScriptableDocumentParser(fragment->document())
- , m_tokenizer(new HTMLTokenizer)
- , m_treeBuilder(new HTMLTreeBuilder(m_tokenizer.get(), fragment, contextElement, scriptingPermission))
+ , m_tokenizer(HTMLTokenizer::create())
+ , m_treeBuilder(HTMLTreeBuilder::create(m_tokenizer.get(), fragment, contextElement, scriptingPermission))
, m_endWasDelayed(false)
, m_writeNestingLevel(0)
{
@@ -123,10 +123,21 @@ HTMLDocumentParser::HTMLDocumentParser(DocumentFragment* fragment, Element* cont
HTMLDocumentParser::~HTMLDocumentParser()
{
- // FIXME: We'd like to ASSERT that normal operation of this class clears
- // out any delayed actions, but we can't because we're unceremoniously
- // deleted. If there were a required call to some sort of cancel function,
- // then we could ASSERT some invariants here.
+ ASSERT(!m_parserScheduler);
+ ASSERT(!m_writeNestingLevel);
+ ASSERT(!m_preloadScanner);
+}
+
+void HTMLDocumentParser::detach()
+{
+ DocumentParser::detach();
+ if (m_scriptRunner)
+ m_scriptRunner->detach();
+ m_treeBuilder->detach();
+ // FIXME: It seems wrong that we would have a preload scanner here.
+ // Yet during fast/dom/HTMLScriptElement/script-load-events.html we do.
+ m_preloadScanner.clear();
+ m_parserScheduler.clear(); // Deleting the scheduler will clear any timers.
}
void HTMLDocumentParser::stopParsing()
@@ -162,6 +173,10 @@ bool HTMLDocumentParser::isScheduledForResume() const
// Used by HTMLParserScheduler
void HTMLDocumentParser::resumeParsingAfterYield()
{
+ // pumpTokenizer can cause this parser to be detached from the Document,
+ // but we need to ensure it isn't deleted yet.
+ RefPtr<HTMLDocumentParser> protect(this);
+
// We should never be here unless we can pump immediately. Call pumpTokenizer()
// directly so that ASSERTS will fire if we're wrong.
pumpTokenizer(AllowYield);
@@ -182,9 +197,12 @@ bool HTMLDocumentParser::runScriptsForPausedTreeBuilder()
void HTMLDocumentParser::pumpTokenizer(SynchronousMode mode)
{
+ ASSERT(!isDetached());
ASSERT(!m_parserStopped);
ASSERT(!m_treeBuilder->isPaused());
ASSERT(!isScheduledForResume());
+ // ASSERT that this object is both attached to the Document and protected.
+ ASSERT(refCount() >= 2);
// We tell the InspectorTimelineAgent about every pump, even if we
// end up pumping nothing. It can filter out empty pumps itself.
@@ -192,13 +210,17 @@ void HTMLDocumentParser::pumpTokenizer(SynchronousMode mode)
HTMLParserScheduler::PumpSession session;
// FIXME: This loop body has is now too long and needs cleanup.
- while (mode == ForceSynchronous || (!m_parserStopped && m_parserScheduler->shouldContinueParsing(session))) {
+ while (mode == ForceSynchronous || m_parserScheduler->shouldContinueParsing(session)) {
if (!m_tokenizer->nextToken(m_input.current(), m_token))
break;
m_treeBuilder->constructTreeFromToken(m_token);
m_token.clear();
+ // JavaScript may have stopped or detached the parser.
+ if (isDetached() || m_parserStopped)
+ return;
+
// The parser will pause itself when waiting on a script to load or run.
if (!m_treeBuilder->isPaused())
continue;
@@ -206,14 +228,23 @@ void HTMLDocumentParser::pumpTokenizer(SynchronousMode mode)
// If we're paused waiting for a script, we try to execute scripts before continuing.
bool shouldContinueParsing = runScriptsForPausedTreeBuilder();
m_treeBuilder->setPaused(!shouldContinueParsing);
+
+ // JavaScript may have stopped or detached the parser.
+ if (isDetached() || m_parserStopped)
+ return;
+
if (!shouldContinueParsing)
break;
}
+ // Ensure we haven't been totally deref'ed after pumping. Any caller of this
+ // function should be holding a RefPtr to this to ensure we weren't deleted.
+ ASSERT(refCount() >= 1);
+
if (isWaitingForScripts()) {
ASSERT(m_tokenizer->state() == HTMLTokenizer::DataState);
if (!m_preloadScanner) {
- m_preloadScanner.set(new HTMLPreloadScanner(m_document));
+ m_preloadScanner.set(new HTMLPreloadScanner(document()));
m_preloadScanner->appendToEnd(m_input.current());
}
m_preloadScanner->scan();
@@ -228,7 +259,7 @@ void HTMLDocumentParser::willPumpLexer()
// FIXME: m_input.current().length() is only accurate if we
// end up parsing the whole buffer in this pump. We should pass how
// much we parsed as part of didWriteHTML instead of willWriteHTML.
- if (InspectorTimelineAgent* timelineAgent = m_document->inspectorTimelineAgent())
+ if (InspectorTimelineAgent* timelineAgent = document()->inspectorTimelineAgent())
timelineAgent->willWriteHTML(m_input.current().length(), m_tokenizer->lineNumber());
#endif
}
@@ -236,7 +267,7 @@ void HTMLDocumentParser::willPumpLexer()
void HTMLDocumentParser::didPumpLexer()
{
#if ENABLE(INSPECTOR)
- if (InspectorTimelineAgent* timelineAgent = m_document->inspectorTimelineAgent())
+ if (InspectorTimelineAgent* timelineAgent = document()->inspectorTimelineAgent())
timelineAgent->didWriteHTML(m_tokenizer->lineNumber());
#endif
}
@@ -251,9 +282,15 @@ void HTMLDocumentParser::insert(const SegmentedString& source)
if (m_parserStopped)
return;
+<<<<<<< HEAD
#ifdef ANDROID_INSTRUMENT
android::TimeCounter::start(android::TimeCounter::ParsingTimeCounter);
#endif
+=======
+ // pumpTokenizer can cause this parser to be detached from the Document,
+ // but we need to ensure it isn't deleted yet.
+ RefPtr<HTMLDocumentParser> protect(this);
+>>>>>>> webkit.org at r66079
{
NestingLevelIncrementer nestingLevelIncrementer(m_writeNestingLevel);
@@ -272,6 +309,10 @@ void HTMLDocumentParser::append(const SegmentedString& source)
if (m_parserStopped)
return;
+ // pumpTokenizer can cause this parser to be detached from the Document,
+ // but we need to ensure it isn't deleted yet.
+ RefPtr<HTMLDocumentParser> protect(this);
+
{
NestingLevelIncrementer nestingLevelIncrementer(m_writeNestingLevel);
@@ -300,7 +341,13 @@ void HTMLDocumentParser::append(const SegmentedString& source)
void HTMLDocumentParser::end()
{
+ ASSERT(!isDetached());
ASSERT(!isScheduledForResume());
+
+ // pumpTokenizer can cause this parser to be detached from the Document,
+ // but we need to ensure it isn't deleted yet.
+ RefPtr<HTMLDocumentParser> protect(this);
+
// NOTE: This pump should only ever emit buffered character tokens,
// so ForceSynchronous vs. AllowYield should be meaningless.
pumpTokenizerIfPossible(ForceSynchronous);
@@ -323,6 +370,10 @@ void HTMLDocumentParser::attemptToEnd()
void HTMLDocumentParser::endIfDelayed()
{
+ // If we've already been detached, don't bother ending.
+ if (isDetached())
+ return;
+
if (!m_endWasDelayed || shouldDelayEnd())
return;
@@ -332,6 +383,11 @@ void HTMLDocumentParser::endIfDelayed()
void HTMLDocumentParser::finish()
{
+ // FIXME: We should ASSERT(!m_parserStopped) here, since it does not
+ // makes sense to call any methods on DocumentParser once it's been stopped.
+ // However, FrameLoader::stop calls Document::finishParsing unconditionally
+ // which in turn calls m_parser->finish().
+
// We're not going to get any more data off the network, so we tell the
// input stream we've reached the end of file. finish() can be called more
// than once, if the first time does not call end().
@@ -369,11 +425,6 @@ int HTMLDocumentParser::columnNumber() const
return m_tokenizer->columnNumber();
}
-LegacyHTMLTreeBuilder* HTMLDocumentParser::htmlTreeBuilder() const
-{
- return m_treeBuilder->legacyTreeBuilder();
-}
-
bool HTMLDocumentParser::isWaitingForScripts() const
{
return m_treeBuilder->isPaused();
@@ -412,6 +463,10 @@ bool HTMLDocumentParser::shouldLoadExternalScriptFromSrc(const AtomicString& src
void HTMLDocumentParser::notifyFinished(CachedResource* cachedResource)
{
+ // pumpTokenizer can cause this parser to be detached from the Document,
+ // but we need to ensure it isn't deleted yet.
+ RefPtr<HTMLDocumentParser> protect(this);
+
ASSERT(m_scriptRunner);
ASSERT(!inScriptExecution());
ASSERT(m_treeBuilder->isPaused());
@@ -434,6 +489,11 @@ void HTMLDocumentParser::executeScriptsWaitingForStylesheets()
// is a re-entrant call from encountering a </ style> tag.
if (!m_scriptRunner->hasScriptsWaitingForStylesheets())
return;
+
+ // pumpTokenizer can cause this parser to be detached from the Document,
+ // but we need to ensure it isn't deleted yet.
+ RefPtr<HTMLDocumentParser> protect(this);
+
ASSERT(!m_scriptRunner->isExecutingScript());
ASSERT(m_treeBuilder->isPaused());
// Note: We only ever wait on one script at a time, so we always know this
@@ -447,15 +507,16 @@ void HTMLDocumentParser::executeScriptsWaitingForStylesheets()
ScriptController* HTMLDocumentParser::script() const
{
- return m_document->frame() ? m_document->frame()->script() : 0;
+ return document()->frame() ? document()->frame()->script() : 0;
}
void HTMLDocumentParser::parseDocumentFragment(const String& source, DocumentFragment* fragment, Element* contextElement, FragmentScriptingPermission scriptingPermission)
{
- HTMLDocumentParser parser(fragment, contextElement, scriptingPermission);
- parser.insert(source); // Use insert() so that the parser will not yield.
- parser.finish();
- ASSERT(!parser.processingData()); // Make sure we're done. <rdar://problem/3963151>
+ RefPtr<HTMLDocumentParser> parser = HTMLDocumentParser::create(fragment, contextElement, scriptingPermission);
+ parser->insert(source); // Use insert() so that the parser will not yield.
+ parser->finish();
+ ASSERT(!parser->processingData()); // Make sure we're done. <rdar://problem/3963151>
+ parser->detach(); // Allows ~DocumentParser to assert it was detached before destruction.
}
}
diff --git a/WebCore/html/HTMLDocumentParser.h b/WebCore/html/HTMLDocumentParser.h
index d35cfaf..da21a2b 100644
--- a/WebCore/html/HTMLDocumentParser.h
+++ b/WebCore/html/HTMLDocumentParser.h
@@ -46,15 +46,20 @@ class HTMLTokenizer;
class HTMLScriptRunner;
class HTMLTreeBuilder;
class HTMLPreloadScanner;
-class LegacyHTMLTreeBuilder;
class ScriptController;
class ScriptSourceCode;
class HTMLDocumentParser : public ScriptableDocumentParser, HTMLScriptRunnerHost, CachedResourceClient {
public:
- // FIXME: These constructors should be made private and replaced by create() methods.
- HTMLDocumentParser(HTMLDocument*, bool reportErrors);
- HTMLDocumentParser(DocumentFragment*, Element* contextElement, FragmentScriptingPermission);
+ static PassRefPtr<HTMLDocumentParser> create(HTMLDocument* document, bool reportErrors)
+ {
+ return adoptRef(new HTMLDocumentParser(document, reportErrors));
+ }
+ static PassRefPtr<HTMLDocumentParser> create(DocumentFragment* fragment, Element* contextElement, FragmentScriptingPermission permission)
+ {
+ return adoptRef(new HTMLDocumentParser(fragment, contextElement, permission));
+ }
+
virtual ~HTMLDocumentParser();
// Exposed for HTMLParserScheduler
@@ -66,8 +71,12 @@ protected:
virtual void insert(const SegmentedString&);
virtual void finish();
+ HTMLDocumentParser(HTMLDocument*, bool reportErrors);
+ HTMLDocumentParser(DocumentFragment*, Element* contextElement, FragmentScriptingPermission);
+
private:
// DocumentParser
+ virtual void detach();
virtual bool hasInsertionPoint();
virtual void append(const SegmentedString&);
virtual bool finishWasCalled();
@@ -78,9 +87,6 @@ private:
virtual void executeScriptsWaitingForStylesheets();
virtual int lineNumber() const;
virtual int columnNumber() const;
- // FIXME: HTMLFormControlElement accesses the LegacyHTMLTreeBuilder via this method.
- // Remove this when the LegacyHTMLTreeBuilder is no longer used.
- virtual LegacyHTMLTreeBuilder* htmlTreeBuilder() const;
// HTMLScriptRunnerHost
virtual void watchForLoad(CachedResource*);
diff --git a/WebCore/html/HTMLElement.cpp b/WebCore/html/HTMLElement.cpp
index ff25e62..f40489b 100644
--- a/WebCore/html/HTMLElement.cpp
+++ b/WebCore/html/HTMLElement.cpp
@@ -61,68 +61,55 @@ PassRefPtr<HTMLElement> HTMLElement::create(const QualifiedName& tagName, Docume
String HTMLElement::nodeName() const
{
- // FIXME: Would be nice to have an atomicstring lookup based off uppercase chars that does not have to copy
- // the string on a hit in the hash.
+ // FIXME: Would be nice to have an atomicstring lookup based off uppercase
+ // chars that does not have to copy the string on a hit in the hash.
// FIXME: We should have a way to detect XHTML elements and replace the hasPrefix() check with it.
if (document()->isHTMLDocument() && !tagQName().hasPrefix())
return tagQName().localNameUpper();
return Element::nodeName();
}
-
-HTMLTagStatus HTMLElement::endTagRequirement() const
-{
- if (hasLocalName(wbrTag))
- return TagStatusForbidden;
- if (hasLocalName(dtTag) || hasLocalName(ddTag) || hasLocalName(rpTag) || hasLocalName(rtTag))
- return TagStatusOptional;
-
- // Same values as <span>. This way custom tag name elements will behave like inline spans.
- return TagStatusRequired;
-}
-struct Empty1IntHashTraits : HashTraits<int> {
- static const bool emptyValueIsZero = false;
- static int emptyValue() { return 1; }
-};
-typedef HashMap<AtomicStringImpl*, int, DefaultHash<AtomicStringImpl*>::Hash, HashTraits<AtomicStringImpl*>, Empty1IntHashTraits> TagPriorityMap;
-
-static const TagPriorityMap* createTagPriorityMap()
-{
- TagPriorityMap* map = new TagPriorityMap;
-
- map->add(wbrTag.localName().impl(), 0);
-
- map->add(addressTag.localName().impl(), 3);
- map->add(ddTag.localName().impl(), 3);
- map->add(dtTag.localName().impl(), 3);
- map->add(noscriptTag.localName().impl(), 3);
- map->add(rpTag.localName().impl(), 3);
- map->add(rtTag.localName().impl(), 3);
-
- // 5 is same as <div>'s priority.
- map->add(articleTag.localName().impl(), 5);
- map->add(asideTag.localName().impl(), 5);
- map->add(centerTag.localName().impl(), 5);
- map->add(footerTag.localName().impl(), 5);
- map->add(headerTag.localName().impl(), 5);
- map->add(hgroupTag.localName().impl(), 5);
- map->add(nobrTag.localName().impl(), 5);
- map->add(rubyTag.localName().impl(), 5);
- map->add(navTag.localName().impl(), 5);
- map->add(sectionTag.localName().impl(), 5);
-
- map->add(noembedTag.localName().impl(), 10);
- map->add(noframesTag.localName().impl(), 10);
-
- // TagPriorityMap returns 1 for unregistered tags. It's same as <span>.
- // This way custom tag name elements will behave like inline spans.
- return map;
-}
-
-int HTMLElement::tagPriority() const
-{
- static const TagPriorityMap* tagPriorityMap = createTagPriorityMap();
- return tagPriorityMap->get(localName().impl());
+bool HTMLElement::ieForbidsInsertHTML() const
+{
+ // FIXME: Supposedly IE disallows settting innerHTML, outerHTML
+ // and createContextualFragment on these tags. We have no tests to
+ // verify this however, so this list could be totally wrong.
+ // This list was moved from the previous endTagRequirement() implementation.
+ // This is also called from editing and assumed to be the list of tags
+ // for which no end tag should be serialized. It's unclear if the list for
+ // IE compat and the list for serialization sanity are the same.
+ if (hasLocalName(areaTag)
+ || hasLocalName(baseTag)
+ || hasLocalName(basefontTag)
+ || hasLocalName(brTag)
+ || hasLocalName(colTag)
+#if ENABLE(DATAGRID)
+ || hasLocalName(dcellTag)
+ || hasLocalName(dcolTag)
+#endif
+ || hasLocalName(embedTag)
+ || hasLocalName(frameTag)
+ || hasLocalName(hrTag)
+ || hasLocalName(imageTag)
+ || hasLocalName(imgTag)
+ || hasLocalName(inputTag)
+ || hasLocalName(isindexTag)
+ || hasLocalName(linkTag)
+ || hasLocalName(metaTag)
+ || hasLocalName(paramTag)
+ || hasLocalName(sourceTag)
+ || hasLocalName(wbrTag))
+ return true;
+ // FIXME: I'm not sure why dashboard mode would want to change the
+ // serialization of <canvas>, that seems like a bad idea.
+#if ENABLE(DASHBOARD_SUPPORT)
+ if (hasLocalName(canvasTag)) {
+ Settings* settings = document()->settings();
+ if (settings && settings->usesDashboardBackwardCompatibilityMode())
+ return true;
+ }
+#endif
+ return false;
}
bool HTMLElement::mapToEntry(const QualifiedName& attrName, MappedAttributeEntry& result) const
@@ -275,16 +262,16 @@ String HTMLElement::outerHTML() const
return createMarkup(this);
}
-static bool useLegacyTreeBuilder(Document* document)
+static bool useLegacyTreeBuilder(Document*)
{
- return !document || !document->settings() || !document->settings()->html5TreeBuilderEnabled();
+ return false;
}
// FIXME: This logic should move into Range::createContextualFragment
PassRefPtr<DocumentFragment> HTMLElement::deprecatedCreateContextualFragment(const String& markup, FragmentScriptingPermission scriptingPermission)
{
// The following is in accordance with the definition as used by IE.
- if (endTagRequirement() == TagStatusForbidden)
+ if (ieForbidsInsertHTML())
return 0;
if (hasLocalName(colTag) || hasLocalName(colgroupTag) || hasLocalName(framesetTag)
@@ -404,8 +391,7 @@ void HTMLElement::setOuterHTML(const String& html, ExceptionCode& ec)
void HTMLElement::setInnerText(const String& text, ExceptionCode& ec)
{
- // Follow the IE specs about when this is allowed.
- if (endTagRequirement() == TagStatusForbidden) {
+ if (ieForbidsInsertHTML()) {
ec = NO_MODIFICATION_ALLOWED_ERR;
return;
}
@@ -474,8 +460,7 @@ void HTMLElement::setInnerText(const String& text, ExceptionCode& ec)
void HTMLElement::setOuterText(const String &text, ExceptionCode& ec)
{
- // Follow the IE specs about when this is allowed.
- if (endTagRequirement() == TagStatusForbidden) {
+ if (ieForbidsInsertHTML()) {
ec = NO_MODIFICATION_ALLOWED_ERR;
return;
}
@@ -666,9 +651,9 @@ bool HTMLElement::isContentEditable() const
if (document()->frame() && document()->frame()->isContentEditable())
return true;
- // FIXME: this is a terrible thing to do here:
- // https://bugs.webkit.org/show_bug.cgi?id=21834
- document()->updateStyleIfNeeded();
+ // Ideally we'd call ASSERT!needsStyleRecalc()) here, but
+ // ContainerNode::setFocus() calls setNeedsStyleRecalc(), so the assertion
+ // would fire in the middle of Document::setFocusedNode().
if (!renderer()) {
if (parentNode())
@@ -685,8 +670,6 @@ bool HTMLElement::isContentRichlyEditable() const
if (document()->frame() && document()->frame()->isContentEditable())
return true;
- document()->updateStyleIfNeeded();
-
if (!renderer()) {
if (parentNode())
return parentNode()->isContentEditable();
@@ -699,8 +682,6 @@ bool HTMLElement::isContentRichlyEditable() const
String HTMLElement::contentEditable() const
{
- document()->updateStyleIfNeeded();
-
if (!renderer())
return "false";
@@ -802,239 +783,6 @@ PassRefPtr<HTMLCollection> HTMLElement::children()
return HTMLCollection::create(this, NodeChildren);
}
-// DOM Section 1.1.1
-bool HTMLElement::childAllowed(Node *newChild)
-{
- if (!Element::childAllowed(newChild))
- return false;
-
- // For XML documents, we are non-validating and do not check against a DTD, even for HTML elements.
- if (!document()->isHTMLDocument())
- return true;
-
- // Future-proof for XML content inside HTML documents (we may allow this some day).
- if (newChild->isElementNode() && !newChild->isHTMLElement())
- return true;
-
- // Elements with forbidden tag status can never have children
- if (endTagRequirement() == TagStatusForbidden)
- return false;
-
- // Comment nodes are always allowed.
- if (newChild->isCommentNode())
- return true;
-
- // Now call checkDTD.
- return checkDTD(newChild);
-}
-
-// DTD Stuff
-// This unfortunate function is only needed when checking against the DTD. Other languages (like SVG) won't need this.
-bool HTMLElement::isRecognizedTagName(const QualifiedName& tagName)
-{
- DEFINE_STATIC_LOCAL(HashSet<AtomicStringImpl*>, tagList, ());
- if (tagList.isEmpty()) {
- size_t tagCount = 0;
- WebCore::QualifiedName** tags = HTMLNames::getHTMLTags(&tagCount);
- for (size_t i = 0; i < tagCount; i++) {
- if (*tags[i] == bgsoundTag
- || *tags[i] == commandTag
- || *tags[i] == detailsTag
- || *tags[i] == figcaptionTag
- || *tags[i] == figureTag
- || *tags[i] == summaryTag
- || *tags[i] == trackTag) {
- // Even though we have atoms for these tags, we don't want to
- // treat them as "recognized tags" for the purpose of parsing
- // because that changes how we parse documents.
- continue;
- }
- tagList.add(tags[i]->localName().impl());
- }
- }
- return tagList.contains(tagName.localName().impl());
-}
-
-// The terms inline and block are used here loosely. Don't make the mistake of assuming all inlines or all blocks
-// need to be in these two lists.
-static HashSet<AtomicStringImpl*>* inlineTagList()
-{
- DEFINE_STATIC_LOCAL(HashSet<AtomicStringImpl*>, tagList, ());
- if (tagList.isEmpty()) {
- tagList.add(ttTag.localName().impl());
- tagList.add(iTag.localName().impl());
- tagList.add(bTag.localName().impl());
- tagList.add(uTag.localName().impl());
- tagList.add(sTag.localName().impl());
- tagList.add(strikeTag.localName().impl());
- tagList.add(bigTag.localName().impl());
- tagList.add(smallTag.localName().impl());
- tagList.add(emTag.localName().impl());
- tagList.add(strongTag.localName().impl());
- tagList.add(dfnTag.localName().impl());
- tagList.add(codeTag.localName().impl());
- tagList.add(sampTag.localName().impl());
- tagList.add(kbdTag.localName().impl());
- tagList.add(varTag.localName().impl());
- tagList.add(citeTag.localName().impl());
- tagList.add(abbrTag.localName().impl());
- tagList.add(acronymTag.localName().impl());
- tagList.add(aTag.localName().impl());
- tagList.add(canvasTag.localName().impl());
- tagList.add(imgTag.localName().impl());
- tagList.add(appletTag.localName().impl());
- tagList.add(objectTag.localName().impl());
- tagList.add(embedTag.localName().impl());
- tagList.add(fontTag.localName().impl());
- tagList.add(basefontTag.localName().impl());
- tagList.add(brTag.localName().impl());
- tagList.add(scriptTag.localName().impl());
- tagList.add(styleTag.localName().impl());
- tagList.add(linkTag.localName().impl());
- tagList.add(mapTag.localName().impl());
- tagList.add(qTag.localName().impl());
- tagList.add(subTag.localName().impl());
- tagList.add(supTag.localName().impl());
- tagList.add(spanTag.localName().impl());
- tagList.add(bdoTag.localName().impl());
- tagList.add(iframeTag.localName().impl());
- tagList.add(inputTag.localName().impl());
- tagList.add(keygenTag.localName().impl());
- tagList.add(selectTag.localName().impl());
- tagList.add(datagridTag.localName().impl());
- tagList.add(textareaTag.localName().impl());
- tagList.add(labelTag.localName().impl());
- tagList.add(buttonTag.localName().impl());
- tagList.add(datalistTag.localName().impl());
- tagList.add(insTag.localName().impl());
- tagList.add(delTag.localName().impl());
- tagList.add(nobrTag.localName().impl());
- tagList.add(wbrTag.localName().impl());
-#if ENABLE(VIDEO)
- tagList.add(audioTag.localName().impl());
- tagList.add(videoTag.localName().impl());
-#endif
- tagList.add(rpTag.localName().impl());
- tagList.add(rtTag.localName().impl());
- tagList.add(rubyTag.localName().impl());
- tagList.add(progressTag.localName().impl());
- tagList.add(meterTag.localName().impl());
- tagList.add(markTag.localName().impl());
- }
- return &tagList;
-}
-
-static HashSet<AtomicStringImpl*>* blockTagList()
-{
- DEFINE_STATIC_LOCAL(HashSet<AtomicStringImpl*>, tagList, ());
- if (tagList.isEmpty()) {
- tagList.add(addressTag.localName().impl());
- tagList.add(articleTag.localName().impl());
- tagList.add(asideTag.localName().impl());
- tagList.add(blockquoteTag.localName().impl());
- tagList.add(centerTag.localName().impl());
- tagList.add(ddTag.localName().impl());
- tagList.add(dirTag.localName().impl());
- tagList.add(divTag.localName().impl());
- tagList.add(dlTag.localName().impl());
- tagList.add(dtTag.localName().impl());
- tagList.add(fieldsetTag.localName().impl());
- tagList.add(footerTag.localName().impl());
- tagList.add(formTag.localName().impl());
- tagList.add(h1Tag.localName().impl());
- tagList.add(h2Tag.localName().impl());
- tagList.add(h3Tag.localName().impl());
- tagList.add(h4Tag.localName().impl());
- tagList.add(h5Tag.localName().impl());
- tagList.add(h6Tag.localName().impl());
- tagList.add(headerTag.localName().impl());
- tagList.add(hgroupTag.localName().impl());
- tagList.add(hrTag.localName().impl());
- tagList.add(isindexTag.localName().impl());
- tagList.add(layerTag.localName().impl());
- tagList.add(liTag.localName().impl());
- tagList.add(listingTag.localName().impl());
- tagList.add(marqueeTag.localName().impl());
- tagList.add(menuTag.localName().impl());
- tagList.add(navTag.localName().impl());
- tagList.add(noembedTag.localName().impl());
- tagList.add(noframesTag.localName().impl());
- tagList.add(nolayerTag.localName().impl());
- tagList.add(noscriptTag.localName().impl());
- tagList.add(olTag.localName().impl());
- tagList.add(pTag.localName().impl());
- tagList.add(plaintextTag.localName().impl());
- tagList.add(preTag.localName().impl());
- tagList.add(sectionTag.localName().impl());
- tagList.add(tableTag.localName().impl());
- tagList.add(ulTag.localName().impl());
- tagList.add(xmpTag.localName().impl());
- }
- return &tagList;
-}
-
-bool HTMLElement::inEitherTagList(const Node* newChild)
-{
- if (newChild->isTextNode())
- return true;
-
- if (newChild->isHTMLElement()) {
- const HTMLElement* child = static_cast<const HTMLElement*>(newChild);
- if (inlineTagList()->contains(child->tagQName().localName().impl())) {
-#if PLATFORM(MAC)
- if (child->tagQName().localName() == styleTag) {
- // Leopard Mail doesn't expect <style> to be in the body of the document, so don't allow it in that case.
- // See <rdar://problem/6621310>
- Settings* settings = newChild->document() ? newChild->document()->settings() : 0;
- if (settings && settings->needsLeopardMailQuirks())
- return false;
- }
-#endif
- return true;
- }
- if (blockTagList()->contains(child->tagQName().localName().impl()))
- return true;
- return !isRecognizedTagName(child->tagQName()); // Accept custom html tags
- }
-
- return false;
-}
-
-bool HTMLElement::inInlineTagList(const Node* newChild)
-{
- if (newChild->isTextNode())
- return true;
-
- if (newChild->isHTMLElement()) {
- const HTMLElement* child = static_cast<const HTMLElement*>(newChild);
- if (inlineTagList()->contains(child->tagQName().localName().impl()))
- return true;
- return !isRecognizedTagName(child->tagQName()); // Accept custom html tags
- }
-
- return false;
-}
-
-bool HTMLElement::inBlockTagList(const Node* newChild)
-{
- if (newChild->isTextNode())
- return true;
-
- if (newChild->isHTMLElement()) {
- const HTMLElement* child = static_cast<const HTMLElement*>(newChild);
- return (blockTagList()->contains(child->tagQName().localName().impl()));
- }
-
- return false;
-}
-
-bool HTMLElement::checkDTD(const Node* newChild)
-{
- if (hasLocalName(addressTag) && newChild->hasTagName(pTag))
- return true;
- return inEitherTagList(newChild);
-}
-
bool HTMLElement::rendererIsNeeded(RenderStyle *style)
{
#if !ENABLE(XHTMLMP)
diff --git a/WebCore/html/HTMLElement.h b/WebCore/html/HTMLElement.h
index 8f54d3e..52e9ecf 100644
--- a/WebCore/html/HTMLElement.h
+++ b/WebCore/html/HTMLElement.h
@@ -30,8 +30,6 @@ namespace WebCore {
class DocumentFragment;
class HTMLCollection;
class HTMLFormElement;
-
-enum HTMLTagStatus { TagStatusOptional, TagStatusRequired, TagStatusForbidden };
class HTMLElement : public StyledElement {
public:
@@ -72,8 +70,7 @@ public:
virtual void accessKeyAction(bool sendToAnyElement);
- virtual HTMLTagStatus endTagRequirement() const;
- virtual int tagPriority() const;
+ bool ieForbidsInsertHTML() const;
virtual bool rendererIsNeeded(RenderStyle*);
virtual RenderObject* createRenderer(RenderArena*, RenderStyle*);
@@ -90,16 +87,6 @@ protected:
virtual bool mapToEntry(const QualifiedName& attrName, MappedAttributeEntry& result) const;
virtual void parseMappedAttribute(Attribute*);
- virtual bool childAllowed(Node* newChild); // Error-checking during parsing that checks the DTD
-
- // Helper function to check the DTD for a given child node.
- virtual bool checkDTD(const Node*);
-
- static bool inEitherTagList(const Node*);
- static bool inInlineTagList(const Node*);
- static bool inBlockTagList(const Node*);
- static bool isRecognizedTagName(const QualifiedName&);
-
HTMLFormElement* findFormAncestor() const;
private:
diff --git a/WebCore/html/HTMLElementStack.cpp b/WebCore/html/HTMLElementStack.cpp
index 194753b..b6f4111 100644
--- a/WebCore/html/HTMLElementStack.cpp
+++ b/WebCore/html/HTMLElementStack.cpp
@@ -299,7 +299,7 @@ void HTMLElementStack::insertAbove(PassRefPtr<Element> element, ElementRecord* r
if (recordAbove->next() != recordBelow)
continue;
- recordAbove->setNext(new ElementRecord(element, recordAbove->releaseNext()));
+ recordAbove->setNext(adoptPtr(new ElementRecord(element, recordAbove->releaseNext())));
recordAbove->next()->element()->beginParsingChildren();
return;
}
@@ -492,7 +492,7 @@ Element* HTMLElementStack::bodyElement() const
void HTMLElementStack::pushCommon(PassRefPtr<Element> element)
{
ASSERT(m_htmlElement);
- m_top.set(new ElementRecord(element, m_top.release()));
+ m_top = adoptPtr(new ElementRecord(element, m_top.release()));
top()->beginParsingChildren();
}
diff --git a/WebCore/html/HTMLEmbedElement.cpp b/WebCore/html/HTMLEmbedElement.cpp
index afa56d4..0a15321 100644
--- a/WebCore/html/HTMLEmbedElement.cpp
+++ b/WebCore/html/HTMLEmbedElement.cpp
@@ -100,7 +100,7 @@ void HTMLEmbedElement::parseMappedAttribute(Attribute* attr)
m_url = deprecatedParseURL(value.string());
if (renderer() && isImageType()) {
if (!m_imageLoader)
- m_imageLoader.set(new HTMLImageLoader(this));
+ m_imageLoader = adoptPtr(new HTMLImageLoader(this));
m_imageLoader->updateFromElementIgnoringPreviousError();
}
} else if (attr->name() == hiddenAttr) {
@@ -167,7 +167,7 @@ void HTMLEmbedElement::attach()
if (isImage && renderer()) {
if (!m_imageLoader)
- m_imageLoader.set(new HTMLImageLoader(this));
+ m_imageLoader = adoptPtr(new HTMLImageLoader(this));
m_imageLoader->updateFromElement();
if (renderer())
diff --git a/WebCore/html/HTMLEmbedElement.h b/WebCore/html/HTMLEmbedElement.h
index 53da011..5f4df67 100644
--- a/WebCore/html/HTMLEmbedElement.h
+++ b/WebCore/html/HTMLEmbedElement.h
@@ -36,9 +36,6 @@ public:
private:
HTMLEmbedElement(const QualifiedName&, Document*);
- virtual HTMLTagStatus endTagRequirement() const { return TagStatusForbidden; }
- virtual int tagPriority() const { return 0; }
-
virtual bool mapToEntry(const QualifiedName& attrName, MappedAttributeEntry& result) const;
virtual void parseMappedAttribute(Attribute*);
diff --git a/WebCore/html/HTMLFieldSetElement.cpp b/WebCore/html/HTMLFieldSetElement.cpp
index ae0f8e7..4b90412 100644
--- a/WebCore/html/HTMLFieldSetElement.cpp
+++ b/WebCore/html/HTMLFieldSetElement.cpp
@@ -44,11 +44,6 @@ PassRefPtr<HTMLFieldSetElement> HTMLFieldSetElement::create(const QualifiedName&
return adoptRef(new HTMLFieldSetElement(tagName, document, form));
}
-bool HTMLFieldSetElement::checkDTD(const Node* newChild)
-{
- return newChild->hasTagName(legendTag) || HTMLElement::checkDTD(newChild);
-}
-
bool HTMLFieldSetElement::supportsFocus() const
{
return HTMLElement::supportsFocus();
diff --git a/WebCore/html/HTMLFieldSetElement.h b/WebCore/html/HTMLFieldSetElement.h
index 58c3ec4..db99a89 100644
--- a/WebCore/html/HTMLFieldSetElement.h
+++ b/WebCore/html/HTMLFieldSetElement.h
@@ -35,9 +35,6 @@ public:
private:
HTMLFieldSetElement(const QualifiedName&, Document*, HTMLFormElement*);
- virtual int tagPriority() const { return 3; }
- virtual bool checkDTD(const Node* newChild);
-
virtual bool supportsFocus() const;
virtual RenderObject* createRenderer(RenderArena*, RenderStyle*);
virtual const AtomicString& formControlType() const;
diff --git a/WebCore/html/HTMLFontElement.h b/WebCore/html/HTMLFontElement.h
index f96a50b..f97ab08 100644
--- a/WebCore/html/HTMLFontElement.h
+++ b/WebCore/html/HTMLFontElement.h
@@ -36,9 +36,6 @@ public:
private:
HTMLFontElement(const QualifiedName&, Document*);
-
- virtual HTMLTagStatus endTagRequirement() const { return TagStatusRequired; }
- virtual int tagPriority() const { return 1; }
virtual bool mapToEntry(const QualifiedName&, MappedAttributeEntry&) const;
virtual void parseMappedAttribute(Attribute*);
diff --git a/WebCore/html/HTMLFormCollection.cpp b/WebCore/html/HTMLFormCollection.cpp
index 7a2e63a..4147f29 100644
--- a/WebCore/html/HTMLFormCollection.cpp
+++ b/WebCore/html/HTMLFormCollection.cpp
@@ -39,7 +39,7 @@ using namespace HTMLNames;
inline CollectionCache* HTMLFormCollection::formCollectionInfo(HTMLFormElement* form)
{
if (!form->m_collectionCache)
- form->m_collectionCache.set(new CollectionCache);
+ form->m_collectionCache = adoptPtr(new CollectionCache);
return form->m_collectionCache.get();
}
diff --git a/WebCore/html/HTMLFormControlElement.cpp b/WebCore/html/HTMLFormControlElement.cpp
index ae1ac62..2080d91 100644
--- a/WebCore/html/HTMLFormControlElement.cpp
+++ b/WebCore/html/HTMLFormControlElement.cpp
@@ -39,7 +39,6 @@
#include "HTMLFormElement.h"
#include "HTMLInputElement.h"
#include "HTMLNames.h"
-#include "LegacyHTMLTreeBuilder.h"
#include "LabelsNodeList.h"
#include "Page.h"
#include "RenderBox.h"
@@ -173,11 +172,7 @@ void HTMLFormControlElement::removedFromTree(bool deep)
{
// If the form and element are both in the same tree, preserve the connection to the form.
// Otherwise, null out our form and remove ourselves from the form's list of elements.
- LegacyHTMLTreeBuilder* treeBuilder = 0;
- if (DocumentParser* parser = document()->parser())
- treeBuilder = parser->htmlTreeBuilder();
-
- if (m_form && !(treeBuilder && treeBuilder->isHandlingResidualStyleAcrossBlocks()) && findRoot(this) != findRoot(m_form)) {
+ if (m_form && findRoot(this) != findRoot(m_form)) {
m_form->removeFormElement(this);
m_form = 0;
}
diff --git a/WebCore/html/HTMLFormControlElement.h b/WebCore/html/HTMLFormControlElement.h
index 02ea4e7..2352182 100644
--- a/WebCore/html/HTMLFormControlElement.h
+++ b/WebCore/html/HTMLFormControlElement.h
@@ -122,9 +122,6 @@ protected:
virtual bool recalcWillValidate() const;
private:
- virtual HTMLTagStatus endTagRequirement() const { return TagStatusRequired; }
- virtual int tagPriority() const { return 1; }
-
virtual const AtomicString& formControlName() const;
virtual const AtomicString& formControlType() const = 0;
diff --git a/WebCore/html/HTMLFormElement.cpp b/WebCore/html/HTMLFormElement.cpp
index d75de01..c53ea1d 100644
--- a/WebCore/html/HTMLFormElement.cpp
+++ b/WebCore/html/HTMLFormElement.cpp
@@ -529,7 +529,7 @@ void HTMLFormElement::addElementAlias(HTMLFormControlElement* element, const Ato
if (alias.isEmpty())
return;
if (!m_elementAliases)
- m_elementAliases.set(new AliasMap);
+ m_elementAliases = adoptPtr(new AliasMap);
m_elementAliases->set(alias.impl(), element);
}
diff --git a/WebCore/html/HTMLFormElement.h b/WebCore/html/HTMLFormElement.h
index c9fb9ac..151b2e8 100644
--- a/WebCore/html/HTMLFormElement.h
+++ b/WebCore/html/HTMLFormElement.h
@@ -114,9 +114,6 @@ public:
private:
HTMLFormElement(const QualifiedName&, Document*);
- virtual HTMLTagStatus endTagRequirement() const { return TagStatusRequired; }
- virtual int tagPriority() const { return 3; }
-
virtual bool rendererIsNeeded(RenderStyle*);
virtual void insertedIntoDocument();
virtual void removedFromDocument();
diff --git a/WebCore/html/HTMLFrameElement.h b/WebCore/html/HTMLFrameElement.h
index 3b1b5ad..d8cf509 100644
--- a/WebCore/html/HTMLFrameElement.h
+++ b/WebCore/html/HTMLFrameElement.h
@@ -39,9 +39,6 @@ public:
private:
HTMLFrameElement(const QualifiedName&, Document*);
- virtual HTMLTagStatus endTagRequirement() const { return TagStatusForbidden; }
- virtual int tagPriority() const { return 0; }
-
virtual void attach();
virtual bool rendererIsNeeded(RenderStyle*);
diff --git a/WebCore/html/HTMLFrameSetElement.cpp b/WebCore/html/HTMLFrameSetElement.cpp
index 09c153d..48c19a1 100644
--- a/WebCore/html/HTMLFrameSetElement.cpp
+++ b/WebCore/html/HTMLFrameSetElement.cpp
@@ -59,15 +59,6 @@ PassRefPtr<HTMLFrameSetElement> HTMLFrameSetElement::create(const QualifiedName&
return adoptRef(new HTMLFrameSetElement(tagName, document));
}
-bool HTMLFrameSetElement::checkDTD(const Node* newChild)
-{
- // FIXME: Old code had adjacent double returns and seemed to want to do something with NOFRAMES (but didn't).
- // What is the correct behavior?
- if (newChild->isTextNode())
- return static_cast<const Text*>(newChild)->containsOnlyWhitespace();
- return newChild->hasTagName(framesetTag) || newChild->hasTagName(frameTag);
-}
-
bool HTMLFrameSetElement::mapToEntry(const QualifiedName& attrName, MappedAttributeEntry& result) const
{
if (attrName == bordercolorAttr) {
diff --git a/WebCore/html/HTMLFrameSetElement.h b/WebCore/html/HTMLFrameSetElement.h
index a79793d..c761414 100644
--- a/WebCore/html/HTMLFrameSetElement.h
+++ b/WebCore/html/HTMLFrameSetElement.h
@@ -67,10 +67,6 @@ public:
private:
HTMLFrameSetElement(const QualifiedName&, Document*);
- virtual HTMLTagStatus endTagRequirement() const { return TagStatusRequired; }
- virtual int tagPriority() const { return 10; }
- virtual bool checkDTD(const Node* newChild);
-
virtual bool mapToEntry(const QualifiedName& attrName, MappedAttributeEntry& result) const;
virtual void parseMappedAttribute(Attribute*);
diff --git a/WebCore/html/HTMLHRElement.h b/WebCore/html/HTMLHRElement.h
index 3cfaabf..e86bb56 100644
--- a/WebCore/html/HTMLHRElement.h
+++ b/WebCore/html/HTMLHRElement.h
@@ -35,9 +35,6 @@ public:
private:
HTMLHRElement(const QualifiedName&, Document*);
- virtual HTMLTagStatus endTagRequirement() const { return TagStatusForbidden; }
- virtual int tagPriority() const { return 0; }
-
virtual bool mapToEntry(const QualifiedName&, MappedAttributeEntry&) const;
virtual void parseMappedAttribute(Attribute*);
};
diff --git a/WebCore/html/HTMLHeadElement.cpp b/WebCore/html/HTMLHeadElement.cpp
index c57cc2f..8218311 100644
--- a/WebCore/html/HTMLHeadElement.cpp
+++ b/WebCore/html/HTMLHeadElement.cpp
@@ -47,21 +47,4 @@ PassRefPtr<HTMLHeadElement> HTMLHeadElement::create(const QualifiedName& tagName
return adoptRef(new HTMLHeadElement(tagName, document));
}
-bool HTMLHeadElement::childAllowed(Node* newChild)
-{
- // Do not allow non-whitespace text nodes in the head
- if (newChild->isTextNode())
- return static_cast<Text*>(newChild)->containsOnlyWhitespace();
-
- return HTMLElement::childAllowed(newChild);
-}
-
-bool HTMLHeadElement::checkDTD(const Node* newChild)
-{
- return newChild->hasTagName(noscriptTag) || newChild->hasTagName(titleTag) || newChild->hasTagName(isindexTag) ||
- newChild->hasTagName(baseTag) || newChild->hasTagName(scriptTag) ||
- newChild->hasTagName(styleTag) || newChild->hasTagName(metaTag) ||
- newChild->hasTagName(linkTag) || newChild->isTextNode();
-}
-
}
diff --git a/WebCore/html/HTMLHeadElement.h b/WebCore/html/HTMLHeadElement.h
index c7cfc00..1a5df86 100644
--- a/WebCore/html/HTMLHeadElement.h
+++ b/WebCore/html/HTMLHeadElement.h
@@ -33,14 +33,8 @@ public:
static PassRefPtr<HTMLHeadElement> create(Document*);
static PassRefPtr<HTMLHeadElement> create(const QualifiedName&, Document*);
- virtual int tagPriority() const { return 10; }
-
private:
HTMLHeadElement(const QualifiedName&, Document*);
-
- virtual HTMLTagStatus endTagRequirement() const { return TagStatusOptional; }
- virtual bool childAllowed(Node* newChild);
- virtual bool checkDTD(const Node* newChild);
};
} // namespace
diff --git a/WebCore/html/HTMLHeadingElement.cpp b/WebCore/html/HTMLHeadingElement.cpp
index e2a0f73..47a9ea3 100644
--- a/WebCore/html/HTMLHeadingElement.cpp
+++ b/WebCore/html/HTMLHeadingElement.cpp
@@ -23,12 +23,8 @@
#include "config.h"
#include "HTMLHeadingElement.h"
-#include "HTMLNames.h"
-
namespace WebCore {
-using namespace HTMLNames;
-
inline HTMLHeadingElement::HTMLHeadingElement(const QualifiedName& tagName, Document* document)
: HTMLElement(tagName, document)
{
@@ -39,14 +35,4 @@ PassRefPtr<HTMLHeadingElement> HTMLHeadingElement::create(const QualifiedName& t
return adoptRef(new HTMLHeadingElement(tagName, document));
}
-bool HTMLHeadingElement::checkDTD(const Node* newChild)
-{
- if (newChild->hasTagName(h1Tag) || newChild->hasTagName(h2Tag) ||
- newChild->hasTagName(h3Tag) || newChild->hasTagName(h4Tag) ||
- newChild->hasTagName(h5Tag) || newChild->hasTagName(h6Tag))
- return false;
-
- return inEitherTagList(newChild);
-}
-
}
diff --git a/WebCore/html/HTMLHeadingElement.h b/WebCore/html/HTMLHeadingElement.h
index 575a05c..f09cfe3 100644
--- a/WebCore/html/HTMLHeadingElement.h
+++ b/WebCore/html/HTMLHeadingElement.h
@@ -33,10 +33,6 @@ public:
private:
HTMLHeadingElement(const QualifiedName&, Document*);
-
- virtual HTMLTagStatus endTagRequirement() const { return TagStatusRequired; }
- virtual int tagPriority() const { return 5; }
- virtual bool checkDTD(const Node* newChild);
};
} // namespace WebCore
diff --git a/WebCore/html/HTMLHtmlElement.cpp b/WebCore/html/HTMLHtmlElement.cpp
index 93edf6c..6205d10 100644
--- a/WebCore/html/HTMLHtmlElement.cpp
+++ b/WebCore/html/HTMLHtmlElement.cpp
@@ -50,12 +50,6 @@ PassRefPtr<HTMLHtmlElement> HTMLHtmlElement::create(const QualifiedName& tagName
return adoptRef(new HTMLHtmlElement(tagName, document));
}
-bool HTMLHtmlElement::checkDTD(const Node* newChild)
-{
- return newChild->hasTagName(headTag) || newChild->hasTagName(bodyTag) ||
- newChild->hasTagName(framesetTag) || newChild->hasTagName(noframesTag);
-}
-
#if ENABLE(OFFLINE_WEB_APPLICATIONS)
void HTMLHtmlElement::insertedIntoDocument()
{
diff --git a/WebCore/html/HTMLHtmlElement.h b/WebCore/html/HTMLHtmlElement.h
index 34879ed..e854fb1 100644
--- a/WebCore/html/HTMLHtmlElement.h
+++ b/WebCore/html/HTMLHtmlElement.h
@@ -36,10 +36,6 @@ public:
private:
HTMLHtmlElement(const QualifiedName&, Document*);
- virtual HTMLTagStatus endTagRequirement() const { return TagStatusRequired; }
- virtual int tagPriority() const { return 11; }
- virtual bool checkDTD(const Node* newChild);
-
#if ENABLE(OFFLINE_WEB_APPLICATIONS)
virtual void insertedIntoDocument();
#endif
diff --git a/WebCore/html/HTMLIFrameElement.h b/WebCore/html/HTMLIFrameElement.h
index 1d01c66..61cd6b6 100644
--- a/WebCore/html/HTMLIFrameElement.h
+++ b/WebCore/html/HTMLIFrameElement.h
@@ -35,9 +35,6 @@ public:
private:
HTMLIFrameElement(const QualifiedName&, Document*);
- virtual HTMLTagStatus endTagRequirement() const { return TagStatusRequired; }
- virtual int tagPriority() const { return 1; }
-
virtual bool mapToEntry(const QualifiedName&, MappedAttributeEntry&) const;
virtual void parseMappedAttribute(Attribute*);
diff --git a/WebCore/html/HTMLImageElement.h b/WebCore/html/HTMLImageElement.h
index 2b29570..7f38216 100644
--- a/WebCore/html/HTMLImageElement.h
+++ b/WebCore/html/HTMLImageElement.h
@@ -80,9 +80,6 @@ protected:
virtual void willMoveToNewOwnerDocument();
private:
- virtual HTMLTagStatus endTagRequirement() const { return TagStatusForbidden; }
- virtual int tagPriority() const { return 0; }
-
virtual bool mapToEntry(const QualifiedName& attrName, MappedAttributeEntry& result) const;
virtual void parseMappedAttribute(Attribute*);
diff --git a/WebCore/html/HTMLInputElement.cpp b/WebCore/html/HTMLInputElement.cpp
index 50b6ed0..f9c5162 100644
--- a/WebCore/html/HTMLInputElement.cpp
+++ b/WebCore/html/HTMLInputElement.cpp
@@ -50,7 +50,7 @@
#include "HTMLImageLoader.h"
#include "HTMLNames.h"
#include "HTMLOptionElement.h"
-#include "LegacyHTMLTreeBuilder.h"
+#include "HTMLTreeBuilder.h"
#include "KeyboardEvent.h"
#include "LocalizedStrings.h"
#include "MouseEvent.h"
@@ -746,9 +746,9 @@ void HTMLInputElement::setType(const String& t)
}
typedef HashMap<String, HTMLInputElement::InputType, CaseFoldingHash> InputTypeMap;
-static const InputTypeMap* createTypeMap()
+static PassOwnPtr<InputTypeMap> createTypeMap()
{
- InputTypeMap* map = new InputTypeMap;
+ OwnPtr<InputTypeMap> map = adoptPtr(new InputTypeMap);
map->add("button", HTMLInputElement::BUTTON);
map->add("checkbox", HTMLInputElement::CHECKBOX);
map->add("color", HTMLInputElement::COLOR);
@@ -773,12 +773,12 @@ static const InputTypeMap* createTypeMap()
map->add("url", HTMLInputElement::URL);
map->add("week", HTMLInputElement::WEEK);
// No need to register "text" because it is the default type.
- return map;
+ return map.release();
}
void HTMLInputElement::setInputType(const String& t)
{
- static const InputTypeMap* typeMap = createTypeMap();
+ static const InputTypeMap* typeMap = createTypeMap().leakPtr();
InputType newType = t.isNull() ? TEXT : typeMap->get(t);
#ifdef ANDROID_ACCEPT_CHANGES_TO_FOCUSED_TEXTFIELDS
if (newType == PASSWORD && document()->focusedNode() == this)
@@ -1089,7 +1089,7 @@ void HTMLInputElement::parseMappedAttribute(Attribute* attr)
} else if (attr->name() == srcAttr) {
if (renderer() && inputType() == IMAGE) {
if (!m_imageLoader)
- m_imageLoader.set(new HTMLImageLoader(this));
+ m_imageLoader = adoptPtr(new HTMLImageLoader(this));
m_imageLoader->updateFromElementIgnoringPreviousError();
}
} else if (attr->name() == usemapAttr || attr->name() == accesskeyAttr) {
@@ -1212,7 +1212,7 @@ void HTMLInputElement::attach()
if (inputType() == IMAGE) {
if (!m_imageLoader)
- m_imageLoader.set(new HTMLImageLoader(this));
+ m_imageLoader = adoptPtr(new HTMLImageLoader(this));
m_imageLoader->updateFromElement();
if (renderer() && m_imageLoader->haveFiredBeforeLoadEvent()) {
RenderImage* imageObj = toRenderImage(renderer());
@@ -2059,7 +2059,7 @@ void* HTMLInputElement::preDispatchEventHandler(Event *evt)
if ((inputType() == CHECKBOX || inputType() == RADIO) && evt->isMouseEvent()
&& evt->type() == eventNames().clickEvent && static_cast<MouseEvent*>(evt)->button() == LeftButton) {
- EventHandlingState* state = new EventHandlingState(indeterminate(), checked());
+ OwnPtr<EventHandlingState> state = adoptPtr(new EventHandlingState(indeterminate(), checked()));
if (inputType() == CHECKBOX) {
if (indeterminate())
@@ -2081,7 +2081,7 @@ void* HTMLInputElement::preDispatchEventHandler(Event *evt)
setIndeterminate(false);
setChecked(true, true);
}
- result = state;
+ result = state.leakPtr(); // FIXME: Check whether this actually ends up leaking.
}
return result;
}
diff --git a/WebCore/html/HTMLInputElement.h b/WebCore/html/HTMLInputElement.h
index 18cbaa4..e6cdda3 100644
--- a/WebCore/html/HTMLInputElement.h
+++ b/WebCore/html/HTMLInputElement.h
@@ -218,9 +218,6 @@ private:
virtual void willMoveToNewOwnerDocument();
virtual void didMoveToNewOwnerDocument();
- virtual HTMLTagStatus endTagRequirement() const { return TagStatusForbidden; }
- virtual int tagPriority() const { return 0; }
-
virtual bool isKeyboardFocusable(KeyboardEvent*) const;
virtual bool isMouseFocusable() const;
virtual bool isEnumeratable() const { return inputType() != IMAGE; }
diff --git a/WebCore/html/HTMLIsIndexElement.h b/WebCore/html/HTMLIsIndexElement.h
index 8c33d71..857ef75 100644
--- a/WebCore/html/HTMLIsIndexElement.h
+++ b/WebCore/html/HTMLIsIndexElement.h
@@ -36,8 +36,6 @@ public:
private:
HTMLIsIndexElement(const QualifiedName&, Document*, HTMLFormElement*);
- virtual HTMLTagStatus endTagRequirement() const { return TagStatusForbidden; }
- virtual int tagPriority() const { return 0; }
virtual bool canTriggerImplicitSubmission() const { return true; }
virtual void parseMappedAttribute(Attribute*);
diff --git a/WebCore/html/HTMLKeygenElement.cpp b/WebCore/html/HTMLKeygenElement.cpp
index 5185f51..881a0a8 100644
--- a/WebCore/html/HTMLKeygenElement.cpp
+++ b/WebCore/html/HTMLKeygenElement.cpp
@@ -45,13 +45,14 @@ inline HTMLKeygenElement::HTMLKeygenElement(const QualifiedName& tagName, Docume
{
ASSERT(hasTagName(keygenTag));
+ // FIXME: This markup should go in the shadow tree.
// Add one option element for each key size.
Vector<String> keys;
getSupportedKeySizes(keys);
for (size_t i = 0; i < keys.size(); ++i) {
RefPtr<HTMLOptionElement> option = HTMLOptionElement::create(document, this->form());
- legacyParserAddChild(option);
- option->legacyParserAddChild(Text::create(document, keys[i]));
+ parserAddChild(option);
+ option->parserAddChild(Text::create(document, keys[i]));
}
}
diff --git a/WebCore/html/HTMLKeygenElement.h b/WebCore/html/HTMLKeygenElement.h
index baa9a17..4c08014 100644
--- a/WebCore/html/HTMLKeygenElement.h
+++ b/WebCore/html/HTMLKeygenElement.h
@@ -35,7 +35,6 @@ public:
private:
HTMLKeygenElement(const QualifiedName&, Document*, HTMLFormElement*);
- virtual int tagPriority() const { return 0; }
virtual const AtomicString& formControlType() const;
virtual bool isEnumeratable() const { return false; }
virtual void parseMappedAttribute(Attribute*);
diff --git a/WebCore/html/HTMLLIElement.h b/WebCore/html/HTMLLIElement.h
index 418f7a4..ad12b67 100644
--- a/WebCore/html/HTMLLIElement.h
+++ b/WebCore/html/HTMLLIElement.h
@@ -35,9 +35,6 @@ public:
private:
HTMLLIElement(const QualifiedName&, Document*);
- virtual HTMLTagStatus endTagRequirement() const { return TagStatusOptional; }
- virtual int tagPriority() const { return 3; }
-
virtual bool mapToEntry(const QualifiedName&, MappedAttributeEntry&) const;
virtual void parseMappedAttribute(Attribute*);
diff --git a/WebCore/html/HTMLLabelElement.h b/WebCore/html/HTMLLabelElement.h
index 7964ade..2b09e17 100644
--- a/WebCore/html/HTMLLabelElement.h
+++ b/WebCore/html/HTMLLabelElement.h
@@ -38,8 +38,6 @@ public:
private:
HTMLLabelElement(const QualifiedName&, Document*);
- virtual int tagPriority() const { return 5; }
-
virtual bool isFocusable() const;
virtual void accessKeyAction(bool sendToAnyElement);
diff --git a/WebCore/html/HTMLLinkElement.h b/WebCore/html/HTMLLinkElement.h
index 6d7643a..aec971b 100644
--- a/WebCore/html/HTMLLinkElement.h
+++ b/WebCore/html/HTMLLinkElement.h
@@ -79,9 +79,6 @@ public:
bool isIcon() const { return m_relAttribute.m_isIcon; }
private:
- virtual HTMLTagStatus endTagRequirement() const { return TagStatusForbidden; }
- virtual int tagPriority() const { return 0; }
-
virtual void parseMappedAttribute(Attribute*);
void process();
diff --git a/WebCore/html/HTMLMapElement.cpp b/WebCore/html/HTMLMapElement.cpp
index eba23ca..873a9ab 100644
--- a/WebCore/html/HTMLMapElement.cpp
+++ b/WebCore/html/HTMLMapElement.cpp
@@ -58,12 +58,6 @@ HTMLMapElement::~HTMLMapElement()
{
}
-bool HTMLMapElement::checkDTD(const Node* newChild)
-{
- return inEitherTagList(newChild) || newChild->hasTagName(areaTag) // HTML 4 DTD
- || newChild->hasTagName(scriptTag); // extensions
-}
-
bool HTMLMapElement::mapMouseEvent(int x, int y, const IntSize& size, HitTestResult& result)
{
HTMLAreaElement* defaultArea = 0;
diff --git a/WebCore/html/HTMLMapElement.h b/WebCore/html/HTMLMapElement.h
index 1394c95..c0c1395 100644
--- a/WebCore/html/HTMLMapElement.h
+++ b/WebCore/html/HTMLMapElement.h
@@ -47,10 +47,6 @@ public:
private:
HTMLMapElement(const QualifiedName&, Document*);
- virtual HTMLTagStatus endTagRequirement() const { return TagStatusRequired; }
- virtual int tagPriority() const { return 1; }
- virtual bool checkDTD(const Node*);
-
virtual void parseMappedAttribute(Attribute*);
virtual void insertedIntoDocument();
diff --git a/WebCore/html/HTMLMarqueeElement.h b/WebCore/html/HTMLMarqueeElement.h
index 4932d46..1b3229a 100644
--- a/WebCore/html/HTMLMarqueeElement.h
+++ b/WebCore/html/HTMLMarqueeElement.h
@@ -43,9 +43,6 @@ public:
private:
HTMLMarqueeElement(const QualifiedName&, Document*);
-
- virtual HTMLTagStatus endTagRequirement() const { return TagStatusRequired; }
- virtual int tagPriority() const { return 3; }
virtual bool mapToEntry(const QualifiedName&, MappedAttributeEntry&) const;
virtual void parseMappedAttribute(Attribute*);
diff --git a/WebCore/html/HTMLMediaElement.cpp b/WebCore/html/HTMLMediaElement.cpp
index 13b7807..751735d 100644
--- a/WebCore/html/HTMLMediaElement.cpp
+++ b/WebCore/html/HTMLMediaElement.cpp
@@ -162,12 +162,6 @@ void HTMLMediaElement::didMoveToNewOwnerDocument()
HTMLElement::didMoveToNewOwnerDocument();
}
-
-bool HTMLMediaElement::checkDTD(const Node* newChild)
-{
- return newChild->hasTagName(sourceTag) || HTMLElement::checkDTD(newChild);
-}
-
void HTMLMediaElement::attributeChanged(Attribute* attr, bool preserveDecls)
{
HTMLElement::attributeChanged(attr, preserveDecls);
diff --git a/WebCore/html/HTMLMediaElement.h b/WebCore/html/HTMLMediaElement.h
index a73abba..4706178 100644
--- a/WebCore/html/HTMLMediaElement.h
+++ b/WebCore/html/HTMLMediaElement.h
@@ -183,7 +183,6 @@ protected:
virtual void setDisplayMode(DisplayMode mode) { m_displayMode = mode; }
private:
- virtual bool checkDTD(const Node* newChild);
virtual void attributeChanged(Attribute*, bool preserveDecls);
virtual bool rendererIsNeeded(RenderStyle*);
virtual RenderObject* createRenderer(RenderArena*, RenderStyle*);
diff --git a/WebCore/html/HTMLMenuElement.h b/WebCore/html/HTMLMenuElement.h
index 002df00..6b588ec 100644
--- a/WebCore/html/HTMLMenuElement.h
+++ b/WebCore/html/HTMLMenuElement.h
@@ -33,9 +33,6 @@ public:
private:
HTMLMenuElement(const QualifiedName&, Document*);
-
- virtual HTMLTagStatus endTagRequirement() const { return TagStatusRequired; }
- virtual int tagPriority() const { return 5; }
};
} //namespace
diff --git a/WebCore/html/HTMLMetaElement.h b/WebCore/html/HTMLMetaElement.h
index 6af7483..9b0178e 100644
--- a/WebCore/html/HTMLMetaElement.h
+++ b/WebCore/html/HTMLMetaElement.h
@@ -38,9 +38,6 @@ public:
private:
HTMLMetaElement(const QualifiedName&, Document*);
- virtual HTMLTagStatus endTagRequirement() const { return TagStatusForbidden; }
- virtual int tagPriority() const { return 0; }
-
virtual void parseMappedAttribute(Attribute*);
virtual void insertedIntoDocument();
diff --git a/WebCore/html/HTMLMeterElement.cpp b/WebCore/html/HTMLMeterElement.cpp
index 7c025f7..aaba125 100644
--- a/WebCore/html/HTMLMeterElement.cpp
+++ b/WebCore/html/HTMLMeterElement.cpp
@@ -28,7 +28,7 @@
#include "FormDataList.h"
#include "HTMLFormElement.h"
#include "HTMLNames.h"
-#include "LegacyHTMLTreeBuilder.h"
+#include "HTMLTreeBuilder.h"
#include "RenderMeter.h"
#include <wtf/StdLibExtras.h>
diff --git a/WebCore/html/HTMLModElement.h b/WebCore/html/HTMLModElement.h
index 7370320..2b09e21 100644
--- a/WebCore/html/HTMLModElement.h
+++ b/WebCore/html/HTMLModElement.h
@@ -34,9 +34,6 @@ public:
private:
HTMLModElement(const QualifiedName&, Document*);
-
- virtual HTMLTagStatus endTagRequirement() const { return TagStatusRequired; }
- virtual int tagPriority() const { return 1; }
};
} //namespace
diff --git a/WebCore/html/HTMLNoScriptElement.cpp b/WebCore/html/HTMLNoScriptElement.cpp
index f232340..5bba16f 100644
--- a/WebCore/html/HTMLNoScriptElement.cpp
+++ b/WebCore/html/HTMLNoScriptElement.cpp
@@ -42,11 +42,6 @@ PassRefPtr<HTMLNoScriptElement> HTMLNoScriptElement::create(const QualifiedName&
return adoptRef(new HTMLNoScriptElement(tagName, document));
}
-bool HTMLNoScriptElement::checkDTD(const Node* newChild)
-{
- return newChild->isTextNode() || inBlockTagList(newChild);
-}
-
void HTMLNoScriptElement::attach()
{
HTMLElement::attach();
diff --git a/WebCore/html/HTMLNoScriptElement.h b/WebCore/html/HTMLNoScriptElement.h
index 8b98205..9a3b92d 100644
--- a/WebCore/html/HTMLNoScriptElement.h
+++ b/WebCore/html/HTMLNoScriptElement.h
@@ -34,7 +34,6 @@ public:
private:
HTMLNoScriptElement(const QualifiedName&, Document*);
- virtual bool checkDTD(const Node*);
virtual void attach();
virtual void recalcStyle(StyleChange);
virtual bool childShouldCreateRenderer(Node*) const;
diff --git a/WebCore/html/HTMLOListElement.h b/WebCore/html/HTMLOListElement.h
index 3067138..179fec0 100644
--- a/WebCore/html/HTMLOListElement.h
+++ b/WebCore/html/HTMLOListElement.h
@@ -38,9 +38,6 @@ public:
private:
HTMLOListElement(const QualifiedName&, Document*);
- virtual HTMLTagStatus endTagRequirement() const { return TagStatusRequired; }
- virtual int tagPriority() const { return 5; }
-
virtual bool mapToEntry(const QualifiedName&, MappedAttributeEntry&) const;
virtual void parseMappedAttribute(Attribute*);
diff --git a/WebCore/html/HTMLObjectElement.cpp b/WebCore/html/HTMLObjectElement.cpp
index 5989ec7..de1ed91 100644
--- a/WebCore/html/HTMLObjectElement.cpp
+++ b/WebCore/html/HTMLObjectElement.cpp
@@ -86,7 +86,7 @@ void HTMLObjectElement::parseMappedAttribute(Attribute* attr)
m_needWidgetUpdate = true;
if (renderer() && isImageType()) {
if (!m_imageLoader)
- m_imageLoader.set(new HTMLImageLoader(this));
+ m_imageLoader = adoptPtr(new HTMLImageLoader(this));
m_imageLoader->updateFromElementIgnoringPreviousError();
}
} else if (attr->name() == classidAttr) {
@@ -152,7 +152,7 @@ void HTMLObjectElement::attach()
if (isImage && renderer() && !m_useFallbackContent) {
if (!m_imageLoader)
- m_imageLoader.set(new HTMLImageLoader(this));
+ m_imageLoader = adoptPtr(new HTMLImageLoader(this));
m_imageLoader->updateFromElement();
}
}
@@ -262,6 +262,32 @@ void HTMLObjectElement::renderFallbackContent()
attach();
}
+// FIXME: This should be removed, all callers are almost certainly wrong.
+static bool isRecognizedTagName(const QualifiedName& tagName)
+{
+ DEFINE_STATIC_LOCAL(HashSet<AtomicStringImpl*>, tagList, ());
+ if (tagList.isEmpty()) {
+ size_t tagCount = 0;
+ QualifiedName** tags = HTMLNames::getHTMLTags(&tagCount);
+ for (size_t i = 0; i < tagCount; i++) {
+ if (*tags[i] == bgsoundTag
+ || *tags[i] == commandTag
+ || *tags[i] == detailsTag
+ || *tags[i] == figcaptionTag
+ || *tags[i] == figureTag
+ || *tags[i] == summaryTag
+ || *tags[i] == trackTag) {
+ // Even though we have atoms for these tags, we don't want to
+ // treat them as "recognized tags" for the purpose of parsing
+ // because that changes how we parse documents.
+ continue;
+ }
+ tagList.add(tags[i]->localName().impl());
+ }
+ }
+ return tagList.contains(tagName.localName().impl());
+}
+
void HTMLObjectElement::updateDocNamedItem()
{
// The rule is "<object> elements with no children other than
@@ -273,7 +299,8 @@ void HTMLObjectElement::updateDocNamedItem()
while (child && isNamedItem) {
if (child->isElementNode()) {
Element* element = static_cast<Element*>(child);
- if (HTMLElement::isRecognizedTagName(element->tagQName()) && !element->hasTagName(paramTag))
+ // FIXME: Use of isRecognizedTagName is almost certainly wrong here.
+ if (isRecognizedTagName(element->tagQName()) && !element->hasTagName(paramTag))
isNamedItem = false;
} else if (child->isTextNode()) {
if (!static_cast<Text*>(child)->containsOnlyWhitespace())
diff --git a/WebCore/html/HTMLObjectElement.h b/WebCore/html/HTMLObjectElement.h
index c904c74..8dc59be 100644
--- a/WebCore/html/HTMLObjectElement.h
+++ b/WebCore/html/HTMLObjectElement.h
@@ -44,8 +44,6 @@ public:
private:
HTMLObjectElement(const QualifiedName&, Document*, bool createdByParser);
- virtual int tagPriority() const { return 5; }
-
virtual void parseMappedAttribute(Attribute*);
virtual void attach();
diff --git a/WebCore/html/HTMLOptGroupElement.cpp b/WebCore/html/HTMLOptGroupElement.cpp
index 7db0924..091e0f2 100644
--- a/WebCore/html/HTMLOptGroupElement.cpp
+++ b/WebCore/html/HTMLOptGroupElement.cpp
@@ -86,12 +86,6 @@ void HTMLOptGroupElement::recalcSelectOptions()
static_cast<HTMLSelectElement*>(select)->setRecalcListItems();
}
-bool HTMLOptGroupElement::checkDTD(const Node* newChild)
-{
- // Make sure to keep this in sync with <select> (other than not allowing an optgroup).
- return newChild->isTextNode() || newChild->hasTagName(HTMLNames::optionTag) || newChild->hasTagName(HTMLNames::hrTag) || newChild->hasTagName(HTMLNames::scriptTag);
-}
-
void HTMLOptGroupElement::attach()
{
if (parentNode()->renderStyle())
diff --git a/WebCore/html/HTMLOptGroupElement.h b/WebCore/html/HTMLOptGroupElement.h
index 095b9d2..a58e957 100644
--- a/WebCore/html/HTMLOptGroupElement.h
+++ b/WebCore/html/HTMLOptGroupElement.h
@@ -42,7 +42,6 @@ public:
private:
HTMLOptGroupElement(const QualifiedName&, Document*, HTMLFormElement*);
- virtual bool checkDTD(const Node*);
virtual const AtomicString& formControlType() const;
virtual bool supportsFocus() const;
virtual bool isFocusable() const;
diff --git a/WebCore/html/HTMLOptionElement.cpp b/WebCore/html/HTMLOptionElement.cpp
index 19f40be..3bf522c 100644
--- a/WebCore/html/HTMLOptionElement.cpp
+++ b/WebCore/html/HTMLOptionElement.cpp
@@ -78,11 +78,6 @@ PassRefPtr<HTMLOptionElement> HTMLOptionElement::createForJSConstructor(Document
return element.release();
}
-bool HTMLOptionElement::checkDTD(const Node* newChild)
-{
- return newChild->isTextNode() || newChild->hasTagName(scriptTag);
-}
-
void HTMLOptionElement::attach()
{
if (parentNode()->renderStyle())
diff --git a/WebCore/html/HTMLOptionElement.h b/WebCore/html/HTMLOptionElement.h
index d0ff23b..deac66a 100644
--- a/WebCore/html/HTMLOptionElement.h
+++ b/WebCore/html/HTMLOptionElement.h
@@ -78,9 +78,6 @@ public:
private:
HTMLOptionElement(const QualifiedName&, Document*, HTMLFormElement* = 0);
- virtual HTMLTagStatus endTagRequirement() const { return TagStatusOptional; }
- virtual int tagPriority() const { return 2; }
- virtual bool checkDTD(const Node* newChild);
virtual bool supportsFocus() const;
virtual bool isFocusable() const;
virtual bool rendererIsNeeded(RenderStyle*) { return false; }
diff --git a/WebCore/html/HTMLParagraphElement.cpp b/WebCore/html/HTMLParagraphElement.cpp
index 4af5b77..0b3e83f 100644
--- a/WebCore/html/HTMLParagraphElement.cpp
+++ b/WebCore/html/HTMLParagraphElement.cpp
@@ -44,11 +44,6 @@ PassRefPtr<HTMLParagraphElement> HTMLParagraphElement::create(const QualifiedNam
return adoptRef(new HTMLParagraphElement(tagName, document));
}
-bool HTMLParagraphElement::checkDTD(const Node* newChild)
-{
- return inInlineTagList(newChild) || (document()->inCompatMode() && newChild->hasTagName(tableTag));
-}
-
bool HTMLParagraphElement::mapToEntry(const QualifiedName& attrName, MappedAttributeEntry& result) const
{
if (attrName == alignAttr) {
diff --git a/WebCore/html/HTMLParagraphElement.h b/WebCore/html/HTMLParagraphElement.h
index 0a31a1c..6dbf071 100644
--- a/WebCore/html/HTMLParagraphElement.h
+++ b/WebCore/html/HTMLParagraphElement.h
@@ -34,10 +34,6 @@ public:
private:
HTMLParagraphElement(const QualifiedName&, Document*);
- virtual HTMLTagStatus endTagRequirement() const { return TagStatusRequired; }
- virtual int tagPriority() const { return 3; }
- virtual bool checkDTD(const Node* newChild);
-
virtual bool mapToEntry(const QualifiedName&, MappedAttributeEntry&) const;
virtual void parseMappedAttribute(Attribute*);
};
diff --git a/WebCore/html/HTMLParamElement.h b/WebCore/html/HTMLParamElement.h
index a787927..f13f8fa 100644
--- a/WebCore/html/HTMLParamElement.h
+++ b/WebCore/html/HTMLParamElement.h
@@ -37,20 +37,18 @@ public:
private:
HTMLParamElement(const QualifiedName&, Document*);
- virtual HTMLTagStatus endTagRequirement() const { return TagStatusForbidden; }
- virtual int tagPriority() const { return 0; }
-
virtual void parseMappedAttribute(Attribute*);
virtual bool isURLAttribute(Attribute*) const;
virtual void addSubresourceAttributeURLs(ListHashSet<KURL>&) const;
+ // FIXME: These don't need to be stored as members and instead
+ // name() value() could use getAttribute(nameAttr/valueAttr).
AtomicString m_name;
AtomicString m_value;
};
-
-}
+} // namespace WebCore
#endif
diff --git a/WebCore/html/HTMLParserScheduler.h b/WebCore/html/HTMLParserScheduler.h
index 1ea2c65..5be33b0 100644
--- a/WebCore/html/HTMLParserScheduler.h
+++ b/WebCore/html/HTMLParserScheduler.h
@@ -29,6 +29,7 @@
#include "Timer.h"
#include <wtf/CurrentTime.h>
#include <wtf/Noncopyable.h>
+#include <wtf/PassOwnPtr.h>
namespace WebCore {
@@ -36,7 +37,10 @@ class HTMLDocumentParser;
class HTMLParserScheduler : public Noncopyable {
public:
- HTMLParserScheduler(HTMLDocumentParser*);
+ static PassOwnPtr<HTMLParserScheduler> create(HTMLDocumentParser* parser)
+ {
+ return adoptPtr(new HTMLParserScheduler(parser));
+ }
~HTMLParserScheduler();
struct PumpSession {
@@ -70,6 +74,8 @@ public:
bool isScheduledForResume() const { return m_continueNextChunkTimer.isActive(); }
private:
+ HTMLParserScheduler(HTMLDocumentParser*);
+
void continueNextChunkTimerFired(Timer<HTMLParserScheduler>*);
HTMLDocumentParser* m_parser;
diff --git a/WebCore/html/HTMLPlugInElement.cpp b/WebCore/html/HTMLPlugInElement.cpp
index 2ce44a6..9f479fb 100644
--- a/WebCore/html/HTMLPlugInElement.cpp
+++ b/WebCore/html/HTMLPlugInElement.cpp
@@ -143,11 +143,6 @@ void HTMLPlugInElement::parseMappedAttribute(Attribute* attr)
HTMLFrameOwnerElement::parseMappedAttribute(attr);
}
-bool HTMLPlugInElement::checkDTD(const Node* newChild)
-{
- return newChild->hasTagName(paramTag) || HTMLFrameOwnerElement::checkDTD(newChild);
-}
-
void HTMLPlugInElement::defaultEventHandler(Event* event)
{
// Firefox seems to use a fake event listener to dispatch events to plug-in (tested with mouse events only).
diff --git a/WebCore/html/HTMLPlugInElement.h b/WebCore/html/HTMLPlugInElement.h
index 6288e74..eadf38a 100644
--- a/WebCore/html/HTMLPlugInElement.h
+++ b/WebCore/html/HTMLPlugInElement.h
@@ -71,9 +71,6 @@ private:
virtual RenderWidget* renderWidgetForJSBindings() const = 0;
- virtual HTMLTagStatus endTagRequirement() const { return TagStatusRequired; }
- virtual bool checkDTD(const Node* newChild);
-
virtual void updateWidget() { }
protected:
diff --git a/WebCore/html/HTMLPreElement.h b/WebCore/html/HTMLPreElement.h
index 1a67c65..3ccdb86 100644
--- a/WebCore/html/HTMLPreElement.h
+++ b/WebCore/html/HTMLPreElement.h
@@ -34,9 +34,6 @@ public:
private:
HTMLPreElement(const QualifiedName&, Document*);
- virtual HTMLTagStatus endTagRequirement() const { return TagStatusRequired; }
- virtual int tagPriority() const { return 5; }
-
virtual bool mapToEntry(const QualifiedName&, MappedAttributeEntry&) const;
virtual void parseMappedAttribute(Attribute*);
};
diff --git a/WebCore/html/HTMLPreloadScanner.cpp b/WebCore/html/HTMLPreloadScanner.cpp
index 57ac408..7aafd90 100644
--- a/WebCore/html/HTMLPreloadScanner.cpp
+++ b/WebCore/html/HTMLPreloadScanner.cpp
@@ -31,6 +31,7 @@
#include "CSSHelper.h"
#include "DocLoader.h"
#include "Document.h"
+#include "HTMLTokenizer.h"
#include "HTMLTreeBuilder.h"
#include "HTMLLinkElement.h"
#include "HTMLNames.h"
@@ -120,6 +121,7 @@ private:
HTMLPreloadScanner::HTMLPreloadScanner(Document* document)
: m_document(document)
, m_cssScanner(document)
+ , m_tokenizer(HTMLTokenizer::create())
, m_bodySeen(false)
, m_inStyle(false)
{
@@ -134,7 +136,7 @@ void HTMLPreloadScanner::scan()
{
// FIXME: We should save and re-use these tokens in HTMLDocumentParser if
// the pending script doesn't end up calling document.write.
- while (m_tokenizer.nextToken(m_source, m_token)) {
+ while (m_tokenizer->nextToken(m_source, m_token)) {
processToken();
m_token.clear();
}
@@ -155,12 +157,12 @@ void HTMLPreloadScanner::processToken()
return;
PreloadTask task(m_token);
- m_tokenizer.setState(HTMLTreeBuilder::adjustedLexerState(m_tokenizer.state(), task.tagName(), m_document->frame()));
+ m_tokenizer->setState(HTMLTreeBuilder::adjustedLexerState(m_tokenizer->state(), task.tagName(), m_document->frame()));
if (task.tagName() == scriptTag) {
// The tree builder handles scriptTag separately from the other tokenizer
// state adjustments, so we need to handle it separately too.
- ASSERT(m_tokenizer.state() == HTMLTokenizer::DataState);
- m_tokenizer.setState(HTMLTokenizer::ScriptDataState);
+ ASSERT(m_tokenizer->state() == HTMLTokenizer::DataState);
+ m_tokenizer->setState(HTMLTokenizer::ScriptDataState);
}
if (task.tagName() == bodyTag)
diff --git a/WebCore/html/HTMLPreloadScanner.h b/WebCore/html/HTMLPreloadScanner.h
index ee49ee0..94a90e6 100644
--- a/WebCore/html/HTMLPreloadScanner.h
+++ b/WebCore/html/HTMLPreloadScanner.h
@@ -28,7 +28,6 @@
#define HTMLPreloadScanner_h
#include "CSSPreloadScanner.h"
-#include "HTMLTokenizer.h"
#include "HTMLToken.h"
#include "SegmentedString.h"
#include <wtf/Noncopyable.h>
@@ -37,6 +36,7 @@ namespace WebCore {
class Document;
class HTMLToken;
+class HTMLTokenizer;
class SegmentedString;
class HTMLPreloadScanner : public Noncopyable {
@@ -52,9 +52,9 @@ private:
Document* m_document;
SegmentedString m_source;
- HTMLTokenizer m_tokenizer;
- HTMLToken m_token;
CSSPreloadScanner m_cssScanner;
+ OwnPtr<HTMLTokenizer> m_tokenizer;
+ HTMLToken m_token;
bool m_bodySeen;
bool m_inStyle;
};
diff --git a/WebCore/html/HTMLProgressElement.cpp b/WebCore/html/HTMLProgressElement.cpp
index 5cf7714..de65fcb 100644
--- a/WebCore/html/HTMLProgressElement.cpp
+++ b/WebCore/html/HTMLProgressElement.cpp
@@ -28,7 +28,7 @@
#include "FormDataList.h"
#include "HTMLFormElement.h"
#include "HTMLNames.h"
-#include "LegacyHTMLTreeBuilder.h"
+#include "HTMLTreeBuilder.h"
#include "RenderProgress.h"
#include <wtf/StdLibExtras.h>
diff --git a/WebCore/html/HTMLQuoteElement.h b/WebCore/html/HTMLQuoteElement.h
index 9261da6..225dde8 100644
--- a/WebCore/html/HTMLQuoteElement.h
+++ b/WebCore/html/HTMLQuoteElement.h
@@ -36,9 +36,6 @@ public:
private:
HTMLQuoteElement(const QualifiedName&, Document*);
- virtual HTMLTagStatus endTagRequirement() const { return TagStatusRequired; }
- virtual int tagPriority() const { return 1; }
-
virtual void insertedIntoDocument();
};
diff --git a/WebCore/html/HTMLScriptElement.h b/WebCore/html/HTMLScriptElement.h
index b18278d..a5629ee 100644
--- a/WebCore/html/HTMLScriptElement.h
+++ b/WebCore/html/HTMLScriptElement.h
@@ -49,10 +49,6 @@ private:
virtual String scriptContent() const;
- virtual HTMLTagStatus endTagRequirement() const { return TagStatusRequired; }
- virtual int tagPriority() const { return 1; }
- virtual bool checkDTD(const Node* newChild) { return newChild->isTextNode(); }
-
virtual void parseMappedAttribute(Attribute*);
virtual void insertedIntoDocument();
virtual void removedFromDocument();
diff --git a/WebCore/html/HTMLScriptRunner.cpp b/WebCore/html/HTMLScriptRunner.cpp
index 0d603ed..6d470a0 100644
--- a/WebCore/html/HTMLScriptRunner.cpp
+++ b/WebCore/html/HTMLScriptRunner.cpp
@@ -77,6 +77,11 @@ HTMLScriptRunner::~HTMLScriptRunner()
stopWatchingForLoad(m_parsingBlockingScript);
}
+void HTMLScriptRunner::detach()
+{
+ m_document = 0;
+}
+
static KURL documentURLForScriptExecution(Document* document)
{
if (!document || !document->frame())
@@ -119,6 +124,7 @@ bool HTMLScriptRunner::isPendingScriptReady(const PendingScript& script)
void HTMLScriptRunner::executeParsingBlockingScript()
{
+ ASSERT(m_document);
ASSERT(!m_scriptNestingLevel);
ASSERT(m_document->haveStylesheetsLoaded());
ASSERT(isPendingScriptReady(m_parsingBlockingScript));
@@ -152,6 +158,7 @@ void HTMLScriptRunner::executePendingScriptAndDispatchEvent(PendingScript& pendi
void HTMLScriptRunner::executeScript(Element* element, const ScriptSourceCode& sourceCode) const
{
+ ASSERT(m_document);
ScriptElement* scriptElement = toScriptElement(element);
ASSERT(scriptElement);
if (!scriptElement->shouldExecuteAsJavaScript())
@@ -222,6 +229,7 @@ bool HTMLScriptRunner::executeScriptsWaitingForLoad(CachedResource* cachedScript
bool HTMLScriptRunner::executeScriptsWaitingForStylesheets()
{
+ ASSERT(m_document);
// Callers should check hasScriptsWaitingForStylesheets() before calling
// to prevent parser or script re-entry during </style> parsing.
ASSERT(hasScriptsWaitingForStylesheets());
@@ -269,6 +277,7 @@ bool HTMLScriptRunner::requestPendingScript(PendingScript& pendingScript, Elemen
// http://www.whatwg.org/specs/web-apps/current-work/multipage/scripting-1.html#running-a-script
void HTMLScriptRunner::runScript(Element* script, int startingLineNumber)
{
+ ASSERT(m_document);
ASSERT(!haveParsingBlockingScript());
{
InsertionPointRecord insertionPointRecord(m_host->inputStream());
diff --git a/WebCore/html/HTMLScriptRunner.h b/WebCore/html/HTMLScriptRunner.h
index 981d433..ead9289 100644
--- a/WebCore/html/HTMLScriptRunner.h
+++ b/WebCore/html/HTMLScriptRunner.h
@@ -42,9 +42,14 @@ class ScriptSourceCode;
class HTMLScriptRunner : public Noncopyable {
public:
- HTMLScriptRunner(Document*, HTMLScriptRunnerHost*);
+ static PassOwnPtr<HTMLScriptRunner> create(Document* document, HTMLScriptRunnerHost* host)
+ {
+ return adoptPtr(new HTMLScriptRunner(document, host));
+ }
~HTMLScriptRunner();
+ void detach();
+
// Processes the passed in script and any pending scripts if possible.
bool execute(PassRefPtr<Element> scriptToProcess, int scriptStartLine);
@@ -55,6 +60,8 @@ public:
bool isExecutingScript() const { return !!m_scriptNestingLevel; }
private:
+ HTMLScriptRunner(Document*, HTMLScriptRunnerHost*);
+
Frame* frame() const;
void executeParsingBlockingScript();
diff --git a/WebCore/html/HTMLSelectElement.cpp b/WebCore/html/HTMLSelectElement.cpp
index 6ddcc2d..b1b6d23 100644
--- a/WebCore/html/HTMLSelectElement.cpp
+++ b/WebCore/html/HTMLSelectElement.cpp
@@ -58,13 +58,6 @@ PassRefPtr<HTMLSelectElement> HTMLSelectElement::create(const QualifiedName& tag
return adoptRef(new HTMLSelectElement(tagName, document, form));
}
-bool HTMLSelectElement::checkDTD(const Node* newChild)
-{
- // Make sure to keep <optgroup> in sync with this.
- return newChild->isTextNode() || newChild->hasTagName(optionTag) || newChild->hasTagName(optgroupTag) || newChild->hasTagName(hrTag) ||
- newChild->hasTagName(scriptTag);
-}
-
void HTMLSelectElement::recalcStyle(StyleChange change)
{
HTMLFormControlElementWithState::recalcStyle(change);
diff --git a/WebCore/html/HTMLSelectElement.h b/WebCore/html/HTMLSelectElement.h
index 59c943a..79b0789 100644
--- a/WebCore/html/HTMLSelectElement.h
+++ b/WebCore/html/HTMLSelectElement.h
@@ -86,9 +86,6 @@ protected:
HTMLSelectElement(const QualifiedName&, Document*, HTMLFormElement*);
private:
- virtual int tagPriority() const { return 6; }
- virtual bool checkDTD(const Node* newChild);
-
virtual const AtomicString& formControlType() const;
virtual bool isKeyboardFocusable(KeyboardEvent*) const;
diff --git a/WebCore/html/HTMLSourceElement.h b/WebCore/html/HTMLSourceElement.h
index 7d49a3e..8aa1d06 100644
--- a/WebCore/html/HTMLSourceElement.h
+++ b/WebCore/html/HTMLSourceElement.h
@@ -48,9 +48,6 @@ public:
private:
HTMLSourceElement(const QualifiedName&, Document*);
-
- virtual HTMLTagStatus endTagRequirement() const { return TagStatusForbidden; }
- virtual int tagPriority() const { return 0; }
virtual void insertedIntoTree(bool);
virtual bool isURLAttribute(Attribute*) const;
diff --git a/WebCore/html/HTMLStyleElement.h b/WebCore/html/HTMLStyleElement.h
index 07b5bd9..b4013b8 100644
--- a/WebCore/html/HTMLStyleElement.h
+++ b/WebCore/html/HTMLStyleElement.h
@@ -41,10 +41,6 @@ public:
private:
HTMLStyleElement(const QualifiedName&, Document*, bool createdByParser);
- virtual HTMLTagStatus endTagRequirement() const { return TagStatusRequired; }
- virtual int tagPriority() const { return 1; }
- virtual bool checkDTD(const Node* newChild) { return newChild->isTextNode(); }
-
// overload from HTMLElement
virtual void parseMappedAttribute(Attribute*);
virtual void insertedIntoDocument();
diff --git a/WebCore/html/HTMLTableCaptionElement.h b/WebCore/html/HTMLTableCaptionElement.h
index d19c7ce..a2dd2fa 100644
--- a/WebCore/html/HTMLTableCaptionElement.h
+++ b/WebCore/html/HTMLTableCaptionElement.h
@@ -37,9 +37,6 @@ public:
private:
HTMLTableCaptionElement(const QualifiedName&, Document*);
- virtual HTMLTagStatus endTagRequirement() const { return TagStatusRequired; }
- virtual int tagPriority() const { return 5; }
-
virtual bool mapToEntry(const QualifiedName&, MappedAttributeEntry&) const;
virtual void parseMappedAttribute(Attribute*);
};
diff --git a/WebCore/html/HTMLTableCellElement.h b/WebCore/html/HTMLTableCellElement.h
index a70bdcd..0c97413 100644
--- a/WebCore/html/HTMLTableCellElement.h
+++ b/WebCore/html/HTMLTableCellElement.h
@@ -56,9 +56,6 @@ public:
private:
HTMLTableCellElement(const QualifiedName&, Document*);
- virtual HTMLTagStatus endTagRequirement() const { return TagStatusOptional; }
- virtual int tagPriority() const { return 6; }
-
virtual bool mapToEntry(const QualifiedName&, MappedAttributeEntry&) const;
virtual void parseMappedAttribute(Attribute*);
diff --git a/WebCore/html/HTMLTableColElement.cpp b/WebCore/html/HTMLTableColElement.cpp
index 6c2f1fe..20b0f36 100644
--- a/WebCore/html/HTMLTableColElement.cpp
+++ b/WebCore/html/HTMLTableColElement.cpp
@@ -47,26 +47,6 @@ PassRefPtr<HTMLTableColElement> HTMLTableColElement::create(const QualifiedName&
return adoptRef(new HTMLTableColElement(tagName, document));
}
-HTMLTagStatus HTMLTableColElement::endTagRequirement() const
-{
- return hasLocalName(colTag) ? TagStatusForbidden : TagStatusOptional;
-}
-
-int HTMLTableColElement::tagPriority() const
-{
- return hasLocalName(colTag) ? 0 : 1;
-}
-
-bool HTMLTableColElement::checkDTD(const Node* newChild)
-{
- if (hasLocalName(colTag))
- return false;
-
- if (newChild->isTextNode())
- return static_cast<const Text*>(newChild)->containsOnlyWhitespace();
- return newChild->hasTagName(colTag);
-}
-
bool HTMLTableColElement::mapToEntry(const QualifiedName& attrName, MappedAttributeEntry& result) const
{
if (attrName == widthAttr) {
diff --git a/WebCore/html/HTMLTableColElement.h b/WebCore/html/HTMLTableColElement.h
index 4a219c1..c7517d1 100644
--- a/WebCore/html/HTMLTableColElement.h
+++ b/WebCore/html/HTMLTableColElement.h
@@ -42,9 +42,6 @@ public:
private:
HTMLTableColElement(const QualifiedName& tagName, Document*);
- virtual HTMLTagStatus endTagRequirement() const;
- virtual int tagPriority() const;
- virtual bool checkDTD(const Node*);
virtual bool mapToEntry(const QualifiedName&, MappedAttributeEntry&) const;
virtual void parseMappedAttribute(Attribute*);
virtual bool canHaveAdditionalAttributeStyleDecls() const { return true; }
diff --git a/WebCore/html/HTMLTableElement.cpp b/WebCore/html/HTMLTableElement.cpp
index 56cb32a..ef29bf6 100644
--- a/WebCore/html/HTMLTableElement.cpp
+++ b/WebCore/html/HTMLTableElement.cpp
@@ -63,17 +63,6 @@ PassRefPtr<HTMLTableElement> HTMLTableElement::create(const QualifiedName& tagNa
return adoptRef(new HTMLTableElement(tagName, document));
}
-bool HTMLTableElement::checkDTD(const Node* newChild)
-{
- if (newChild->isTextNode())
- return static_cast<const Text*>(newChild)->containsOnlyWhitespace();
- return newChild->hasTagName(captionTag) ||
- newChild->hasTagName(colTag) || newChild->hasTagName(colgroupTag) ||
- newChild->hasTagName(theadTag) || newChild->hasTagName(tfootTag) ||
- newChild->hasTagName(tbodyTag) || newChild->hasTagName(formTag) ||
- newChild->hasTagName(scriptTag);
-}
-
HTMLTableCaptionElement* HTMLTableElement::caption() const
{
for (Node* child = firstChild(); child; child = child->nextSibling()) {
@@ -251,20 +240,6 @@ void HTMLTableElement::deleteRow(int index, ExceptionCode& ec)
row->remove(ec);
}
-ContainerNode* HTMLTableElement::legacyParserAddChild(PassRefPtr<Node> child)
-{
- if (child->hasTagName(formTag)) {
- // First add the child.
- HTMLElement::legacyParserAddChild(child);
-
- // Now simply return ourselves as the container to insert into.
- // This has the effect of demoting the form to a leaf and moving it safely out of the way.
- return this;
- }
-
- return HTMLElement::legacyParserAddChild(child.get());
-}
-
bool HTMLTableElement::mapToEntry(const QualifiedName& attrName, MappedAttributeEntry& result) const
{
if (attrName == backgroundAttr) {
diff --git a/WebCore/html/HTMLTableElement.h b/WebCore/html/HTMLTableElement.h
index c48fee5..da3dc30 100644
--- a/WebCore/html/HTMLTableElement.h
+++ b/WebCore/html/HTMLTableElement.h
@@ -63,8 +63,6 @@ public:
String rules() const;
String summary() const;
- virtual ContainerNode* legacyParserAddChild(PassRefPtr<Node>);
-
virtual void attach();
void addSharedCellDecls(Vector<CSSMutableStyleDeclaration*>&);
@@ -73,10 +71,6 @@ public:
private:
HTMLTableElement(const QualifiedName&, Document*);
- virtual HTMLTagStatus endTagRequirement() const { return TagStatusRequired; }
- virtual int tagPriority() const { return 9; }
- virtual bool checkDTD(const Node*);
-
virtual bool mapToEntry(const QualifiedName&, MappedAttributeEntry&) const;
virtual void parseMappedAttribute(Attribute*);
virtual bool isURLAttribute(Attribute*) const;
diff --git a/WebCore/html/HTMLTableRowElement.cpp b/WebCore/html/HTMLTableRowElement.cpp
index 0bafb12..e9b5cec 100644
--- a/WebCore/html/HTMLTableRowElement.cpp
+++ b/WebCore/html/HTMLTableRowElement.cpp
@@ -54,28 +54,6 @@ PassRefPtr<HTMLTableRowElement> HTMLTableRowElement::create(const QualifiedName&
return adoptRef(new HTMLTableRowElement(tagName, document));
}
-bool HTMLTableRowElement::checkDTD(const Node* newChild)
-{
- if (newChild->isTextNode())
- return static_cast<const Text*>(newChild)->containsOnlyWhitespace();
- return newChild->hasTagName(tdTag) || newChild->hasTagName(thTag) ||
- newChild->hasTagName(formTag) || newChild->hasTagName(scriptTag);
-}
-
-ContainerNode* HTMLTableRowElement::legacyParserAddChild(PassRefPtr<Node> child)
-{
- if (child->hasTagName(formTag)) {
- // First add the child.
- HTMLTablePartElement::legacyParserAddChild(child);
-
- // Now simply return ourselves as the container to insert into.
- // This has the effect of demoting the form to a leaf and moving it safely out of the way.
- return this;
- }
-
- return HTMLTablePartElement::legacyParserAddChild(child);
-}
-
int HTMLTableRowElement::rowIndex() const
{
Node *table = parentNode();
diff --git a/WebCore/html/HTMLTableRowElement.h b/WebCore/html/HTMLTableRowElement.h
index 825d763..c433677 100644
--- a/WebCore/html/HTMLTableRowElement.h
+++ b/WebCore/html/HTMLTableRowElement.h
@@ -35,8 +35,6 @@ public:
static PassRefPtr<HTMLTableRowElement> create(Document*);
static PassRefPtr<HTMLTableRowElement> create(const QualifiedName&, Document*);
- virtual ContainerNode* legacyParserAddChild(PassRefPtr<Node>);
-
int rowIndex() const;
void setRowIndex(int);
@@ -51,10 +49,6 @@ public:
private:
HTMLTableRowElement(const QualifiedName&, Document*);
-
- virtual HTMLTagStatus endTagRequirement() const { return TagStatusOptional; }
- virtual int tagPriority() const { return 7; }
- virtual bool checkDTD(const Node*);
};
} // namespace
diff --git a/WebCore/html/HTMLTableSectionElement.cpp b/WebCore/html/HTMLTableSectionElement.cpp
index 93bfef2..982e035 100644
--- a/WebCore/html/HTMLTableSectionElement.cpp
+++ b/WebCore/html/HTMLTableSectionElement.cpp
@@ -47,28 +47,6 @@ PassRefPtr<HTMLTableSectionElement> HTMLTableSectionElement::create(const Qualif
return adoptRef(new HTMLTableSectionElement(tagName, document));
}
-bool HTMLTableSectionElement::checkDTD(const Node* newChild)
-{
- if (newChild->isTextNode())
- return static_cast<const Text*>(newChild)->containsOnlyWhitespace();
- return newChild->hasTagName(trTag) || newChild->hasTagName(formTag) ||
- newChild->hasTagName(scriptTag);
-}
-
-ContainerNode* HTMLTableSectionElement::legacyParserAddChild(PassRefPtr<Node> child)
-{
- if (child->hasTagName(formTag)) {
- // First add the child.
- HTMLTablePartElement::legacyParserAddChild(child);
-
- // Now simply return ourselves as the container to insert into.
- // This has the effect of demoting the form to a leaf and moving it safely out of the way.
- return this;
- }
-
- return HTMLTablePartElement::legacyParserAddChild(child);
-}
-
// used by table row groups to share style decls created by the enclosing table.
void HTMLTableSectionElement::additionalAttributeStyleDecls(Vector<CSSMutableStyleDeclaration*>& results)
{
diff --git a/WebCore/html/HTMLTableSectionElement.h b/WebCore/html/HTMLTableSectionElement.h
index 3e356da..a84cbde 100644
--- a/WebCore/html/HTMLTableSectionElement.h
+++ b/WebCore/html/HTMLTableSectionElement.h
@@ -34,8 +34,6 @@ class HTMLTableSectionElement : public HTMLTablePartElement {
public:
static PassRefPtr<HTMLTableSectionElement> create(const QualifiedName&, Document*);
- virtual ContainerNode* legacyParserAddChild(PassRefPtr<Node>);
-
PassRefPtr<HTMLElement> insertRow(int index, ExceptionCode&);
void deleteRow(int index, ExceptionCode&);
@@ -58,9 +56,6 @@ public:
private:
HTMLTableSectionElement(const QualifiedName& tagName, Document*);
- virtual HTMLTagStatus endTagRequirement() const { return TagStatusOptional; }
- virtual int tagPriority() const { return 8; }
- virtual bool checkDTD(const Node*);
virtual bool canHaveAdditionalAttributeStyleDecls() const { return true; }
virtual void additionalAttributeStyleDecls(Vector<CSSMutableStyleDeclaration*>&);
};
diff --git a/WebCore/html/HTMLTextAreaElement.h b/WebCore/html/HTMLTextAreaElement.h
index 43fe493..bb0039e 100644
--- a/WebCore/html/HTMLTextAreaElement.h
+++ b/WebCore/html/HTMLTextAreaElement.h
@@ -76,8 +76,6 @@ private:
virtual void defaultEventHandler(Event*);
- virtual bool checkDTD(const Node* newChild) { return newChild->isTextNode(); }
-
virtual bool isEnumeratable() const { return true; }
virtual const AtomicString& formControlType() const;
diff --git a/WebCore/html/HTMLTitleElement.h b/WebCore/html/HTMLTitleElement.h
index bcd4283..8b90f56 100644
--- a/WebCore/html/HTMLTitleElement.h
+++ b/WebCore/html/HTMLTitleElement.h
@@ -36,8 +36,6 @@ public:
private:
HTMLTitleElement(const QualifiedName&, Document*);
- virtual bool checkDTD(const Node* newChild) { return newChild->isTextNode(); }
-
virtual void insertedIntoDocument();
virtual void removedFromDocument();
virtual void childrenChanged(bool changedByParser = false, Node* beforeChange = 0, Node* afterChange = 0, int childCountDelta = 0);
diff --git a/WebCore/html/HTMLToken.h b/WebCore/html/HTMLToken.h
index e42a829..42cddb8 100644
--- a/WebCore/html/HTMLToken.h
+++ b/WebCore/html/HTMLToken.h
@@ -128,7 +128,7 @@ public:
{
ASSERT(m_type == Uninitialized);
m_type = DOCTYPE;
- m_doctypeData.set(new DoctypeData());
+ m_doctypeData = adoptPtr(new DoctypeData());
}
void beginDOCTYPE(UChar character)
diff --git a/WebCore/html/HTMLTokenizer.h b/WebCore/html/HTMLTokenizer.h
index 6fb3053..2b93e15 100644
--- a/WebCore/html/HTMLTokenizer.h
+++ b/WebCore/html/HTMLTokenizer.h
@@ -29,6 +29,7 @@
#include "SegmentedString.h"
#include <wtf/Noncopyable.h>
+#include <wtf/PassOwnPtr.h>
#include <wtf/Vector.h>
#include <wtf/text/AtomicString.h>
@@ -115,7 +116,7 @@ public:
CDATASectionState,
};
- HTMLTokenizer();
+ static PassOwnPtr<HTMLTokenizer> create() { return adoptPtr(new HTMLTokenizer); }
~HTMLTokenizer();
void reset();
@@ -231,6 +232,8 @@ private:
bool m_skipNextNewLine;
};
+ HTMLTokenizer();
+
inline bool processEntity(SegmentedString&);
inline void parseError();
diff --git a/WebCore/html/HTMLTreeBuilder.cpp b/WebCore/html/HTMLTreeBuilder.cpp
index fd0b62e..24eb62f 100644
--- a/WebCore/html/HTMLTreeBuilder.cpp
+++ b/WebCore/html/HTMLTreeBuilder.cpp
@@ -39,7 +39,6 @@
#include "HTMLScriptElement.h"
#include "HTMLToken.h"
#include "HTMLTokenizer.h"
-#include "LegacyHTMLTreeBuilder.h"
#include "LocalizedStrings.h"
#include "MathMLNames.h"
#include "NotImplemented.h"
@@ -50,6 +49,9 @@
#include "XLinkNames.h"
#include "XMLNSNames.h"
#include "XMLNames.h"
+// FIXME: Remove this include once we find a home for the free functions that
+// are using it.
+#include <wtf/dtoa.h>
#include <wtf/UnusedParam.h>
namespace WebCore {
@@ -98,11 +100,6 @@ inline bool isAllWhitespaceOrReplacementCharacters(const String& string)
return isAllSpecialCharacters<isTreeBuilderWhitepaceOrReplacementCharacter>(string);
}
-bool shouldUseLegacyTreeBuilder(Document* document)
-{
- return !document->settings() || !document->settings()->html5TreeBuilderEnabled();
-}
-
bool isNumberedHeaderTag(const AtomicString& tagName)
{
return tagName == h1Tag
@@ -133,8 +130,12 @@ bool isTableBodyContextTag(const AtomicString& tagName)
}
// http://www.whatwg.org/specs/web-apps/current-work/multipage/parsing.html#special
-bool isSpecialTag(const AtomicString& tagName)
+bool isSpecialNode(Node* node)
{
+ if (node->namespaceURI() != xhtmlNamespaceURI)
+ return false;
+ // FIXME: This list is out of sync with the spec.
+ const AtomicString& tagName = node->localName();
return tagName == addressTag
|| tagName == articleTag
|| tagName == asideTag
@@ -167,6 +168,7 @@ bool isSpecialTag(const AtomicString& tagName)
|| tagName == headerTag
|| tagName == hgroupTag
|| tagName == hrTag
+ || tagName == htmlTag
|| tagName == iframeTag
|| tagName == imgTag
|| tagName == inputTag
@@ -199,7 +201,6 @@ bool isSpecialTag(const AtomicString& tagName)
}
// http://www.whatwg.org/specs/web-apps/current-work/multipage/parsing.html#scoping
-// Same as isScopingTag in LegacyHTMLTreeBuilder.cpp
// and isScopeMarker in HTMLElementStack.cpp
bool isScopingTag(const AtomicString& tagName)
{
@@ -241,22 +242,6 @@ bool isFormattingTag(const AtomicString& tagName)
return tagName == aTag || isNonAnchorFormattingTag(tagName);
}
-// http://www.whatwg.org/specs/web-apps/current-work/multipage/parsing.html#phrasing
-bool isPhrasingTag(const AtomicString& tagName)
-{
- return !isSpecialTag(tagName) && !isScopingTag(tagName) && !isFormattingTag(tagName);
-}
-
-bool isNotFormattingAndNotPhrasing(const Element* element)
-{
- // The spec often says "node is not in the formatting category, and is not
- // in the phrasing category". !phrasing && !formatting == scoping || special
- // scoping || special is easier to compute.
- // FIXME: localName() is wrong for non-html content.
- const AtomicString& tagName = element->localName();
- return isScopingTag(tagName) || isSpecialTag(tagName);
-}
-
HTMLFormElement* closestFormAncestor(Element* element)
{
while (element) {
@@ -388,8 +373,8 @@ HTMLTreeBuilder::HTMLTreeBuilder(HTMLTokenizer* tokenizer, HTMLDocument* documen
, m_originalInsertionMode(InitialMode)
, m_secondaryInsertionMode(InitialMode)
, m_tokenizer(tokenizer)
- , m_lastScriptElementStartLine(uninitializedLineNumberValue)
, m_scriptToProcessStartLine(uninitializedLineNumberValue)
+ , m_lastScriptElementStartLine(uninitializedLineNumberValue)
{
}
@@ -397,7 +382,7 @@ HTMLTreeBuilder::HTMLTreeBuilder(HTMLTokenizer* tokenizer, HTMLDocument* documen
// minimize code duplication between these constructors.
HTMLTreeBuilder::HTMLTreeBuilder(HTMLTokenizer* tokenizer, DocumentFragment* fragment, Element* contextElement, FragmentScriptingPermission scriptingPermission)
: m_framesetOk(true)
- , m_fragmentContext(fragment, contextElement, scriptingPermission, shouldUseLegacyTreeBuilder(fragment->document()))
+ , m_fragmentContext(fragment, contextElement, scriptingPermission)
, m_document(m_fragmentContext.document())
, m_tree(m_document, scriptingPermission, true)
, m_reportErrors(false) // FIXME: Why not report errors in fragments?
@@ -406,12 +391,9 @@ HTMLTreeBuilder::HTMLTreeBuilder(HTMLTokenizer* tokenizer, DocumentFragment* fra
, m_originalInsertionMode(InitialMode)
, m_secondaryInsertionMode(InitialMode)
, m_tokenizer(tokenizer)
- , m_legacyTreeBuilder(shouldUseLegacyTreeBuilder(fragment->document()) ? new LegacyHTMLTreeBuilder(fragment, scriptingPermission) : 0)
- , m_lastScriptElementStartLine(uninitializedLineNumberValue)
, m_scriptToProcessStartLine(uninitializedLineNumberValue)
+ , m_lastScriptElementStartLine(uninitializedLineNumberValue)
{
- if (shouldUseLegacyTreeBuilder(fragment->document()))
- return;
if (contextElement) {
// Steps 4.2-4.6 of the HTML5 Fragment Case parsing algorithm:
// http://www.whatwg.org/specs/web-apps/current-work/multipage/the-end.html#fragment-case
@@ -426,19 +408,27 @@ HTMLTreeBuilder::~HTMLTreeBuilder()
{
}
+void HTMLTreeBuilder::detach()
+{
+ // This call makes little sense in fragment mode, but for consistency
+ // DocumentParser expects detach() to always be called before it's destroyed.
+ m_document = 0;
+ // HTMLConstructionSite might be on the callstack when detach() is called
+ // otherwise we'd just call m_tree.clear() here instead.
+ m_tree.detach();
+}
+
HTMLTreeBuilder::FragmentParsingContext::FragmentParsingContext()
: m_fragment(0)
, m_contextElement(0)
- , m_usingLegacyTreeBuilder(false)
, m_scriptingPermission(FragmentScriptingAllowed)
{
}
-HTMLTreeBuilder::FragmentParsingContext::FragmentParsingContext(DocumentFragment* fragment, Element* contextElement, FragmentScriptingPermission scriptingPermission, bool legacyMode)
- : m_dummyDocumentForFragmentParsing(legacyMode ? 0 : HTMLDocument::create(0, KURL()))
+HTMLTreeBuilder::FragmentParsingContext::FragmentParsingContext(DocumentFragment* fragment, Element* contextElement, FragmentScriptingPermission scriptingPermission)
+ : m_dummyDocumentForFragmentParsing(HTMLDocument::create(0, KURL()))
, m_fragment(fragment)
, m_contextElement(contextElement)
- , m_usingLegacyTreeBuilder(legacyMode)
, m_scriptingPermission(scriptingPermission)
{
}
@@ -446,8 +436,6 @@ HTMLTreeBuilder::FragmentParsingContext::FragmentParsingContext(DocumentFragment
Document* HTMLTreeBuilder::FragmentParsingContext::document() const
{
ASSERT(m_fragment);
- if (m_usingLegacyTreeBuilder)
- return m_fragment->document();
return m_dummyDocumentForFragmentParsing.get();
}
@@ -472,39 +460,6 @@ HTMLTreeBuilder::FragmentParsingContext::~FragmentParsingContext()
{
}
-static void convertToOldStyle(AtomicHTMLToken& token, Token& oldStyleToken)
-{
- switch (token.type()) {
- case HTMLToken::Uninitialized:
- case HTMLToken::DOCTYPE:
- ASSERT_NOT_REACHED();
- break;
- case HTMLToken::EndOfFile:
- ASSERT_NOT_REACHED();
- notImplemented();
- break;
- case HTMLToken::StartTag:
- case HTMLToken::EndTag: {
- oldStyleToken.beginTag = (token.type() == HTMLToken::StartTag);
- // The LegacyHTMLTreeBuilder seems to work better if we lie here and
- // say that tags are never self closing. As a wise man once said:
- // "You can't handle the truth!"
- oldStyleToken.selfClosingTag = false;
- oldStyleToken.tagName = token.name();
- oldStyleToken.attrs = token.takeAtributes();
- break;
- }
- case HTMLToken::Comment:
- oldStyleToken.tagName = commentAtom;
- oldStyleToken.text = token.comment().impl();
- break;
- case HTMLToken::Character:
- oldStyleToken.tagName = textAtom;
- oldStyleToken.text = StringImpl::create(token.characters().data(), token.characters().size());
- break;
- }
-}
-
PassRefPtr<Element> HTMLTreeBuilder::takeScriptToProcess(int& scriptStartLine)
{
// Unpause ourselves, callers may pause us again when processing the script.
@@ -536,74 +491,8 @@ HTMLTokenizer::State HTMLTreeBuilder::adjustedLexerState(HTMLTokenizer::State st
return state;
}
-void HTMLTreeBuilder::passTokenToLegacyParser(HTMLToken& token)
-{
- if (token.type() == HTMLToken::DOCTYPE) {
- DoctypeToken doctypeToken;
- doctypeToken.m_name.append(token.name().data(), token.name().size());
- doctypeToken.m_publicID = token.publicIdentifier();
- doctypeToken.m_systemID = token.systemIdentifier();
- doctypeToken.m_forceQuirks = token.forceQuirks();
-
- m_legacyTreeBuilder->parseDoctypeToken(&doctypeToken);
- return;
- }
-
- if (token.type() == HTMLToken::EndOfFile)
- return;
-
- // For now, we translate into an old-style token for testing.
- Token oldStyleToken;
- AtomicHTMLToken atomicToken(token);
- convertToOldStyle(atomicToken, oldStyleToken);
-
- RefPtr<Node> result = m_legacyTreeBuilder->parseToken(&oldStyleToken);
- if (token.type() == HTMLToken::StartTag) {
- // This work is supposed to be done by the parser, but
- // when using the old parser for we have to do this manually.
- if (oldStyleToken.tagName == scriptTag) {
- m_tokenizer->setState(HTMLTokenizer::ScriptDataState);
- m_lastScriptElement = static_pointer_cast<Element>(result);
- m_lastScriptElementStartLine = m_tokenizer->lineNumber();
- } else if (oldStyleToken.tagName == preTag || oldStyleToken.tagName == listingTag)
- m_tokenizer->setSkipLeadingNewLineForListing(true);
- else
- m_tokenizer->setState(adjustedLexerState(m_tokenizer->state(), oldStyleToken.tagName, m_document->frame()));
- } else if (token.type() == HTMLToken::EndTag) {
- if (oldStyleToken.tagName == scriptTag) {
- if (m_lastScriptElement) {
- ASSERT(m_lastScriptElementStartLine != uninitializedLineNumberValue);
- if (m_fragmentContext.scriptingPermission() == FragmentScriptingNotAllowed) {
- // FIXME: This is a horrible hack for platform/Pasteboard.
- // Clear the <script> tag when using the Parser to create
- // a DocumentFragment for pasting so that javascript content
- // does not show up in pasted HTML.
- m_lastScriptElement->removeChildren();
- } else if (insertionMode() != AfterFramesetMode) {
- ASSERT(!m_scriptToProcess); // Caller never called takeScriptToProcess!
- ASSERT(m_scriptToProcessStartLine == uninitializedLineNumberValue); // Caller never called takeScriptToProcess!
- // Pause ourselves so that parsing stops until the script can be processed by the caller.
- m_isPaused = true;
- m_scriptToProcess = m_lastScriptElement.get();
- // Lexer line numbers are 0-based, ScriptSourceCode expects 1-based lines,
- // so we convert here before passing the line number off to HTMLScriptRunner.
- m_scriptToProcessStartLine = m_lastScriptElementStartLine + 1;
- }
- m_lastScriptElement = 0;
- m_lastScriptElementStartLine = uninitializedLineNumberValue;
- }
- } else if (oldStyleToken.tagName == framesetTag)
- setInsertionMode(AfterFramesetMode);
- }
-}
-
void HTMLTreeBuilder::constructTreeFromToken(HTMLToken& rawToken)
{
- if (m_legacyTreeBuilder) {
- passTokenToLegacyParser(rawToken);
- return;
- }
-
AtomicHTMLToken token(rawToken);
processToken(token);
@@ -754,7 +643,7 @@ void HTMLTreeBuilder::processCloseWhenNestedTag(AtomicHTMLToken& token)
processFakeEndTag(node->tagQName());
break;
}
- if (isNotFormattingAndNotPhrasing(node) && !node->hasTagName(addressTag) && !node->hasTagName(divTag) && !node->hasTagName(pTag))
+ if (isSpecialNode(node) && !node->hasTagName(addressTag) && !node->hasTagName(divTag) && !node->hasTagName(pTag))
break;
nodeRecord = nodeRecord->next();
}
@@ -1034,7 +923,7 @@ void HTMLTreeBuilder::processStartTagForInBody(AtomicHTMLToken& token)
return;
}
if (token.name() == tableTag) {
- if (m_document->parseMode() != Document::Compat && m_tree.openElements()->inScope(pTag))
+ if (m_document->parseMode() != Document::Compat && m_tree.openElements()->inButtonScope(pTag))
processFakeEndTag(pTag);
m_tree.insertHTMLElement(token);
m_framesetOk = false;
@@ -1715,7 +1604,7 @@ void HTMLTreeBuilder::processAnyOtherEndTagForInBody(AtomicHTMLToken& token)
m_tree.openElements()->popUntilPopped(node);
return;
}
- if (isNotFormattingAndNotPhrasing(node)) {
+ if (isSpecialNode(node)) {
parseError(token);
return;
}
@@ -1731,7 +1620,7 @@ HTMLElementStack::ElementRecord* HTMLTreeBuilder::furthestBlockForFormattingElem
for (; record; record = record->next()) {
if (record->element() == formattingElement)
return furthestBlock;
- if (isNotFormattingAndNotPhrasing(record->element()))
+ if (isSpecialNode(record->element()))
furthestBlock = record;
}
ASSERT_NOT_REACHED();
@@ -1745,9 +1634,10 @@ void HTMLTreeBuilder::reparentChildren(Element* oldParent, Element* newParent)
Node* child = oldParent->firstChild();
while (child) {
Node* nextChild = child->nextSibling();
- ExceptionCode ec;
- newParent->appendChild(child, ec);
- ASSERT(!ec);
+ oldParent->parserRemoveChild(child);
+ newParent->parserAddChild(child);
+ if (newParent->attached() && !child->attached())
+ child->attach();
child = nextChild;
}
}
@@ -1818,15 +1708,18 @@ void HTMLTreeBuilder::callTheAdoptionAgency(AtomicHTMLToken& token)
if (lastNode == furthestBlock)
bookmark.moveToAfter(nodeEntry);
// 6.6
- // Use appendChild instead of parserAddChild to handle possible reparenting.
- ExceptionCode ec;
- node->element()->appendChild(lastNode->element(), ec, true);
- ASSERT(!ec);
+ if (Element* parent = lastNode->element()->parentElement())
+ parent->parserRemoveChild(lastNode->element());
+ node->element()->parserAddChild(lastNode->element());
+ if (lastNode->element()->parentElement()->attached() && !lastNode->element()->attached())
+ lastNode->element()->lazyAttach();
// 6.7
lastNode = node;
}
// 7
const AtomicString& commonAncestorTag = commonAncestor->localName();
+ if (Element* parent = lastNode->element()->parentElement())
+ parent->parserRemoveChild(lastNode->element());
// FIXME: If this moves to HTMLConstructionSite, this check should use
// causesFosterParenting(tagName) instead.
if (commonAncestorTag == tableTag
@@ -1834,9 +1727,9 @@ void HTMLTreeBuilder::callTheAdoptionAgency(AtomicHTMLToken& token)
|| isTableBodyContextTag(commonAncestorTag))
m_tree.fosterParent(lastNode->element());
else {
- ExceptionCode ec;
- commonAncestor->appendChild(lastNode->element(), ec, true);
- ASSERT(!ec);
+ commonAncestor->parserAddChild(lastNode->element());
+ if (lastNode->element()->parentElement()->attached() && !lastNode->element()->attached())
+ lastNode->element()->lazyAttach();
}
// 8
RefPtr<Element> newElement = m_tree.createHTMLElementFromElementRecord(formattingElementRecord);
@@ -2394,6 +2287,8 @@ void HTMLTreeBuilder::processEndTag(AtomicHTMLToken& token)
m_scriptToProcess = m_tree.currentElement();
m_scriptToProcessStartLine = m_lastScriptElementStartLine + 1;
m_tree.openElements()->pop();
+ if (isParsingFragment() && m_fragmentContext.scriptingPermission() == FragmentScriptingNotAllowed)
+ m_scriptToProcess->removeAllChildren();
setInsertionMode(m_originalInsertionMode);
return;
}
@@ -2479,30 +2374,19 @@ void HTMLTreeBuilder::processEndTag(AtomicHTMLToken& token)
if (m_tree.currentElement()->namespaceURI() != xhtmlNamespaceURI) {
// FIXME: This code just wants an Element* iterator, instead of an ElementRecord*
HTMLElementStack::ElementRecord* nodeRecord = m_tree.openElements()->topRecord();
- if (!nodeRecord->element()->hasLocalName(token.name())) {
+ if (!nodeRecord->element()->hasLocalName(token.name()))
parseError(token);
- // FIXME: This return is not in the spec but it needed for now
- // to prevent walking off the bottom of the stack.
- // http://www.w3.org/Bugs/Public/show_bug.cgi?id=10118
- if (!m_tree.openElements()->contains(token.name()))
- return;
- }
while (1) {
if (nodeRecord->element()->hasLocalName(token.name())) {
m_tree.openElements()->popUntilPopped(nodeRecord->element());
- return;
+ break;
}
nodeRecord = nodeRecord->next();
- if (nodeRecord->element()->namespaceURI() == xhtmlNamespaceURI) {
- processUsingSecondaryInsertionModeAndAdjustInsertionMode(token);
- // FIXME: This is a hack around a spec bug and is likely wrong.
- // http://www.w3.org/Bugs/Public/show_bug.cgi?id=9581
- if (nodeRecord != m_tree.openElements()->topRecord())
- return;
- }
+ if (nodeRecord->element()->namespaceURI() == xhtmlNamespaceURI)
+ break;
}
- return;
}
+ // Any other end tag (also the last two steps of "An end tag, if the current node is not an element in the HTML namespace."
processUsingSecondaryInsertionModeAndAdjustInsertionMode(token);
break;
}
@@ -2935,19 +2819,13 @@ void HTMLTreeBuilder::processScriptStartTag(AtomicHTMLToken& token)
void HTMLTreeBuilder::finished()
{
- // We should call m_document->finishedParsing() here, except
- // m_legacyTreeBuilder->finished() does it for us.
- if (m_legacyTreeBuilder) {
- m_legacyTreeBuilder->finished();
- return;
- }
-
+ ASSERT(m_document);
if (isParsingFragment()) {
m_fragmentContext.finished();
return;
}
- // Warning, this may delete the parser, so don't try to do anything else after this.
+ // Warning, this may detach the parser. Do not do anything else after this.
m_document->finishedParsing();
}
@@ -2967,4 +2845,40 @@ bool HTMLTreeBuilder::pluginsEnabled(Frame* frame)
return frame->loader()->subframeLoader()->allowPlugins(NotAboutToInstantiatePlugin);
}
+// FIXME: Move this function to a more appropriate place.
+String serializeForNumberType(double number)
+{
+ // According to HTML5, "the best representation of the number n as a floating
+ // point number" is a string produced by applying ToString() to n.
+ NumberToStringBuffer buffer;
+ return String(buffer, numberToString(number, buffer));
+ }
+
+// FIXME: Move this function to a more appropriate place.
+bool parseToDoubleForNumberType(const String& src, double* out)
+{
+ // See HTML5 2.4.4.3 `Real numbers.'
+
+ if (src.isEmpty())
+ return false;
+ // String::toDouble() accepts leading + \t \n \v \f \r and SPACE, which are invalid in HTML5.
+ // So, check the first character.
+ if (src[0] != '-' && (src[0] < '0' || src[0] > '9'))
+ return false;
+
+ bool valid = false;
+ double value = src.toDouble(&valid);
+ if (!valid)
+ return false;
+ // NaN and Infinity are not valid numbers according to the standard.
+ if (!isfinite(value))
+ return false;
+ // -0 -> 0
+ if (!value)
+ value = 0;
+ if (out)
+ *out = value;
+ return true;
+}
+
}
diff --git a/WebCore/html/HTMLTreeBuilder.h b/WebCore/html/HTMLTreeBuilder.h
index 24cb542..c30e6b8 100644
--- a/WebCore/html/HTMLTreeBuilder.h
+++ b/WebCore/html/HTMLTreeBuilder.h
@@ -47,16 +47,22 @@ class DocumentFragment;
class Frame;
class HTMLToken;
class HTMLDocument;
-class LegacyHTMLTreeBuilder;
class Node;
class HTMLTreeBuilder : public Noncopyable {
public:
- // FIXME: Replace constructors with create() functions returning PassOwnPtrs
- HTMLTreeBuilder(HTMLTokenizer*, HTMLDocument*, bool reportErrors);
- HTMLTreeBuilder(HTMLTokenizer*, DocumentFragment*, Element* contextElement, FragmentScriptingPermission);
+ static PassOwnPtr<HTMLTreeBuilder> create(HTMLTokenizer* tokenizer, HTMLDocument* document, bool reportErrors)
+ {
+ return adoptPtr(new HTMLTreeBuilder(tokenizer, document, reportErrors));
+ }
+ static PassOwnPtr<HTMLTreeBuilder> create(HTMLTokenizer* tokenizer, DocumentFragment* fragment, Element* contextElement, FragmentScriptingPermission scriptingPermission)
+ {
+ return adoptPtr(new HTMLTreeBuilder(tokenizer, fragment, contextElement, scriptingPermission));
+ }
~HTMLTreeBuilder();
+ void detach();
+
void setPaused(bool paused) { m_isPaused = paused; }
bool isPaused() const { return m_isPaused; }
@@ -70,10 +76,6 @@ public:
static HTMLTokenizer::State adjustedLexerState(HTMLTokenizer::State, const AtomicString& tagName, Frame*);
- // FIXME: This is a dirty, rotten hack to keep HTMLFormControlElement happy
- // until we stop using the legacy parser. DO NOT CALL THIS METHOD.
- LegacyHTMLTreeBuilder* legacyTreeBuilder() const { return m_legacyTreeBuilder.get(); }
-
static bool scriptEnabled(Frame*);
static bool pluginsEnabled(Frame*);
@@ -108,9 +110,10 @@ private:
AfterAfterFramesetMode,
};
- bool isParsingFragment() const { return !!m_fragmentContext.fragment(); }
+ HTMLTreeBuilder(HTMLTokenizer*, HTMLDocument*, bool reportErrors);
+ HTMLTreeBuilder(HTMLTokenizer*, DocumentFragment*, Element* contextElement, FragmentScriptingPermission);
- void passTokenToLegacyParser(HTMLToken&);
+ bool isParsingFragment() const { return !!m_fragmentContext.fragment(); }
void processToken(AtomicHTMLToken&);
@@ -200,12 +203,12 @@ private:
class FragmentParsingContext : public Noncopyable {
public:
FragmentParsingContext();
- FragmentParsingContext(DocumentFragment*, Element* contextElement, FragmentScriptingPermission, bool usingLegacyTreeBuilder);
+ FragmentParsingContext(DocumentFragment*, Element* contextElement, FragmentScriptingPermission);
~FragmentParsingContext();
Document* document() const;
DocumentFragment* fragment() const { return m_fragment; }
- Element* contextElement() const { ASSERT(m_fragment); ASSERT(!m_usingLegacyTreeBuilder); return m_contextElement; }
+ Element* contextElement() const { ASSERT(m_fragment); return m_contextElement; }
FragmentScriptingPermission scriptingPermission() const { ASSERT(m_fragment); return m_scriptingPermission; }
void finished();
@@ -214,7 +217,6 @@ private:
RefPtr<Document> m_dummyDocumentForFragmentParsing;
DocumentFragment* m_fragment;
Element* m_contextElement;
- bool m_usingLegacyTreeBuilder;
// FragmentScriptingNotAllowed causes the Parser to remove children
// from <script> tags (so javascript doesn't show up in pastes).
@@ -244,18 +246,27 @@ private:
// from within parser actions.
HTMLTokenizer* m_tokenizer;
- // We're re-using logic from the old LegacyHTMLTreeBuilder while this class is being written.
- OwnPtr<LegacyHTMLTreeBuilder> m_legacyTreeBuilder;
-
- // These members are intentionally duplicated as the first set is a hack
- // on top of the legacy parser which will eventually be removed.
- RefPtr<Element> m_lastScriptElement; // FIXME: Hack for <script> support on top of the old parser.
- int m_lastScriptElementStartLine; // FIXME: Hack for <script> support on top of the old parser.
-
RefPtr<Element> m_scriptToProcess; // <script> tag which needs processing before resuming the parser.
int m_scriptToProcessStartLine; // Starting line number of the script tag needing processing.
+
+ // FIXME: We probably want to remove this member. Originally, it was
+ // created to service the legacy tree builder, but it seems to be used for
+ // some other things now.
+ int m_lastScriptElementStartLine;
};
+// FIXME: Move these functions to a more appropriate place.
+
+// Converts the specified string to a floating number.
+// If the conversion fails, the return value is false. Take care that leading
+// or trailing unnecessary characters make failures. This returns false for an
+// empty string input.
+// The double* parameter may be 0.
+bool parseToDoubleForNumberType(const String&, double*);
+// Converts the specified number to a string. This is an implementation of
+// HTML5's "algorithm to convert a number to a string" for NUMBER/RANGE types.
+String serializeForNumberType(double);
+
}
#endif
diff --git a/WebCore/html/HTMLUListElement.h b/WebCore/html/HTMLUListElement.h
index 996626c..f91bf1c 100644
--- a/WebCore/html/HTMLUListElement.h
+++ b/WebCore/html/HTMLUListElement.h
@@ -35,9 +35,6 @@ public:
private:
HTMLUListElement(const QualifiedName&, Document*);
- virtual HTMLTagStatus endTagRequirement() const { return TagStatusRequired; }
- virtual int tagPriority() const { return 5; }
-
virtual bool mapToEntry(const QualifiedName&, MappedAttributeEntry&) const;
virtual void parseMappedAttribute(Attribute*);
};
diff --git a/WebCore/html/HTMLVideoElement.cpp b/WebCore/html/HTMLVideoElement.cpp
index ed2d35c..cd9c7ec 100644
--- a/WebCore/html/HTMLVideoElement.cpp
+++ b/WebCore/html/HTMLVideoElement.cpp
@@ -76,7 +76,7 @@ void HTMLVideoElement::attach()
updateDisplayState();
if (shouldDisplayPosterImage()) {
if (!m_imageLoader)
- m_imageLoader.set(new HTMLImageLoader(this));
+ m_imageLoader = adoptPtr(new HTMLImageLoader(this));
m_imageLoader->updateFromElement();
if (renderer()) {
RenderImage* imageRenderer = toRenderImage(renderer());
@@ -105,7 +105,7 @@ void HTMLVideoElement::parseMappedAttribute(Attribute* attr)
#if !ENABLE(PLUGIN_PROXY_FOR_VIDEO)
if (shouldDisplayPosterImage()) {
if (!m_imageLoader)
- m_imageLoader.set(new HTMLImageLoader(this));
+ m_imageLoader = adoptPtr(new HTMLImageLoader(this));
m_imageLoader->updateFromElementIgnoringPreviousError();
} else {
if (m_imageLoader)
diff --git a/WebCore/html/HTMLVideoElement.h b/WebCore/html/HTMLVideoElement.h
index 04a0beb..d893411 100644
--- a/WebCore/html/HTMLVideoElement.h
+++ b/WebCore/html/HTMLVideoElement.h
@@ -63,7 +63,6 @@ public:
private:
HTMLVideoElement(const QualifiedName&, Document*);
- virtual int tagPriority() const { return 5; }
virtual bool rendererIsNeeded(RenderStyle*);
#if !ENABLE(PLUGIN_PROXY_FOR_VIDEO)
virtual RenderObject* createRenderer(RenderArena*, RenderStyle*);
diff --git a/WebCore/html/HTMLViewSourceDocument.cpp b/WebCore/html/HTMLViewSourceDocument.cpp
index e0e71ee..b307ea2 100644
--- a/WebCore/html/HTMLViewSourceDocument.cpp
+++ b/WebCore/html/HTMLViewSourceDocument.cpp
@@ -53,7 +53,7 @@ HTMLViewSourceDocument::HTMLViewSourceDocument(Frame* frame, const KURL& url, co
setUsesBeforeAfterRules(true);
}
-DocumentParser* HTMLViewSourceDocument::createParser()
+PassRefPtr<DocumentParser> HTMLViewSourceDocument::createParser()
{
// Use HTMLDocumentParser if applicable, otherwise use TextDocumentParser.
if (m_type == "text/html" || m_type == "application/xhtml+xml" || m_type == "image/svg+xml" || DOMImplementation::isXMLMIMEType(m_type)
@@ -61,7 +61,7 @@ DocumentParser* HTMLViewSourceDocument::createParser()
|| m_type == "application/vnd.wap.xhtml+xml"
#endif
)
- return new HTMLViewSourceParser(this);
+ return HTMLViewSourceParser::create(this);
return createTextDocumentParser(this);
}
diff --git a/WebCore/html/HTMLViewSourceDocument.h b/WebCore/html/HTMLViewSourceDocument.h
index 8805848..f459016 100644
--- a/WebCore/html/HTMLViewSourceDocument.h
+++ b/WebCore/html/HTMLViewSourceDocument.h
@@ -49,7 +49,7 @@ private:
HTMLViewSourceDocument(Frame*, const KURL&, const String& mimeType);
// Returns HTMLViewSourceParser or TextDocumentParser based on m_type.
- virtual DocumentParser* createParser();
+ virtual PassRefPtr<DocumentParser> createParser();
void processDoctypeToken(const String& source, HTMLToken&);
void processTagToken(const String& source, HTMLToken&);
diff --git a/WebCore/html/HTMLViewSourceParser.cpp b/WebCore/html/HTMLViewSourceParser.cpp
index 3da4c23..8a7984d 100644
--- a/WebCore/html/HTMLViewSourceParser.cpp
+++ b/WebCore/html/HTMLViewSourceParser.cpp
@@ -32,6 +32,12 @@
namespace WebCore {
+HTMLViewSourceParser::HTMLViewSourceParser(HTMLViewSourceDocument* document)
+ : DecodedDataDocumentParser(document)
+ , m_tokenizer(HTMLTokenizer::create())
+{
+}
+
HTMLViewSourceParser::~HTMLViewSourceParser()
{
}
@@ -43,7 +49,7 @@ void HTMLViewSourceParser::insert(const SegmentedString&)
void HTMLViewSourceParser::pumpTokenizer()
{
- while (m_tokenizer.nextToken(m_input.current(), m_token)) {
+ while (m_tokenizer->nextToken(m_input.current(), m_token)) {
m_token.end(m_input.current().numberOfCharactersConsumed());
document()->addSource(sourceForToken(), m_token);
updateTokenizerState();
@@ -81,12 +87,12 @@ void HTMLViewSourceParser::updateTokenizerState()
return;
AtomicString tagName(m_token.name().data(), m_token.name().size());
- m_tokenizer.setState(HTMLTreeBuilder::adjustedLexerState(m_tokenizer.state(), tagName, m_document->frame()));
+ m_tokenizer->setState(HTMLTreeBuilder::adjustedLexerState(m_tokenizer->state(), tagName, document()->frame()));
if (tagName == HTMLNames::scriptTag) {
// The tree builder handles scriptTag separately from the other tokenizer
// state adjustments, so we need to handle it separately too.
- ASSERT(m_tokenizer.state() == HTMLTokenizer::DataState);
- m_tokenizer.setState(HTMLTokenizer::ScriptDataState);
+ ASSERT(m_tokenizer->state() == HTMLTokenizer::DataState);
+ m_tokenizer->setState(HTMLTokenizer::ScriptDataState);
}
}
diff --git a/WebCore/html/HTMLViewSourceParser.h b/WebCore/html/HTMLViewSourceParser.h
index 2571301..34caf43 100644
--- a/WebCore/html/HTMLViewSourceParser.h
+++ b/WebCore/html/HTMLViewSourceParser.h
@@ -39,28 +39,27 @@ class HTMLTokenizer;
class HTMLScriptRunner;
class HTMLTreeBuilder;
class HTMLPreloadScanner;
-class LegacyHTMLTreeBuilder;
class ScriptController;
class ScriptSourceCode;
class HTMLViewSourceParser : public DecodedDataDocumentParser {
public:
- // FIXME: Make private with a create method.
- HTMLViewSourceParser(HTMLViewSourceDocument* document)
- : DecodedDataDocumentParser(document)
+ static PassRefPtr<HTMLViewSourceParser> create(HTMLViewSourceDocument* document)
{
+ return adoptRef(new HTMLViewSourceParser(document));
}
-
virtual ~HTMLViewSourceParser();
private:
+ HTMLViewSourceParser(HTMLViewSourceDocument*);
+
// DocumentParser
virtual void insert(const SegmentedString&);
virtual void append(const SegmentedString&);
virtual void finish();
virtual bool finishWasCalled();
- HTMLViewSourceDocument* document() const { return static_cast<HTMLViewSourceDocument*>(m_document); }
+ HTMLViewSourceDocument* document() const { return static_cast<HTMLViewSourceDocument*>(DecodedDataDocumentParser::document()); }
void pumpTokenizer();
String sourceForToken();
@@ -69,7 +68,7 @@ private:
HTMLInputStream m_input;
SegmentedString m_source;
HTMLToken m_token;
- HTMLTokenizer m_tokenizer;
+ OwnPtr<HTMLTokenizer> m_tokenizer;
};
}
diff --git a/WebCore/html/LegacyHTMLTreeBuilder.cpp b/WebCore/html/LegacyHTMLTreeBuilder.cpp
deleted file mode 100644
index f39579c..0000000
--- a/WebCore/html/LegacyHTMLTreeBuilder.cpp
+++ /dev/null
@@ -1,1786 +0,0 @@
-/*
- Copyright (C) 1997 Martin Jones (mjones@kde.org)
- (C) 1997 Torben Weis (weis@kde.org)
- (C) 1999,2001 Lars Knoll (knoll@kde.org)
- (C) 2000,2001 Dirk Mueller (mueller@kde.org)
- Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009 Apple Inc. All rights reserved.
- Copyright (C) 2009 Torch Mobile Inc. All rights reserved. (http://www.torchmobile.com/)
-
- 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 "LegacyHTMLTreeBuilder.h"
-
-#include "CharacterNames.h"
-#include "CSSPropertyNames.h"
-#include "CSSValueKeywords.h"
-#include "Chrome.h"
-#include "ChromeClient.h"
-#include "Comment.h"
-#include "Console.h"
-#include "DOMWindow.h"
-#include "DocumentFragment.h"
-#include "DocumentType.h"
-#include "Frame.h"
-#include "HTMLBodyElement.h"
-#include "HTMLDocument.h"
-#include "HTMLDivElement.h"
-#include "HTMLDListElement.h"
-#include "HTMLElementFactory.h"
-#include "HTMLFormElement.h"
-#include "HTMLHeadElement.h"
-#include "HTMLHRElement.h"
-#include "HTMLHtmlElement.h"
-#include "HTMLIsIndexElement.h"
-#include "HTMLMapElement.h"
-#include "HTMLNames.h"
-#include "HTMLParserQuirks.h"
-#include "HTMLTableCellElement.h"
-#include "HTMLTableRowElement.h"
-#include "HTMLTableSectionElement.h"
-#include "LocalizedStrings.h"
-#include "Page.h"
-#include "ScriptableDocumentParser.h"
-#include "Settings.h"
-#include "Text.h"
-#include "TreeDepthLimit.h"
-#include <wtf/StdLibExtras.h>
-#include <wtf/dtoa.h>
-
-namespace WebCore {
-
-using namespace HTMLNames;
-
-static const unsigned cMaxRedundantTagDepth = 20;
-static const unsigned cResidualStyleMaxDepth = 200;
-static const unsigned cResidualStyleIterationLimit = 10;
-
-
-static const int minBlockLevelTagPriority = 3;
-
-// A cap on the number of tags with priority minBlockLevelTagPriority or higher
-// allowed in m_blockStack. The cap is enforced by adding such new elements as
-// siblings instead of children once it is reached.
-static const size_t cMaxBlockDepth = 4096;
-
-
-typedef HashSet<AtomicStringImpl*> TagNameSet;
-
-template< size_t ArraySize >
-static void addTags(TagNameSet& set, QualifiedName (&names)[ArraySize])
-{
- for (size_t x = 0; x < ArraySize; x++) {
- const QualifiedName& name = names[x];
- set.add(name.localName().impl());
- }
-}
-
-struct HTMLStackElem : Noncopyable {
- HTMLStackElem(const AtomicString& t, int lvl, Node* n, bool r, HTMLStackElem* nx)
- : tagName(t)
- , level(lvl)
- , strayTableContent(false)
- , node(n)
- , didRefNode(r)
- , next(nx)
- {
- }
-
- void derefNode()
- {
- if (didRefNode)
- node->deref();
- }
-
- AtomicString tagName;
- int level;
- bool strayTableContent;
- Node* node;
- bool didRefNode;
- HTMLStackElem* next;
-};
-
-/**
- * The parser parses tokenized input into the document, building up the
- * document tree. If the document is well-formed, parsing it is straightforward.
- *
- * Unfortunately, we have to handle many HTML documents that are not well-formed,
- * so the parser has to be tolerant about errors.
- *
- * We have to take care of at least the following error conditions:
- *
- * 1. The element being added is explicitly forbidden inside some outer tag.
- * In this case we should close all tags up to the one, which forbids
- * the element, and add it afterwards.
- *
- * 2. We are not allowed to add the element directly. It could be that
- * the person writing the document forgot some tag in between (or that the
- * tag in between is optional). This could be the case with the following
- * tags: HTML HEAD BODY TBODY TR TD LI (did I forget any?).
- *
- * 3. We want to add a block element inside to an inline element. Close all
- * inline elements up to the next higher block element.
- *
- * 4. If this doesn't help, close elements until we are allowed to add the
- * element or ignore the tag.
- *
- */
-
-LegacyHTMLTreeBuilder::LegacyHTMLTreeBuilder(HTMLDocument* doc, bool reportErrors)
- : m_document(doc)
- , m_current(doc)
- , m_didRefCurrent(false)
- , m_blockStack(0)
- , m_blocksInStack(0)
- , m_treeDepth(0)
- , m_hasPElementInScope(NotInScope)
- , m_inBody(false)
- , m_haveContent(false)
- , m_haveFrameSet(false)
- , m_isParsingFragment(false)
- , m_reportErrors(reportErrors)
- , m_handlingResidualStyleAcrossBlocks(false)
- , m_inStrayTableContent(0)
- , m_scriptingPermission(FragmentScriptingAllowed)
- , m_parserQuirks(m_document->page() ? m_document->page()->chrome()->client()->createHTMLParserQuirks() : 0)
-{
-}
-
-LegacyHTMLTreeBuilder::LegacyHTMLTreeBuilder(DocumentFragment* frag, FragmentScriptingPermission scriptingPermission)
- : m_document(frag->document())
- , m_current(frag)
- , m_didRefCurrent(true)
- , m_blockStack(0)
- , m_blocksInStack(0)
- , m_treeDepth(0)
- , m_hasPElementInScope(NotInScope)
- , m_inBody(true)
- , m_haveContent(false)
- , m_haveFrameSet(false)
- , m_isParsingFragment(true)
- , m_reportErrors(false)
- , m_handlingResidualStyleAcrossBlocks(false)
- , m_inStrayTableContent(0)
- , m_scriptingPermission(scriptingPermission)
- , m_parserQuirks(m_document->page() ? m_document->page()->chrome()->client()->createHTMLParserQuirks() : 0)
-{
- if (frag)
- frag->ref();
-}
-
-LegacyHTMLTreeBuilder::~LegacyHTMLTreeBuilder()
-{
- freeBlock();
- if (m_didRefCurrent)
- m_current->deref();
-}
-
-void LegacyHTMLTreeBuilder::reset()
-{
- ASSERT(!m_isParsingFragment);
-
- setCurrent(m_document);
-
- freeBlock();
-
- m_treeDepth = 0;
- m_inBody = false;
- m_haveFrameSet = false;
- m_haveContent = false;
- m_inStrayTableContent = 0;
-
- m_currentFormElement = 0;
- m_currentMapElement = 0;
- m_head = 0;
- m_isindexElement = 0;
-
- m_skipModeTag = nullAtom;
-
- if (m_parserQuirks)
- m_parserQuirks->reset();
-}
-
-void LegacyHTMLTreeBuilder::setCurrent(Node* newCurrent)
-{
- bool didRefNewCurrent = newCurrent && newCurrent != m_document;
- if (didRefNewCurrent)
- newCurrent->ref();
- if (m_didRefCurrent)
- m_current->deref();
- m_current = newCurrent;
- m_didRefCurrent = didRefNewCurrent;
-}
-
-inline static int tagPriorityOfNode(Node* n)
-{
- return n->isHTMLElement() ? static_cast<HTMLElement*>(n)->tagPriority() : 0;
-}
-
-inline void LegacyHTMLTreeBuilder::limitDepth(int tagPriority)
-{
- while (m_treeDepth >= maxDOMTreeDepth)
- popBlock(m_blockStack->tagName);
- if (tagPriority >= minBlockLevelTagPriority) {
- while (m_blocksInStack >= cMaxBlockDepth)
- popBlock(m_blockStack->tagName);
- }
-}
-
-inline bool LegacyHTMLTreeBuilder::insertNodeAfterLimitDepth(Node* n, bool flat)
-{
- limitDepth(tagPriorityOfNode(n));
- return insertNode(n, flat);
-}
-
-PassRefPtr<Node> LegacyHTMLTreeBuilder::parseToken(Token* t)
-{
- if (!m_skipModeTag.isNull()) {
- if (!t->beginTag && t->tagName == m_skipModeTag)
- // Found the end tag for the current skip mode, so we're done skipping.
- m_skipModeTag = nullAtom;
- else if (m_current->localName() == t->tagName)
- // Do not skip </iframe>.
- // FIXME: What does that comment mean? How can it be right to parse a token without clearing m_skipModeTag?
- ;
- else
- return 0;
- }
-
- // Apparently some sites use </br> instead of <br>. Be compatible with IE and Firefox and treat this like <br>.
- if (t->isCloseTag(brTag) && m_document->inCompatMode()) {
- reportError(MalformedBRError);
- t->beginTag = true;
- }
-
- if (!t->beginTag) {
- processCloseTag(t);
- return 0;
- }
-
- // Ignore spaces, if we're not inside a paragraph or other inline code.
- // Do not alter the text if it is part of a scriptTag.
- if (t->tagName == textAtom && t->text && m_current->localName() != scriptTag) {
- if (m_inBody && !skipMode() && m_current->localName() != styleTag &&
- m_current->localName() != titleTag && !t->text->containsOnlyWhitespace())
- m_haveContent = true;
-
- // HTML5 requires text node coalescing.
- // http://www.whatwg.org/specs/web-apps/current-work/multipage/tokenization.html#insert-a-character
- Node* previousChild = m_current->lastChild();
- if (previousChild && previousChild->isTextNode()) {
- // Only coalesce text nodes if the text node wouldn't be foster parented.
- if (!m_current->hasTagName(htmlTag)
- && !m_current->hasTagName(tableTag)
- && !m_current->hasTagName(trTag)
- && !m_current->hasTagName(theadTag)
- && !m_current->hasTagName(tbodyTag)
- && !m_current->hasTagName(tfootTag)
- && !m_current->hasTagName(titleTag)) {
- // Technically we're only supposed to merge into the previous
- // text node if it was the last node inserted by the parser.
- // (This was a spec modification made to make it easier for
- // mozilla to run their parser in a thread.)
- // In practice it does not seem to matter.
- CharacterData* textNode = static_cast<CharacterData*>(previousChild);
- textNode->parserAppendData(t->text);
- return textNode;
- }
- }
-
- RefPtr<Node> n;
- String text = t->text.get();
- unsigned charsLeft = text.length();
- while (charsLeft) {
- // split large blocks of text to nodes of manageable size
- n = Text::createWithLengthLimit(m_document, text, charsLeft);
- if (!insertNodeAfterLimitDepth(n.get(), t->selfClosingTag))
- return 0;
- }
- return n;
- }
-
- RefPtr<Node> n = getNode(t);
- // just to be sure, and to catch currently unimplemented stuff
- if (!n)
- return 0;
-
- // set attributes
- if (n->isHTMLElement()) {
- HTMLElement* e = static_cast<HTMLElement*>(n.get());
- if (m_scriptingPermission == FragmentScriptingAllowed || t->tagName != scriptTag)
- e->setAttributeMap(t->attrs.get(), m_scriptingPermission);
-
- // take care of optional close tags
- if (e->endTagRequirement() == TagStatusOptional)
- popBlock(t->tagName);
-
- // If the node does not have a forbidden end tag requirement, and if the broken XML self-closing
- // syntax was used, report an error.
- if (t->brokenXMLStyle && e->endTagRequirement() != TagStatusForbidden) {
- if (t->tagName == scriptTag)
- reportError(IncorrectXMLCloseScriptWarning);
- else
- reportError(IncorrectXMLSelfCloseError, &t->tagName);
- }
- }
-
- if (!insertNodeAfterLimitDepth(n.get(), t->selfClosingTag)) {
- // we couldn't insert the node
-
- if (n->isElementNode()) {
- Element* e = static_cast<Element*>(n.get());
- e->setAttributeMap(0);
- }
-
- if (m_currentMapElement == n)
- m_currentMapElement = 0;
-
- if (m_currentFormElement == n)
- m_currentFormElement = 0;
-
- if (m_head == n)
- m_head = 0;
-
- return 0;
- }
- return n;
-}
-
-void LegacyHTMLTreeBuilder::parseDoctypeToken(DoctypeToken* t)
-{
- // Ignore any doctype after the first. Ignore doctypes in fragments.
- if (m_document->doctype() || m_isParsingFragment || m_current != m_document)
- return;
-
- // Make a new doctype node and set it as our doctype.
- m_document->legacyParserAddChild(DocumentType::create(m_document, String::adopt(t->m_name), String::adopt(t->m_publicID), String::adopt(t->m_systemID)));
- if (t->m_forceQuirks)
- m_document->setParseMode(Document::Compat);
-}
-
-static bool isTableSection(const Node* n)
-{
- return n->hasTagName(tbodyTag) || n->hasTagName(tfootTag) || n->hasTagName(theadTag);
-}
-
-static bool isTablePart(const Node* n)
-{
- return n->hasTagName(trTag) || n->hasTagName(tdTag) || n->hasTagName(thTag)
- || isTableSection(n);
-}
-
-static bool isTableRelated(const Node* n)
-{
- return n->hasTagName(tableTag) || isTablePart(n);
-}
-
-static bool isScopingTag(const AtomicString& tagName)
-{
- return tagName == appletTag || tagName == captionTag || tagName == tdTag
- || tagName == thTag || tagName == buttonTag || tagName == marqueeTag
- || tagName == objectTag || tagName == tableTag || tagName == htmlTag;
-}
-
-bool LegacyHTMLTreeBuilder::insertNode(Node* n, bool flat)
-{
- RefPtr<Node> protectNode(n);
-
- const AtomicString& localName = n->localName();
-
- // <table> is never allowed inside stray table content. Always pop out of the stray table content
- // and close up the first table, and then start the second table as a sibling.
- if (m_inStrayTableContent && localName == tableTag)
- popBlock(tableTag);
-
- if (m_parserQuirks && !m_parserQuirks->shouldInsertNode(m_current, n))
- return false;
-
- int tagPriority = tagPriorityOfNode(n);
-
- // let's be stupid and just try to insert it.
- // this should work if the document is well-formed
- Node* newNode = m_current->legacyParserAddChild(n);
- if (!newNode)
- return handleError(n, flat, localName, tagPriority); // Try to handle the error.
-
- // don't push elements without end tags (e.g., <img>) on the stack
- bool parentAttached = m_current->attached();
- if (tagPriority > 0 && !flat) {
- if (newNode == m_current) {
- // This case should only be hit when a demoted <form> is placed inside a table.
- ASSERT(localName == formTag);
- reportError(FormInsideTablePartError, &m_current->localName());
- HTMLFormElement* form = static_cast<HTMLFormElement*>(n);
- form->setDemoted(true);
- } else {
- // The pushBlock function transfers ownership of current to the block stack
- // so we're guaranteed that m_didRefCurrent is false. The code below is an
- // optimized version of setCurrent that takes advantage of that fact and also
- // assumes that newNode is neither 0 nor a pointer to the document.
- pushBlock(localName, tagPriority);
- newNode->beginParsingChildren();
- ASSERT(!m_didRefCurrent);
- newNode->ref();
- m_current = newNode;
- m_didRefCurrent = true;
- }
- if (parentAttached && !n->attached() && !m_isParsingFragment)
- n->attach();
- } else {
- if (parentAttached && !n->attached() && !m_isParsingFragment)
- n->attach();
- n->finishParsingChildren();
- }
-
- if (localName == htmlTag && m_document->frame() && !m_isParsingFragment)
- m_document->frame()->loader()->dispatchDocumentElementAvailable();
-
- return true;
-}
-
-bool LegacyHTMLTreeBuilder::handleError(Node* n, bool flat, const AtomicString& localName, int tagPriority)
-{
- // Error handling code. This is just ad hoc handling of specific parent/child combinations.
- bool handled = false;
-
- // 1. Check out the element's tag name to decide how to deal with errors.
- if (n->isHTMLElement()) {
- HTMLElement* h = static_cast<HTMLElement*>(n);
- if (h->hasLocalName(trTag) || h->hasLocalName(thTag) || h->hasLocalName(tdTag)) {
- if (m_inStrayTableContent && !isTableRelated(m_current)) {
- reportError(MisplacedTablePartError, &localName, &m_current->localName());
- // pop out to the nearest enclosing table-related tag.
- while (m_blockStack && !isTableRelated(m_current))
- popOneBlock();
- return insertNode(n);
- }
- } else if (h->hasLocalName(headTag)) {
- if (!m_current->isDocumentNode() && !m_current->hasTagName(htmlTag)) {
- reportError(MisplacedHeadError);
- return false;
- }
- } else if (h->hasLocalName(metaTag) || h->hasLocalName(linkTag) || h->hasLocalName(baseTag)) {
- bool createdHead = false;
- if (!m_head) {
- createHead();
- createdHead = true;
- }
- if (m_head) {
- if (!createdHead)
- reportError(MisplacedHeadContentError, &localName, &m_current->localName());
- if (m_head->legacyParserAddChild(n)) {
- if (!n->attached() && !m_isParsingFragment)
- n->attach();
- return true;
- }
- return false;
- }
- } else if (h->hasLocalName(htmlTag)) {
- if (!m_current->isDocumentNode() ) {
- if (m_document->documentElement() && m_document->documentElement()->hasTagName(htmlTag) && !m_isParsingFragment) {
- reportError(RedundantHTMLBodyError, &localName);
- // we have another <HTML> element.... apply attributes to existing one
- // make sure we don't overwrite already existing attributes
- NamedNodeMap* map = static_cast<Element*>(n)->attributes(true);
- Element* existingHTML = static_cast<Element*>(m_document->documentElement());
- NamedNodeMap* bmap = existingHTML->attributes(false);
- for (unsigned l = 0; map && l < map->length(); ++l) {
- Attribute* it = map->attributeItem(l);
- if (!bmap->getAttributeItem(it->name()))
- existingHTML->setAttribute(it->name(), it->value());
- }
- }
- return false;
- }
- } else if (h->hasLocalName(titleTag) || h->hasLocalName(styleTag) || h->hasLocalName(scriptTag)) {
- bool createdHead = false;
- if (!m_head) {
- createHead();
- createdHead = true;
- }
- if (m_head) {
- Node* newNode = m_head->legacyParserAddChild(n);
- if (!newNode) {
- setSkipMode(h->tagQName());
- return false;
- }
-
- if (!createdHead)
- reportError(MisplacedHeadContentError, &localName, &m_current->localName());
-
- pushBlock(localName, tagPriority);
- newNode->beginParsingChildren();
- setCurrent(newNode);
- if (!n->attached() && !m_isParsingFragment)
- n->attach();
- return true;
- }
- if (m_inBody) {
- setSkipMode(h->tagQName());
- return false;
- }
- } else if (h->hasLocalName(bodyTag)) {
- if (m_inBody && m_document->body() && !m_isParsingFragment) {
- // we have another <BODY> element.... apply attributes to existing one
- // make sure we don't overwrite already existing attributes
- // some sites use <body bgcolor=rightcolor>...<body bgcolor=wrongcolor>
- reportError(RedundantHTMLBodyError, &localName);
- NamedNodeMap* map = static_cast<Element*>(n)->attributes(true);
- Element* existingBody = m_document->body();
- NamedNodeMap* bmap = existingBody->attributes(false);
- for (unsigned l = 0; map && l < map->length(); ++l) {
- Attribute* it = map->attributeItem(l);
- if (!bmap->getAttributeItem(it->name()))
- existingBody->setAttribute(it->name(), it->value());
- }
- return false;
- } else if (!m_current->isDocumentNode())
- return false;
- } else if (h->hasLocalName(areaTag)) {
- if (m_currentMapElement) {
- reportError(MisplacedAreaError, &m_current->localName());
- m_currentMapElement->legacyParserAddChild(n);
- if (!n->attached() && !m_isParsingFragment)
- n->attach();
- handled = true;
- return true;
- }
- return false;
- } else if (h->hasLocalName(colgroupTag) || h->hasLocalName(captionTag)) {
- if (isTableRelated(m_current)) {
- while (m_blockStack && isTablePart(m_current))
- popOneBlock();
- return insertNode(n);
- }
- }
- } else if (n->isCommentNode() && !m_head)
- return false;
-
- // 2. Next we examine our currently active element to do some further error handling.
- if (m_current->isHTMLElement()) {
- HTMLElement* h = static_cast<HTMLElement*>(m_current);
- const AtomicString& currentTagName = h->localName();
- if (h->hasLocalName(htmlTag)) {
- HTMLElement* elt = n->isHTMLElement() ? static_cast<HTMLElement*>(n) : 0;
- if (elt && (elt->hasLocalName(scriptTag) || elt->hasLocalName(styleTag) ||
- elt->hasLocalName(metaTag) || elt->hasLocalName(linkTag) ||
- elt->hasLocalName(objectTag) || elt->hasLocalName(embedTag) ||
- elt->hasLocalName(titleTag) || elt->hasLocalName(isindexTag) ||
- elt->hasLocalName(baseTag))) {
- if (!m_head) {
- m_head = HTMLHeadElement::create(m_document);
- insertNode(m_head.get());
- handled = true;
- }
- } else {
- if (n->isTextNode()) {
- Text* t = static_cast<Text*>(n);
- if (t->containsOnlyWhitespace()) {
- if (m_head && !m_inBody) {
- // We're between </head> and <body>. According to
- // the HTML5 parsing algorithm, we're supposed to
- // insert whitespace text nodes into the HTML element.
- ExceptionCode ec;
- m_current->appendChild(n, ec);
- return true;
- }
- return false;
- }
- }
- if (!m_haveFrameSet) {
- // Ensure that head exists.
- // But not for older versions of Mail, where the implicit <head> isn't expected - <rdar://problem/6863795>
- if (!m_isParsingFragment && shouldCreateImplicitHead(m_document))
- createHead();
-
- popBlock(headTag);
- startBody();
- insertNode(HTMLBodyElement::create(m_document).get());
- handled = true;
- } else
- reportError(MisplacedFramesetContentError, &localName);
- }
- } else if (h->hasLocalName(headTag)) {
- if (n->hasTagName(htmlTag))
- return false;
- else {
- // This means the body starts here...
- if (!m_haveFrameSet) {
- ASSERT(currentTagName == headTag);
- popBlock(currentTagName);
- startBody();
- insertNode(HTMLBodyElement::create(m_document).get());
- handled = true;
- } else
- reportError(MisplacedFramesetContentError, &localName);
- }
- } else if (h->hasLocalName(addressTag) || h->hasLocalName(fontTag)
- || h->hasLocalName(styleTag) || h->hasLocalName(titleTag)) {
- reportError(MisplacedContentRetryError, &localName, &currentTagName);
- popBlock(currentTagName);
- handled = true;
- } else if (h->hasLocalName(captionTag)) {
- // Illegal content in a caption. Close the caption and try again.
- reportError(MisplacedCaptionContentError, &localName);
- popBlock(currentTagName);
- if (isTablePart(n))
- return insertNode(n, flat);
- } else if (h->hasLocalName(tableTag) || h->hasLocalName(trTag) || isTableSection(h)) {
- if (n->hasTagName(tableTag)) {
- reportError(MisplacedTableError, &currentTagName);
- if (m_isParsingFragment && !h->hasLocalName(tableTag))
- // fragment may contain table parts without <table> ancestor, pop them one by one
- popBlock(h->localName());
- popBlock(localName); // end the table
- handled = true; // ...and start a new one
- } else {
- ExceptionCode ec = 0;
- Node* node = m_current;
- Node* parent = node->parentNode();
- // A script may have removed the current node's parent from the DOM
- // http://bugs.webkit.org/show_bug.cgi?id=7137
- // FIXME: we should do real recovery here and re-parent with the correct node.
- if (!parent)
- return false;
- Node* grandparent = parent->parentNode();
-
- if (n->isTextNode() ||
- (h->hasLocalName(trTag) &&
- isTableSection(parent) && grandparent && grandparent->hasTagName(tableTag)) ||
- ((!n->hasTagName(tdTag) && !n->hasTagName(thTag) &&
- !n->hasTagName(formTag) && !n->hasTagName(scriptTag)) && isTableSection(node) &&
- parent->hasTagName(tableTag))) {
- node = (node->hasTagName(tableTag)) ? node :
- ((node->hasTagName(trTag)) ? grandparent : parent);
- // This can happen with fragments
- if (!node)
- return false;
- Node* parent = node->parentNode();
- if (!parent)
- return false;
- parent->insertBefore(n, node, ec);
- if (!ec) {
- reportError(StrayTableContentError, &localName, &currentTagName);
- if (n->isHTMLElement() && tagPriority > 0 &&
- !flat && static_cast<HTMLElement*>(n)->endTagRequirement() != TagStatusForbidden)
- {
- pushBlock(localName, tagPriority);
- n->beginParsingChildren();
- setCurrent(n);
- m_inStrayTableContent++;
- m_blockStack->strayTableContent = true;
- }
- return true;
- }
- }
-
- if (!ec) {
- if (m_current->hasTagName(trTag)) {
- reportError(TablePartRequiredError, &localName, &tdTag.localName());
- insertNode(HTMLTableCellElement::create(tdTag, m_document).get());
- } else if (m_current->hasTagName(tableTag)) {
- // Don't report an error in this case, since making a <tbody> happens all the time when you have <table><tr>,
- // and it isn't really a parse error per se.
- insertNode(HTMLTableSectionElement::create(tbodyTag, m_document).get());
- } else {
- reportError(TablePartRequiredError, &localName, &trTag.localName());
- insertNode(HTMLTableRowElement::create(m_document).get());
- }
- handled = true;
- }
- }
- } else if (h->hasLocalName(objectTag)) {
- reportError(MisplacedContentRetryError, &localName, &currentTagName);
- popBlock(objectTag);
- handled = true;
- } else if (h->hasLocalName(pTag) || isHeadingTag(currentTagName)) {
- if (!isInline(n)) {
- popBlock(currentTagName);
- handled = true;
- }
- } else if (h->hasLocalName(optionTag) || h->hasLocalName(optgroupTag)) {
- if (localName == optgroupTag) {
- popBlock(currentTagName);
- handled = true;
- } else if (localName == selectTag) {
- // IE treats a nested select as </select>. Let's do the same
- popBlock(localName);
- }
- } else if (h->hasLocalName(selectTag)) {
- if (localName == inputTag || localName == textareaTag) {
- reportError(MisplacedContentRetryError, &localName, &currentTagName);
- popBlock(currentTagName);
- handled = true;
- }
- } else if (h->hasLocalName(colgroupTag)) {
- popBlock(currentTagName);
- handled = true;
- } else if (!h->hasLocalName(bodyTag)) {
- if (isInline(m_current)) {
- popInlineBlocks();
- handled = true;
- }
- }
- } else if (m_current->isDocumentNode()) {
- if (n->isTextNode()) {
- Text* t = static_cast<Text*>(n);
- if (t->containsOnlyWhitespace())
- return false;
- }
-
- if (!m_document->documentElement()) {
- insertNode(HTMLHtmlElement::create(m_document).get());
- handled = true;
- }
- }
-
- // 3. If we couldn't handle the error, just return false and attempt to error-correct again.
- if (!handled) {
- reportError(IgnoredContentError, &localName, &m_current->localName());
- return false;
- }
- return insertNode(n);
-}
-
-typedef bool (LegacyHTMLTreeBuilder::*CreateErrorCheckFunc)(Token* t, RefPtr<Node>&);
-typedef HashMap<AtomicStringImpl*, CreateErrorCheckFunc> FunctionMap;
-
-bool LegacyHTMLTreeBuilder::textCreateErrorCheck(Token* t, RefPtr<Node>& result)
-{
- result = Text::create(m_document, t->text.get());
- return false;
-}
-
-bool LegacyHTMLTreeBuilder::commentCreateErrorCheck(Token* t, RefPtr<Node>& result)
-{
- result = Comment::create(m_document, t->text.get());
- return false;
-}
-
-bool LegacyHTMLTreeBuilder::headCreateErrorCheck(Token*, RefPtr<Node>& result)
-{
- if (!m_head || m_current->localName() == htmlTag) {
- m_head = HTMLHeadElement::create(m_document);
- result = m_head;
- } else
- reportError(MisplacedHeadError);
- return false;
-}
-
-bool LegacyHTMLTreeBuilder::bodyCreateErrorCheck(Token*, RefPtr<Node>&)
-{
- // body no longer allowed if we have a frameset
- if (m_haveFrameSet)
- return false;
-
- // Ensure that head exists (unless parsing a fragment).
- // But not for older versions of Mail, where the implicit <head> isn't expected - <rdar://problem/6863795>
- if (!m_isParsingFragment && shouldCreateImplicitHead(m_document))
- createHead();
-
- popBlock(headTag);
- startBody();
- return true;
-}
-
-bool LegacyHTMLTreeBuilder::framesetCreateErrorCheck(Token*, RefPtr<Node>&)
-{
- popBlock(headTag);
- if (m_inBody && !m_haveFrameSet && !m_haveContent) {
- popBlock(bodyTag);
- // ### actually for IE document.body returns the now hidden "body" element
- // we can't implement that behaviour now because it could cause too many
- // regressions and the headaches are not worth the work as long as there is
- // no site actually relying on that detail (Dirk)
- if (m_document->body() && !m_isParsingFragment)
- m_document->body()->setAttribute(styleAttr, "display:none");
- m_inBody = false;
- }
- if ((m_haveContent || m_haveFrameSet) && m_current->localName() == htmlTag)
- return false;
- m_haveFrameSet = true;
- startBody();
- return true;
-}
-
-bool LegacyHTMLTreeBuilder::formCreateErrorCheck(Token* t, RefPtr<Node>& result)
-{
- // Only create a new form if we're not already inside one.
- // This is consistent with other browsers' behavior.
- if (!m_currentFormElement) {
- m_currentFormElement = HTMLFormElement::create(m_document);
- result = m_currentFormElement;
- pCloserCreateErrorCheck(t, result);
- }
- return false;
-}
-
-bool LegacyHTMLTreeBuilder::isindexCreateErrorCheck(Token* t, RefPtr<Node>& result)
-{
- RefPtr<Node> n = handleIsindex(t);
- if (!m_inBody)
- m_isindexElement = n.release();
- else {
- t->selfClosingTag = true;
- result = n.release();
- }
- return false;
-}
-
-bool LegacyHTMLTreeBuilder::selectCreateErrorCheck(Token*, RefPtr<Node>&)
-{
- return true;
-}
-
-bool LegacyHTMLTreeBuilder::ddCreateErrorCheck(Token* t, RefPtr<Node>& result)
-{
- pCloserCreateErrorCheck(t, result);
- popBlock(dtTag);
- popBlock(ddTag);
- return true;
-}
-
-bool LegacyHTMLTreeBuilder::dtCreateErrorCheck(Token* t, RefPtr<Node>& result)
-{
- pCloserCreateErrorCheck(t, result);
- popBlock(ddTag);
- popBlock(dtTag);
- return true;
-}
-
-bool LegacyHTMLTreeBuilder::rpCreateErrorCheck(Token*, RefPtr<Node>&)
-{
- popBlock(rpTag);
- popBlock(rtTag);
- return true;
-}
-
-bool LegacyHTMLTreeBuilder::rtCreateErrorCheck(Token*, RefPtr<Node>&)
-{
- popBlock(rpTag);
- popBlock(rtTag);
- return true;
-}
-
-bool LegacyHTMLTreeBuilder::nestedCreateErrorCheck(Token* t, RefPtr<Node>&)
-{
- popBlock(t->tagName);
- return true;
-}
-
-bool LegacyHTMLTreeBuilder::nestedPCloserCreateErrorCheck(Token* t, RefPtr<Node>& result)
-{
- pCloserCreateErrorCheck(t, result);
- popBlock(t->tagName);
- return true;
-}
-
-bool LegacyHTMLTreeBuilder::nestedStyleCreateErrorCheck(Token* t, RefPtr<Node>&)
-{
- return allowNestedRedundantTag(t->tagName);
-}
-
-bool LegacyHTMLTreeBuilder::colCreateErrorCheck(Token*, RefPtr<Node>&)
-{
- if (!m_current->hasTagName(tableTag))
- return true;
- RefPtr<Element> implicitColgroup = HTMLElementFactory::createHTMLElement(colgroupTag, m_document, 0, true);
- insertNode(implicitColgroup.get());
- return true;
-}
-
-bool LegacyHTMLTreeBuilder::tableCellCreateErrorCheck(Token*, RefPtr<Node>&)
-{
- popBlock(tdTag);
- popBlock(thTag);
- return true;
-}
-
-bool LegacyHTMLTreeBuilder::tableSectionCreateErrorCheck(Token*, RefPtr<Node>&)
-{
- popBlock(theadTag);
- popBlock(tbodyTag);
- popBlock(tfootTag);
- return true;
-}
-
-bool LegacyHTMLTreeBuilder::noembedCreateErrorCheck(Token*, RefPtr<Node>&)
-{
- setSkipMode(noembedTag);
- return true;
-}
-
-bool LegacyHTMLTreeBuilder::noframesCreateErrorCheck(Token*, RefPtr<Node>&)
-{
- setSkipMode(noframesTag);
- return true;
-}
-
-bool LegacyHTMLTreeBuilder::noscriptCreateErrorCheck(Token*, RefPtr<Node>&)
-{
- if (!m_isParsingFragment) {
- Frame* frame = m_document->frame();
- if (frame && frame->script()->canExecuteScripts(NotAboutToExecuteScript))
- setSkipMode(noscriptTag);
- }
- return true;
-}
-
-bool LegacyHTMLTreeBuilder::pCloserCreateErrorCheck(Token*, RefPtr<Node>&)
-{
- if (hasPElementInScope())
- popBlock(pTag);
- return true;
-}
-
-bool LegacyHTMLTreeBuilder::pCloserStrictCreateErrorCheck(Token*, RefPtr<Node>&)
-{
- if (m_document->inCompatMode())
- return true;
- if (hasPElementInScope())
- popBlock(pTag);
- return true;
-}
-
-bool LegacyHTMLTreeBuilder::mapCreateErrorCheck(Token*, RefPtr<Node>& result)
-{
- m_currentMapElement = HTMLMapElement::create(m_document);
- result = m_currentMapElement;
- return false;
-}
-
-static void mapTagToFunc(FunctionMap& map, const QualifiedName& tag, CreateErrorCheckFunc func)
-{
- map.set(tag.localName().impl(), func);
-}
-
-template< size_t ArraySize >
-static void mapTagsToFunc(FunctionMap& map, QualifiedName (&names)[ArraySize], CreateErrorCheckFunc func)
-{
- for (size_t x = 0; x < ArraySize; x++) {
- const QualifiedName& name = names[x];
- mapTagToFunc(map, name, func);
- }
-}
-
-PassRefPtr<Node> LegacyHTMLTreeBuilder::getNode(Token* t)
-{
- // Init our error handling table.
- DEFINE_STATIC_LOCAL(FunctionMap, gFunctionMap, ());
- if (gFunctionMap.isEmpty()) {
- QualifiedName nestedCreateErrorTags[] = { aTag, buttonTag, nobrTag, trTag };
- mapTagsToFunc(gFunctionMap, nestedCreateErrorTags, &LegacyHTMLTreeBuilder::nestedCreateErrorCheck);
-
- QualifiedName nestedStyleCreateErrorTags[] = { bTag, bigTag, iTag, markTag, sTag, smallTag, strikeTag, ttTag, uTag };
- mapTagsToFunc(gFunctionMap, nestedStyleCreateErrorTags, &LegacyHTMLTreeBuilder::nestedStyleCreateErrorCheck);
-
- QualifiedName pCloserCreateErrorTags[] = { addressTag, articleTag,
- asideTag, blockquoteTag, centerTag, dirTag, divTag, dlTag,
- fieldsetTag, footerTag, h1Tag, h2Tag, h3Tag, h4Tag, h5Tag, h6Tag,
- headerTag, hgroupTag, hrTag, listingTag, menuTag, navTag, olTag,
- pTag, plaintextTag, preTag, sectionTag, ulTag };
- mapTagsToFunc(gFunctionMap, pCloserCreateErrorTags, &LegacyHTMLTreeBuilder::pCloserCreateErrorCheck);
-
- mapTagToFunc(gFunctionMap, bodyTag, &LegacyHTMLTreeBuilder::bodyCreateErrorCheck);
- mapTagToFunc(gFunctionMap, colTag, &LegacyHTMLTreeBuilder::colCreateErrorCheck);
- mapTagToFunc(gFunctionMap, ddTag, &LegacyHTMLTreeBuilder::ddCreateErrorCheck);
- mapTagToFunc(gFunctionMap, dtTag, &LegacyHTMLTreeBuilder::dtCreateErrorCheck);
- mapTagToFunc(gFunctionMap, formTag, &LegacyHTMLTreeBuilder::formCreateErrorCheck);
- mapTagToFunc(gFunctionMap, framesetTag, &LegacyHTMLTreeBuilder::framesetCreateErrorCheck);
- mapTagToFunc(gFunctionMap, headTag, &LegacyHTMLTreeBuilder::headCreateErrorCheck);
- mapTagToFunc(gFunctionMap, isindexTag, &LegacyHTMLTreeBuilder::isindexCreateErrorCheck);
- mapTagToFunc(gFunctionMap, mapTag, &LegacyHTMLTreeBuilder::mapCreateErrorCheck);
- mapTagToFunc(gFunctionMap, liTag, &LegacyHTMLTreeBuilder::nestedPCloserCreateErrorCheck);
- mapTagToFunc(gFunctionMap, noembedTag, &LegacyHTMLTreeBuilder::noembedCreateErrorCheck);
- mapTagToFunc(gFunctionMap, noframesTag, &LegacyHTMLTreeBuilder::noframesCreateErrorCheck);
- mapTagToFunc(gFunctionMap, noscriptTag, &LegacyHTMLTreeBuilder::noscriptCreateErrorCheck);
- mapTagToFunc(gFunctionMap, tableTag, &LegacyHTMLTreeBuilder::pCloserStrictCreateErrorCheck);
- mapTagToFunc(gFunctionMap, rpTag, &LegacyHTMLTreeBuilder::rpCreateErrorCheck);
- mapTagToFunc(gFunctionMap, rtTag, &LegacyHTMLTreeBuilder::rtCreateErrorCheck);
- mapTagToFunc(gFunctionMap, selectTag, &LegacyHTMLTreeBuilder::selectCreateErrorCheck);
- mapTagToFunc(gFunctionMap, tdTag, &LegacyHTMLTreeBuilder::tableCellCreateErrorCheck);
- mapTagToFunc(gFunctionMap, thTag, &LegacyHTMLTreeBuilder::tableCellCreateErrorCheck);
- mapTagToFunc(gFunctionMap, tbodyTag, &LegacyHTMLTreeBuilder::tableSectionCreateErrorCheck);
- mapTagToFunc(gFunctionMap, tfootTag, &LegacyHTMLTreeBuilder::tableSectionCreateErrorCheck);
- mapTagToFunc(gFunctionMap, theadTag, &LegacyHTMLTreeBuilder::tableSectionCreateErrorCheck);
-
- gFunctionMap.set(commentAtom.impl(), &LegacyHTMLTreeBuilder::commentCreateErrorCheck);
- gFunctionMap.set(textAtom.impl(), &LegacyHTMLTreeBuilder::textCreateErrorCheck);
- }
-
- bool proceed = true;
- RefPtr<Node> result;
- if (CreateErrorCheckFunc errorCheckFunc = gFunctionMap.get(t->tagName.impl()))
- proceed = (this->*errorCheckFunc)(t, result);
- if (proceed)
- result = HTMLElementFactory::createHTMLElement(QualifiedName(nullAtom, t->tagName, xhtmlNamespaceURI), m_document, m_currentFormElement.get());
- return result.release();
-}
-
-bool LegacyHTMLTreeBuilder::allowNestedRedundantTag(const AtomicString& tagName)
-{
- // www.liceo.edu.mx is an example of a site that achieves a level of nesting of
- // about 1500 tags, all from a bunch of <b>s. We will only allow at most 20
- // nested tags of the same type before just ignoring them all together.
- unsigned i = 0;
- for (HTMLStackElem* curr = m_blockStack;
- i < cMaxRedundantTagDepth && curr && curr->tagName == tagName;
- curr = curr->next, i++) { }
- return i != cMaxRedundantTagDepth;
-}
-
-void LegacyHTMLTreeBuilder::processCloseTag(Token* t)
-{
- // Support for really broken html.
- // we never close the body tag, since some stupid web pages close it before the actual end of the doc.
- // let's rely on the end() call to close things.
- if (t->tagName == htmlTag || t->tagName == bodyTag || t->tagName == commentAtom)
- return;
-
- bool checkForCloseTagErrors = true;
- if (t->tagName == formTag && m_currentFormElement) {
- m_currentFormElement = 0;
- checkForCloseTagErrors = false;
- } else if (t->tagName == mapTag)
- m_currentMapElement = 0;
- else if (t->tagName == pTag)
- checkForCloseTagErrors = false;
-
- HTMLStackElem* oldElem = m_blockStack;
- popBlock(t->tagName, checkForCloseTagErrors);
- if (oldElem == m_blockStack && t->tagName == pTag) {
- // We encountered a stray </p>. Amazingly Gecko, WinIE, and MacIE all treat
- // this as a valid break, i.e., <p></p>. So go ahead and make the empty
- // paragraph.
- t->beginTag = true;
- parseToken(t);
- popBlock(t->tagName);
- reportError(StrayParagraphCloseError);
- }
-}
-
-bool LegacyHTMLTreeBuilder::isHeadingTag(const AtomicString& tagName)
-{
- DEFINE_STATIC_LOCAL(TagNameSet, headingTags, ());
- if (headingTags.isEmpty()) {
- QualifiedName tagNames[] = { h1Tag, h2Tag, h3Tag, h4Tag, h5Tag, h6Tag };
- addTags(headingTags, tagNames);
- }
- return headingTags.contains(tagName.impl());
-}
-
-bool LegacyHTMLTreeBuilder::isInline(Node* node) const
-{
- if (node->isTextNode())
- return true;
-
- if (node->isHTMLElement()) {
- HTMLElement* e = static_cast<HTMLElement*>(node);
- if (e->hasLocalName(aTag) || e->hasLocalName(fontTag) || e->hasLocalName(ttTag) ||
- e->hasLocalName(uTag) || e->hasLocalName(bTag) || e->hasLocalName(iTag) ||
- e->hasLocalName(sTag) || e->hasLocalName(strikeTag) || e->hasLocalName(bigTag) ||
- e->hasLocalName(smallTag) || e->hasLocalName(emTag) || e->hasLocalName(strongTag) ||
- e->hasLocalName(dfnTag) || e->hasLocalName(codeTag) || e->hasLocalName(sampTag) ||
- e->hasLocalName(kbdTag) || e->hasLocalName(varTag) || e->hasLocalName(citeTag) ||
- e->hasLocalName(abbrTag) || e->hasLocalName(acronymTag) || e->hasLocalName(subTag) ||
- e->hasLocalName(supTag) || e->hasLocalName(spanTag) || e->hasLocalName(nobrTag) ||
- e->hasLocalName(noframesTag) || e->hasLocalName(nolayerTag) ||
- e->hasLocalName(noembedTag) || e->hasLocalName(markTag))
- return true;
-#if !ENABLE(XHTMLMP)
- if (e->hasLocalName(noscriptTag) && !m_isParsingFragment) {
- Frame* frame = m_document->frame();
- if (frame && frame->script()->canExecuteScripts(NotAboutToExecuteScript))
- return true;
- }
-#endif
- }
-
- return false;
-}
-
-bool LegacyHTMLTreeBuilder::isResidualStyleTag(const AtomicString& tagName)
-{
- DEFINE_STATIC_LOCAL(HashSet<AtomicStringImpl*>, residualStyleTags, ());
- if (residualStyleTags.isEmpty()) {
- QualifiedName tagNames[] = { aTag, fontTag, ttTag, uTag, bTag, iTag,
- sTag, strikeTag, bigTag, smallTag, emTag, strongTag, dfnTag,
- codeTag, sampTag, kbdTag, varTag, nobrTag, markTag };
- addTags(residualStyleTags, tagNames);
- }
- return residualStyleTags.contains(tagName.impl());
-}
-
-bool LegacyHTMLTreeBuilder::isAffectedByResidualStyle(const AtomicString& tagName)
-{
- DEFINE_STATIC_LOCAL(HashSet<AtomicStringImpl*>, unaffectedTags, ());
- if (unaffectedTags.isEmpty()) {
- QualifiedName tagNames[] = { bodyTag, tableTag, theadTag, tbodyTag,
- tfootTag, trTag, thTag, tdTag, captionTag, colgroupTag, colTag,
- optionTag, optgroupTag, selectTag, objectTag, datagridTag, datalistTag };
- addTags(unaffectedTags, tagNames);
- }
- return !unaffectedTags.contains(tagName.impl());
-}
-
-void LegacyHTMLTreeBuilder::handleResidualStyleCloseTagAcrossBlocks(HTMLStackElem* elem)
-{
- HTMLStackElem* maxElem = 0;
- bool finished = false;
- bool strayTableContent = elem->strayTableContent;
-
- unsigned iterationCount = 0;
-
- m_handlingResidualStyleAcrossBlocks = true;
- while (!finished && (iterationCount++ < cResidualStyleIterationLimit)) {
- // Find the outermost element that crosses over to a higher level. If there exists another higher-level
- // element, we will do another pass, until we have corrected the innermost one.
- ExceptionCode ec = 0;
- HTMLStackElem* curr = m_blockStack;
- HTMLStackElem* prev = 0;
- HTMLStackElem* prevMaxElem = 0;
- maxElem = 0;
- finished = true;
- while (curr && curr != elem) {
- if (curr->level > elem->level) {
- if (!isAffectedByResidualStyle(curr->tagName))
- return;
- if (maxElem)
- // We will need another pass.
- finished = false;
- maxElem = curr;
- prevMaxElem = prev;
- }
-
- prev = curr;
- curr = curr->next;
- }
-
- if (!curr || !maxElem)
- return;
-
- Node* residualElem = prev->node;
- Node* blockElem = prevMaxElem ? prevMaxElem->node : m_current;
- Node* parentElem = elem->node;
-
- // Check to see if the reparenting that is going to occur is allowed according to the DOM.
- // FIXME: We should either always allow it or perform an additional fixup instead of
- // just bailing here.
- // Example: <p><font><center>blah</font></center></p> isn't doing a fixup right now.
- if (!parentElem->childAllowed(blockElem))
- return;
-
- m_hasPElementInScope = Unknown;
-
- if (maxElem->node->parentNode() != elem->node) {
- // Walk the stack and remove any elements that aren't residual style tags. These
- // are basically just being closed up. Example:
- // <font><span>Moo<p>Goo</font></p>.
- // In the above example, the <span> doesn't need to be reopened. It can just close.
- HTMLStackElem* currElem = maxElem->next;
- HTMLStackElem* prevElem = maxElem;
- while (currElem != elem) {
- HTMLStackElem* nextElem = currElem->next;
- if (!isResidualStyleTag(currElem->tagName)) {
- prevElem->next = nextElem;
- prevElem->derefNode();
- prevElem->node = currElem->node;
- prevElem->didRefNode = currElem->didRefNode;
- delete currElem;
- m_treeDepth--;
- } else
- prevElem = currElem;
- currElem = nextElem;
- }
-
- // We have to reopen residual tags in between maxElem and elem. An example of this case is:
- // <font><i>Moo<p>Foo</font>.
- // In this case, we need to transform the part before the <p> into:
- // <font><i>Moo</i></font><i>
- // so that the <i> will remain open. This involves the modification of elements
- // in the block stack.
- // This will also affect how we ultimately reparent the block, since we want it to end up
- // under the reopened residual tags (e.g., the <i> in the above example.)
- RefPtr<Node> prevNode = 0;
- currElem = maxElem;
- while (currElem->node != residualElem) {
- if (isResidualStyleTag(currElem->node->localName())) {
- // Create a clone of this element.
- // We call releaseRef to get a raw pointer since we plan to hand over ownership to currElem.
- Node* currNode = currElem->node->cloneNode(false).releaseRef();
- reportError(ResidualStyleError, &currNode->localName());
-
- // Change the stack element's node to point to the clone.
- // The stack element adopts the reference we obtained above by calling release().
- currElem->derefNode();
- currElem->node = currNode;
- currElem->didRefNode = true;
-
- // Attach the previous node as a child of this new node.
- if (prevNode)
- currNode->appendChild(prevNode, ec);
- else // The new parent for the block element is going to be the innermost clone.
- parentElem = currNode; // FIXME: We shifted parentElem to be a residual inline. We never checked to see if blockElem could be legally placed inside the inline though.
-
- prevNode = currNode;
- }
-
- currElem = currElem->next;
- }
-
- // Now append the chain of new residual style elements if one exists.
- if (prevNode)
- elem->node->appendChild(prevNode, ec); // FIXME: This append can result in weird stuff happening, like an inline chain being put into a table section.
- }
-
- // Check if the block is still in the tree. If it isn't, then we don't
- // want to remove it from its parent (that would crash) or insert it into
- // a new parent later. See http://bugs.webkit.org/show_bug.cgi?id=6778
- bool isBlockStillInTree = blockElem->parentNode();
-
- // We need to make a clone of |residualElem| and place it just inside |blockElem|.
- // All content of |blockElem| is reparented to be under this clone. We then
- // reparent |blockElem| using real DOM calls so that attachment/detachment will
- // be performed to fix up the rendering tree.
- // So for this example: <b>...<p>Foo</b>Goo</p>
- // The end result will be: <b>...</b><p><b>Foo</b>Goo</p>
- //
- // Step 1: Remove |blockElem| from its parent, doing a batch detach of all the kids.
- if (isBlockStillInTree)
- blockElem->parentNode()->removeChild(blockElem, ec);
-
- Node* newNodePtr = 0;
- if (blockElem->firstChild()) {
- // Step 2: Clone |residualElem|.
- RefPtr<Node> newNode = residualElem->cloneNode(false); // Shallow clone. We don't pick up the same kids.
- newNodePtr = newNode.get();
- reportError(ResidualStyleError, &newNode->localName());
-
- // Step 3: Place |blockElem|'s children under |newNode|. Remove all of the children of |blockElem|
- // before we've put |newElem| into the document. That way we'll only do one attachment of all
- // the new content (instead of a bunch of individual attachments).
- Node* currNode = blockElem->firstChild();
- while (currNode) {
- Node* nextNode = currNode->nextSibling();
- newNode->appendChild(currNode, ec);
- currNode = nextNode;
- }
-
- // Step 4: Place |newNode| under |blockElem|. |blockElem| is still out of the document, so no
- // attachment can occur yet.
- blockElem->appendChild(newNode.release(), ec);
- } else
- finished = true;
-
- // Step 5: Reparent |blockElem|. Now the full attachment of the fixed up tree takes place.
- if (isBlockStillInTree)
- parentElem->appendChild(blockElem, ec);
-
- // Step 6: Pull |elem| out of the stack, since it is no longer enclosing us. Also update
- // the node associated with the previous stack element so that when it gets popped,
- // it doesn't make the residual element the next current node.
- HTMLStackElem* currElem = maxElem;
- HTMLStackElem* prevElem = 0;
- while (currElem != elem) {
- prevElem = currElem;
- currElem = currElem->next;
- }
- prevElem->next = elem->next;
- prevElem->derefNode();
- prevElem->node = elem->node;
- prevElem->didRefNode = elem->didRefNode;
- m_treeDepth--;
- if (!finished) {
- // Repurpose |elem| to represent |newNode| and insert it at the appropriate position
- // in the stack. We do not do this for the innermost block, because in that case the new
- // node is effectively no longer open.
- elem->next = maxElem;
- elem->node = prevMaxElem->node;
- elem->didRefNode = prevMaxElem->didRefNode;
- elem->strayTableContent = false;
- prevMaxElem->next = elem;
- ASSERT(newNodePtr);
- prevMaxElem->node = newNodePtr;
- newNodePtr->ref();
- prevMaxElem->didRefNode = true;
- m_treeDepth++;
- } else
- delete elem;
- }
-
- // FIXME: If we ever make a case like this work:
- // <table><b><i><form></b></form></i></table>
- // Then this check will be too simplistic. Right now the <i><form> chain will end up inside the <tbody>, which is pretty crazy.
- if (strayTableContent)
- m_inStrayTableContent--;
-
- // Step 7: Reopen intermediate inlines, e.g., <b><p><i>Foo</b>Goo</p>.
- // In the above example, Goo should stay italic.
- // We cap the number of tags we're willing to reopen based off cResidualStyleMaxDepth.
-
- HTMLStackElem* curr = m_blockStack;
- HTMLStackElem* residualStyleStack = 0;
- unsigned stackDepth = 1;
- unsigned redundantStyleCount = 0;
- while (curr && curr != maxElem) {
- // We will actually schedule this tag for reopening
- // after we complete the close of this entire block.
- if (isResidualStyleTag(curr->tagName) && stackDepth++ < cResidualStyleMaxDepth) {
- // We've overloaded the use of stack elements and are just reusing the
- // struct with a slightly different meaning to the variables. Instead of chaining
- // from innermost to outermost, we build up a list of all the tags we need to reopen
- // from the outermost to the innermost, i.e., residualStyleStack will end up pointing
- // to the outermost tag we need to reopen.
- // We also set curr->node to be the actual element that corresponds to the ID stored in
- // curr->id rather than the node that you should pop to when the element gets pulled off
- // the stack.
- if (residualStyleStack && curr->tagName == residualStyleStack->tagName && curr->node->attributes()->mapsEquivalent(residualStyleStack->node->attributes()))
- redundantStyleCount++;
- else
- redundantStyleCount = 0;
-
- if (redundantStyleCount < cMaxRedundantTagDepth)
- moveOneBlockToStack(residualStyleStack);
- else
- popOneBlock();
- } else
- popOneBlock();
-
- curr = m_blockStack;
- }
-
- reopenResidualStyleTags(residualStyleStack, 0); // Stray table content can't be an issue here, since some element above will always become the root of new stray table content.
-
- m_handlingResidualStyleAcrossBlocks = false;
-}
-
-void LegacyHTMLTreeBuilder::reopenResidualStyleTags(HTMLStackElem* elem, Node* malformedTableParent)
-{
- // Loop for each tag that needs to be reopened.
- while (elem) {
- // Create a shallow clone of the DOM node for this element.
- RefPtr<Node> newNode = elem->node->cloneNode(false);
- reportError(ResidualStyleError, &newNode->localName());
-
- // Append the new node. In the malformed table case, we need to insert before the table,
- // which will be the last child.
- ExceptionCode ec = 0;
- if (malformedTableParent)
- malformedTableParent->insertBefore(newNode, malformedTableParent->lastChild(), ec);
- else
- m_current->appendChild(newNode, ec);
- // FIXME: Is it really OK to ignore the exceptions here?
-
- // Now push a new stack element for this node we just created.
- pushBlock(elem->tagName, elem->level);
- newNode->beginParsingChildren();
-
- // Set our strayTableContent boolean if needed, so that the reopened tag also knows
- // that it is inside a malformed table.
- m_blockStack->strayTableContent = malformedTableParent != 0;
- if (m_blockStack->strayTableContent)
- m_inStrayTableContent++;
-
- // Clear our malformed table parent variable.
- malformedTableParent = 0;
-
- // Update |current| manually to point to the new node.
- setCurrent(newNode.get());
-
- // Advance to the next tag that needs to be reopened.
- HTMLStackElem* next = elem->next;
- elem->derefNode();
- delete elem;
- elem = next;
- }
-}
-
-void LegacyHTMLTreeBuilder::pushBlock(const AtomicString& tagName, int level)
-{
- m_blockStack = new HTMLStackElem(tagName, level, m_current, m_didRefCurrent, m_blockStack);
- if (level >= minBlockLevelTagPriority)
- m_blocksInStack++;
- m_treeDepth++;
- m_didRefCurrent = false;
- if (tagName == pTag)
- m_hasPElementInScope = InScope;
- else if (isScopingTag(tagName))
- m_hasPElementInScope = NotInScope;
-}
-
-void LegacyHTMLTreeBuilder::popBlock(const AtomicString& tagName, bool reportErrors)
-{
- HTMLStackElem* elem = m_blockStack;
-
- if (m_parserQuirks && elem && !m_parserQuirks->shouldPopBlock(elem->tagName, tagName))
- return;
-
- int maxLevel = 0;
-
- while (elem && (elem->tagName != tagName)) {
- if (maxLevel < elem->level)
- maxLevel = elem->level;
- elem = elem->next;
- }
-
- if (!elem) {
- if (reportErrors)
- reportError(StrayCloseTagError, &tagName, 0, true);
- return;
- }
-
- if (maxLevel > elem->level) {
- // We didn't match because the tag is in a different scope, e.g.,
- // <b><p>Foo</b>. Try to correct the problem.
- if (!isResidualStyleTag(tagName))
- return;
- return handleResidualStyleCloseTagAcrossBlocks(elem);
- }
-
- bool isAffectedByStyle = isAffectedByResidualStyle(elem->tagName);
- HTMLStackElem* residualStyleStack = 0;
- Node* malformedTableParent = 0;
-
- elem = m_blockStack;
- unsigned stackDepth = 1;
- unsigned redundantStyleCount = 0;
- while (elem) {
- if (elem->tagName == tagName) {
- int strayTable = m_inStrayTableContent;
- popOneBlock();
- elem = 0;
-
- // This element was the root of some malformed content just inside an implicit or
- // explicit <tbody> or <tr>.
- // If we end up needing to reopen residual style tags, the root of the reopened chain
- // must also know that it is the root of malformed content inside a <tbody>/<tr>.
- if (strayTable && (m_inStrayTableContent < strayTable) && residualStyleStack) {
- Node* curr = m_current;
- while (curr && !curr->hasTagName(tableTag))
- curr = curr->parentNode();
- malformedTableParent = curr ? curr->parentNode() : 0;
- }
- }
- else {
- if (m_currentFormElement && elem->tagName == formTag)
- // A <form> is being closed prematurely (and this is
- // malformed HTML). Set an attribute on the form to clear out its
- // bottom margin.
- m_currentFormElement->setMalformed(true);
-
- // Schedule this tag for reopening
- // after we complete the close of this entire block.
- if (isAffectedByStyle && isResidualStyleTag(elem->tagName) && stackDepth++ < cResidualStyleMaxDepth) {
- // We've overloaded the use of stack elements and are just reusing the
- // struct with a slightly different meaning to the variables. Instead of chaining
- // from innermost to outermost, we build up a list of all the tags we need to reopen
- // from the outermost to the innermost, i.e., residualStyleStack will end up pointing
- // to the outermost tag we need to reopen.
- // We also set elem->node to be the actual element that corresponds to the ID stored in
- // elem->id rather than the node that you should pop to when the element gets pulled off
- // the stack.
- if (residualStyleStack && elem->tagName == residualStyleStack->tagName && elem->node->attributes()->mapsEquivalent(residualStyleStack->node->attributes()))
- redundantStyleCount++;
- else
- redundantStyleCount = 0;
-
- if (redundantStyleCount < cMaxRedundantTagDepth)
- moveOneBlockToStack(residualStyleStack);
- else
- popOneBlock();
- } else
- popOneBlock();
- elem = m_blockStack;
- }
- }
-
- reopenResidualStyleTags(residualStyleStack, malformedTableParent);
-}
-
-inline HTMLStackElem* LegacyHTMLTreeBuilder::popOneBlockCommon()
-{
- HTMLStackElem* elem = m_blockStack;
-
- // Form elements restore their state during the parsing process.
- // Also, a few elements (<applet>, <object>) need to know when all child elements (<param>s) are available.
- if (m_current && elem->node != m_current)
- m_current->finishParsingChildren();
-
- if (m_blockStack->level >= minBlockLevelTagPriority) {
- ASSERT(m_blocksInStack > 0);
- m_blocksInStack--;
- }
- m_treeDepth--;
- m_blockStack = elem->next;
- m_current = elem->node;
- m_didRefCurrent = elem->didRefNode;
-
- if (elem->strayTableContent)
- m_inStrayTableContent--;
-
- if (elem->tagName == pTag)
- m_hasPElementInScope = NotInScope;
- else if (isScopingTag(elem->tagName))
- m_hasPElementInScope = Unknown;
-
- return elem;
-}
-
-void LegacyHTMLTreeBuilder::popOneBlock()
-{
- // Store the current node before popOneBlockCommon overwrites it.
- Node* lastCurrent = m_current;
- bool didRefLastCurrent = m_didRefCurrent;
-
- delete popOneBlockCommon();
-
- if (didRefLastCurrent)
- lastCurrent->deref();
-}
-
-void LegacyHTMLTreeBuilder::moveOneBlockToStack(HTMLStackElem*& head)
-{
- // We'll be using the stack element we're popping, but for the current node.
- // See the two callers for details.
-
- // Store the current node before popOneBlockCommon overwrites it.
- Node* lastCurrent = m_current;
- bool didRefLastCurrent = m_didRefCurrent;
-
- // Pop the block, but don't deref the current node as popOneBlock does because
- // we'll be using the pointer in the new stack element.
- HTMLStackElem* elem = popOneBlockCommon();
-
- // Transfer the current node into the stack element.
- // No need to deref the old elem->node because popOneBlockCommon transferred
- // it into the m_current/m_didRefCurrent fields.
- elem->node = lastCurrent;
- elem->didRefNode = didRefLastCurrent;
- elem->next = head;
- head = elem;
-}
-
-void LegacyHTMLTreeBuilder::checkIfHasPElementInScope()
-{
- m_hasPElementInScope = NotInScope;
- HTMLStackElem* elem = m_blockStack;
- while (elem) {
- const AtomicString& tagName = elem->tagName;
- if (tagName == pTag) {
- m_hasPElementInScope = InScope;
- return;
- } else if (isScopingTag(tagName))
- return;
- elem = elem->next;
- }
-}
-
-void LegacyHTMLTreeBuilder::popInlineBlocks()
-{
- while (m_blockStack && isInline(m_current))
- popOneBlock();
-}
-
-void LegacyHTMLTreeBuilder::freeBlock()
-{
- while (m_blockStack)
- popOneBlock();
- ASSERT(!m_blocksInStack);
- ASSERT(!m_treeDepth);
-}
-
-void LegacyHTMLTreeBuilder::createHead()
-{
- if (m_head)
- return;
-
- if (!m_document->documentElement() && !m_isParsingFragment) {
- insertNode(HTMLHtmlElement::create(m_document).get());
- ASSERT(m_document->documentElement() || m_isParsingFragment);
- }
-
- m_head = HTMLHeadElement::create(m_document);
-
- if (m_isParsingFragment)
- return;
-
- HTMLElement* body = m_document->body();
- ExceptionCode ec = 0;
- m_document->documentElement()->insertBefore(m_head.get(), body, ec);
- if (ec)
- m_head = 0;
-
- // If the body does not exist yet, then the <head> should be pushed as the current block.
- if (m_head && !body) {
- pushBlock(m_head->localName(), m_head->tagPriority());
- setCurrent(m_head.get());
- }
-}
-
-PassRefPtr<Node> LegacyHTMLTreeBuilder::handleIsindex(Token* t)
-{
- RefPtr<Node> n = HTMLDivElement::create(m_document);
-
- NamedNodeMap* attrs = t->attrs.get();
-
- RefPtr<HTMLIsIndexElement> isIndex = HTMLIsIndexElement::create(m_document, m_currentFormElement.get());
- isIndex->setAttributeMap(attrs);
- isIndex->setAttribute(typeAttr, "khtml_isindex");
-
- String text = searchableIndexIntroduction();
- if (attrs) {
- if (Attribute* a = attrs->getAttributeItem(promptAttr))
- text = a->value().string() + " ";
- t->attrs = 0;
- }
-
- n->legacyParserAddChild(HTMLHRElement::create(m_document));
- n->legacyParserAddChild(Text::create(m_document, text));
- n->legacyParserAddChild(isIndex.release());
- n->legacyParserAddChild(HTMLHRElement::create(m_document));
-
- return n.release();
-}
-
-void LegacyHTMLTreeBuilder::startBody()
-{
- if (m_inBody)
- return;
-
- m_inBody = true;
-
- if (m_isindexElement) {
- insertNode(m_isindexElement.get(), true /* don't descend into this node */);
- m_isindexElement = 0;
- }
-}
-
-void LegacyHTMLTreeBuilder::finished()
-{
- // In the case of a completely empty document, here's the place to create the HTML element.
- if (m_current && m_current->isDocumentNode() && !m_document->documentElement())
- insertNode(HTMLHtmlElement::create(m_document).get());
-
- // This ensures that "current" is not left pointing to a node when the document is destroyed.
- freeBlock();
- setCurrent(0);
-
- // Warning, this may delete the parser, so don't try to do anything else after this.
- if (!m_isParsingFragment)
- m_document->finishedParsing();
-}
-
-void LegacyHTMLTreeBuilder::reportErrorToConsole(HTMLParserErrorCode errorCode, const AtomicString* tagName1, const AtomicString* tagName2, bool closeTags)
-{
- Frame* frame = m_document->frame();
- if (!frame)
- return;
-
- ScriptableDocumentParser* parser = m_document->scriptableDocumentParser();
- int lineNumber = parser->lineNumber() + 1;
-
- AtomicString tag1;
- AtomicString tag2;
- if (tagName1) {
- if (*tagName1 == "#text")
- tag1 = "Text";
- else if (*tagName1 == "#comment")
- tag1 = "<!-- comment -->";
- else
- tag1 = (closeTags ? "</" : "<") + *tagName1 + ">";
- }
- if (tagName2) {
- if (*tagName2 == "#text")
- tag2 = "Text";
- else if (*tagName2 == "#comment")
- tag2 = "<!-- comment -->";
- else
- tag2 = (closeTags ? "</" : "<") + *tagName2 + ">";
- }
-
- const char* errorMsg = htmlParserErrorMessageTemplate(errorCode);
- if (!errorMsg)
- return;
-
- String message;
- if (parser->processingContentWrittenByScript())
- message += htmlParserDocumentWriteMessage();
- message += errorMsg;
- message.replace("%tag1", tag1);
- message.replace("%tag2", tag2);
-
- frame->domWindow()->console()->addMessage(HTMLMessageSource, LogMessageType,
- isWarning(errorCode) ? WarningMessageLevel : ErrorMessageLevel,
- message, lineNumber, m_document->url().string());
-}
-
-#ifdef BUILDING_ON_LEOPARD
-bool shouldCreateImplicitHead(Document* document)
-{
- ASSERT(document);
-
- Settings* settings = document->page() ? document->page()->settings() : 0;
- return settings ? !settings->needsLeopardMailQuirks() : true;
-}
-#elif defined(BUILDING_ON_TIGER)
-bool shouldCreateImplicitHead(Document* document)
-{
- ASSERT(document);
-
- Settings* settings = document->page() ? document->page()->settings() : 0;
- return settings ? !settings->needsTigerMailQuirks() : true;
-}
-#endif
-
-
-String serializeForNumberType(double number)
-{
- // According to HTML5, "the best representation of the number n as a floating
- // point number" is a string produced by applying ToString() to n.
- DtoaBuffer buffer;
- unsigned length;
- doubleToStringInJavaScriptFormat(number, buffer, &length);
- return String(buffer, length);
-}
-
-bool parseToDoubleForNumberType(const String& src, double* out)
-{
- // See HTML5 2.4.4.3 `Real numbers.'
-
- if (src.isEmpty())
- return false;
- // String::toDouble() accepts leading + \t \n \v \f \r and SPACE, which are invalid in HTML5.
- // So, check the first character.
- if (src[0] != '-' && (src[0] < '0' || src[0] > '9'))
- return false;
-
- bool valid = false;
- double value = src.toDouble(&valid);
- if (!valid)
- return false;
- // NaN and Infinity are not valid numbers according to the standard.
- if (!isfinite(value))
- return false;
- // -0 -> 0
- if (!value)
- value = 0;
- if (out)
- *out = value;
- return true;
-}
-
-}
diff --git a/WebCore/html/LegacyHTMLTreeBuilder.h b/WebCore/html/LegacyHTMLTreeBuilder.h
deleted file mode 100644
index ed2b857..0000000
--- a/WebCore/html/LegacyHTMLTreeBuilder.h
+++ /dev/null
@@ -1,306 +0,0 @@
-/*
- Copyright (C) 1997 Martin Jones (mjones@kde.org)
- (C) 1997 Torben Weis (weis@kde.org)
- (C) 1998 Waldo Bastian (bastian@kde.org)
- (C) 1999 Lars Knoll (knoll@kde.org)
- Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009 Apple 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 LegacyHTMLTreeBuilder_h
-#define LegacyHTMLTreeBuilder_h
-
-#include "FragmentScriptingPermission.h"
-#include "HTMLParserErrorCodes.h"
-#include "NamedNodeMap.h"
-#include "QualifiedName.h"
-#include <wtf/Forward.h>
-#include <wtf/OwnPtr.h>
-#include <wtf/RefPtr.h>
-
-namespace WebCore {
-
-class DoctypeToken;
-class Document;
-class DocumentFragment;
-class HTMLDocument;
-class HTMLFormElement;
-class HTMLHeadElement;
-class HTMLMapElement;
-class HTMLParserQuirks;
-class Node;
-
-struct HTMLStackElem;
-
-/**
- * @internal
- * represents one HTML tag. Consists of a numerical id, and the list
- * of attributes. Can also represent text. In this case the id = 0 and
- * text contains the text.
- */
-struct Token {
- Token()
- : beginTag(true)
- , selfClosingTag(false)
- , brokenXMLStyle(false)
- , m_sourceInfo(0)
- { }
- ~Token() { }
-
- void addAttribute(AtomicString& attrName, const AtomicString& v, bool viewSourceMode);
-
- bool isOpenTag(const QualifiedName& fullName) const { return beginTag && fullName.localName() == tagName; }
- bool isCloseTag(const QualifiedName& fullName) const { return !beginTag && fullName.localName() == tagName; }
-
- void reset()
- {
- attrs = 0;
- text = 0;
- tagName = nullAtom;
- beginTag = true;
- selfClosingTag = false;
- brokenXMLStyle = false;
- if (m_sourceInfo)
- m_sourceInfo->clear();
- }
-
- void addViewSourceChar(UChar c)
- {
- if (!m_sourceInfo.get())
- m_sourceInfo.set(new Vector<UChar>);
- m_sourceInfo->append(c);
- }
-
- RefPtr<NamedNodeMap> attrs;
- RefPtr<StringImpl> text;
- AtomicString tagName;
- bool beginTag;
- bool selfClosingTag;
- bool brokenXMLStyle;
- OwnPtr<Vector<UChar> > m_sourceInfo;
-};
-
-enum DoctypeState {
- DoctypeBegin,
- DoctypeBeforeName,
- DoctypeName,
- DoctypeAfterName,
- DoctypeBeforePublicID,
- DoctypePublicID,
- DoctypeAfterPublicID,
- DoctypeBeforeSystemID,
- DoctypeSystemID,
- DoctypeAfterSystemID,
- DoctypeBogus
-};
-
-class DoctypeToken {
-public:
- DoctypeToken() {}
-
- void reset()
- {
- m_name.clear();
- m_publicID.clear();
- m_systemID.clear();
- m_state = DoctypeBegin;
- m_source.clear();
- m_forceQuirks = false;
- }
-
- DoctypeState state() { return m_state; }
- void setState(DoctypeState s) { m_state = s; }
-
- Vector<UChar> m_name;
- Vector<UChar> m_publicID;
- Vector<UChar> m_systemID;
- DoctypeState m_state;
-
- Vector<UChar> m_source;
-
- bool m_forceQuirks; // Used by the HTML5 parser.
-};
-
-//-----------------------------------------------------------------------------
-
-/**
- * The parser for HTML. It receives a stream of tokens from the LegacyHTMLDocumentParser, and
- * builds up the Document structure from it.
- */
-class LegacyHTMLTreeBuilder : public Noncopyable {
-public:
- LegacyHTMLTreeBuilder(HTMLDocument*, bool reportErrors);
- LegacyHTMLTreeBuilder(DocumentFragment*, FragmentScriptingPermission = FragmentScriptingAllowed);
- virtual ~LegacyHTMLTreeBuilder();
-
- /**
- * parses one token delivered by the tokenizer
- */
- PassRefPtr<Node> parseToken(Token*);
-
- // Parses a doctype token.
- void parseDoctypeToken(DoctypeToken*);
-
- /**
- * tokenizer says it's not going to be sending us any more tokens
- */
- void finished();
-
- /**
- * resets the parser
- */
- void reset();
-
- bool skipMode() const { return !m_skipModeTag.isNull(); }
- bool isHandlingResidualStyleAcrossBlocks() const { return m_handlingResidualStyleAcrossBlocks; }
-
-private:
- void setCurrent(Node*);
- void derefCurrent();
- void setSkipMode(const QualifiedName& qName) { m_skipModeTag = qName.localName(); }
-
- PassRefPtr<Node> getNode(Token*);
- bool bodyCreateErrorCheck(Token*, RefPtr<Node>&);
- bool canvasCreateErrorCheck(Token*, RefPtr<Node>&);
- bool colCreateErrorCheck(Token*, RefPtr<Node>&);
- bool commentCreateErrorCheck(Token*, RefPtr<Node>&);
- bool ddCreateErrorCheck(Token*, RefPtr<Node>&);
- bool dtCreateErrorCheck(Token*, RefPtr<Node>&);
- bool formCreateErrorCheck(Token*, RefPtr<Node>&);
- bool framesetCreateErrorCheck(Token*, RefPtr<Node>&);
- bool headCreateErrorCheck(Token*, RefPtr<Node>&);
- bool iframeCreateErrorCheck(Token*, RefPtr<Node>&);
- bool isindexCreateErrorCheck(Token*, RefPtr<Node>&);
- bool mapCreateErrorCheck(Token*, RefPtr<Node>&);
- bool nestedCreateErrorCheck(Token*, RefPtr<Node>&);
- bool nestedPCloserCreateErrorCheck(Token*, RefPtr<Node>&);
- bool nestedStyleCreateErrorCheck(Token*, RefPtr<Node>&);
- bool noembedCreateErrorCheck(Token*, RefPtr<Node>&);
- bool noframesCreateErrorCheck(Token*, RefPtr<Node>&);
- bool nolayerCreateErrorCheck(Token*, RefPtr<Node>&);
- bool noscriptCreateErrorCheck(Token*, RefPtr<Node>&);
- bool pCloserCreateErrorCheck(Token*, RefPtr<Node>&);
- bool pCloserStrictCreateErrorCheck(Token*, RefPtr<Node>&);
- bool rpCreateErrorCheck(Token*, RefPtr<Node>&);
- bool rtCreateErrorCheck(Token*, RefPtr<Node>&);
- bool selectCreateErrorCheck(Token*, RefPtr<Node>&);
- bool tableCellCreateErrorCheck(Token*, RefPtr<Node>&);
- bool tableSectionCreateErrorCheck(Token*, RefPtr<Node>&);
- bool textCreateErrorCheck(Token*, RefPtr<Node>&);
-
- void processCloseTag(Token*);
-
- void limitDepth(int tagPriority);
- bool insertNodeAfterLimitDepth(Node*, bool flat = false);
- bool insertNode(Node*, bool flat = false);
- bool handleError(Node*, bool flat, const AtomicString& localName, int tagPriority);
-
- void pushBlock(const AtomicString& tagName, int level);
- void popBlock(const AtomicString& tagName, bool reportErrors = false);
- void popBlock(const QualifiedName& qName, bool reportErrors = false) { return popBlock(qName.localName(), reportErrors); } // Convenience function for readability.
- void popOneBlock();
- void moveOneBlockToStack(HTMLStackElem*& head);
- inline HTMLStackElem* popOneBlockCommon();
- void popInlineBlocks();
-
- void freeBlock();
-
- void createHead();
-
- static bool isResidualStyleTag(const AtomicString& tagName);
- static bool isAffectedByResidualStyle(const AtomicString& tagName);
- void handleResidualStyleCloseTagAcrossBlocks(HTMLStackElem*);
- void reopenResidualStyleTags(HTMLStackElem*, Node* malformedTableParent);
-
- bool allowNestedRedundantTag(const AtomicString& tagName);
-
- static bool isHeadingTag(const AtomicString& tagName);
-
- bool isInline(Node*) const;
-
- void startBody(); // inserts the isindex element
- PassRefPtr<Node> handleIsindex(Token*);
-
- void checkIfHasPElementInScope();
- bool hasPElementInScope()
- {
- if (m_hasPElementInScope == Unknown)
- checkIfHasPElementInScope();
- return m_hasPElementInScope == InScope;
- }
-
- void reportError(HTMLParserErrorCode errorCode, const AtomicString* tagName1 = 0, const AtomicString* tagName2 = 0, bool closeTags = false)
- { if (!m_reportErrors) return; reportErrorToConsole(errorCode, tagName1, tagName2, closeTags); }
-
- void reportErrorToConsole(HTMLParserErrorCode, const AtomicString* tagName1, const AtomicString* tagName2, bool closeTags);
-
- Document* m_document;
-
- // The currently active element (the one new elements will be added to). Can be a document fragment, a document or an element.
- Node* m_current;
- // We can't ref a document, but we don't want to constantly check if a node is a document just to decide whether to deref.
- bool m_didRefCurrent;
-
- HTMLStackElem* m_blockStack;
-
- // The number of tags with priority minBlockLevelTagPriority or higher
- // currently in m_blockStack. The parser enforces a cap on this value by
- // adding such new elements as siblings instead of children once it is reached.
- size_t m_blocksInStack;
- // Depth of the tree.
- unsigned m_treeDepth;
-
- enum ElementInScopeState { NotInScope, InScope, Unknown };
- ElementInScopeState m_hasPElementInScope;
-
- RefPtr<HTMLFormElement> m_currentFormElement; // currently active form
- RefPtr<HTMLMapElement> m_currentMapElement; // current map
- RefPtr<HTMLHeadElement> m_head; // head element; needed for HTML which defines <base> after </head>
- RefPtr<Node> m_isindexElement; // a possible <isindex> element in the head
-
- bool m_inBody;
- bool m_haveContent;
- bool m_haveFrameSet;
-
- AtomicString m_skipModeTag; // tells the parser to discard all tags until it reaches the one specified
-
- bool m_isParsingFragment;
- bool m_reportErrors;
- bool m_handlingResidualStyleAcrossBlocks;
- int m_inStrayTableContent;
- FragmentScriptingPermission m_scriptingPermission;
-
- OwnPtr<HTMLParserQuirks> m_parserQuirks;
-};
-
-#if defined(BUILDING_ON_LEOPARD) || defined(BUILDING_ON_TIGER)
-bool shouldCreateImplicitHead(Document*);
-#else
-inline bool shouldCreateImplicitHead(Document*) { return true; }
-#endif
-
-// Converts the specified string to a floating number.
-// If the conversion fails, the return value is false. Take care that leading or trailing unnecessary characters make failures. This returns false for an empty string input.
-// The double* parameter may be 0.
-bool parseToDoubleForNumberType(const String&, double*);
-// Converts the specified number to a string. This is an implementation of
-// HTML5's "algorithm to convert a number to a string" for NUMBER/RANGE types.
-String serializeForNumberType(double);
-
-}
-
-#endif // LegacyHTMLTreeBuilder_h
diff --git a/WebCore/html/StepRange.cpp b/WebCore/html/StepRange.cpp
index 9afde1b..aeaf62f 100644
--- a/WebCore/html/StepRange.cpp
+++ b/WebCore/html/StepRange.cpp
@@ -23,7 +23,7 @@
#include "HTMLInputElement.h"
#include "HTMLNames.h"
-#include "LegacyHTMLTreeBuilder.h"
+#include "HTMLTreeBuilder.h"
#include "PlatformString.h"
#include <wtf/MathExtras.h>
diff --git a/WebCore/html/ThreadableBlobRegistry.cpp b/WebCore/html/ThreadableBlobRegistry.cpp
index 1df290d..d92d570 100644
--- a/WebCore/html/ThreadableBlobRegistry.cpp
+++ b/WebCore/html/ThreadableBlobRegistry.cpp
@@ -56,7 +56,7 @@ static void postTaskToMainThread(ScriptExecutionContext* scriptExecutionContext,
static void registerBlobURLTask(ScriptExecutionContext*, const KURL& url, PassOwnPtr<BlobData> blobData)
{
- BlobRegistry::instance().registerBlobURL(url, blobData);
+ blobRegistry().registerBlobURL(url, blobData);
}
void ThreadableBlobRegistry::registerBlobURL(ScriptExecutionContext* scriptExecutionContext, const KURL& url, PassOwnPtr<BlobData> blobData)
@@ -69,7 +69,7 @@ void ThreadableBlobRegistry::registerBlobURL(ScriptExecutionContext* scriptExecu
static void registerBlobURLFromTask(ScriptExecutionContext*, const KURL& url, const KURL& srcURL)
{
- BlobRegistry::instance().registerBlobURL(url, srcURL);
+ blobRegistry().registerBlobURL(url, srcURL);
}
void ThreadableBlobRegistry::registerBlobURL(ScriptExecutionContext* scriptExecutionContext, const KURL& url, const KURL& srcURL)
@@ -82,7 +82,7 @@ void ThreadableBlobRegistry::registerBlobURL(ScriptExecutionContext* scriptExecu
static void unregisterBlobURLTask(ScriptExecutionContext*, const KURL& url)
{
- BlobRegistry::instance().unregisterBlobURL(url);
+ blobRegistry().unregisterBlobURL(url);
}
void ThreadableBlobRegistry::unregisterBlobURL(ScriptExecutionContext* scriptExecutionContext, const KURL& url)
diff --git a/WebCore/html/ValidityState.cpp b/WebCore/html/ValidityState.cpp
index e286b64..0c25dac 100644
--- a/WebCore/html/ValidityState.cpp
+++ b/WebCore/html/ValidityState.cpp
@@ -26,7 +26,7 @@
#include "HTMLInputElement.h"
#include "HTMLNames.h"
-#include "LegacyHTMLTreeBuilder.h"
+#include "HTMLTreeBuilder.h"
#include "KURL.h"
#include "LocalizedStrings.h"
#include "RegularExpression.h"
diff --git a/WebCore/html/ValidityState.h b/WebCore/html/ValidityState.h
index 04f11a1..eecb9be 100644
--- a/WebCore/html/ValidityState.h
+++ b/WebCore/html/ValidityState.h
@@ -33,7 +33,7 @@ class ValidityState : public Noncopyable {
public:
static PassOwnPtr<ValidityState> create(HTMLFormControlElement* control)
{
- return new ValidityState(control);
+ return adoptPtr(new ValidityState(control));
}
void ref() { m_control->ref(); }
diff --git a/WebCore/html/canvas/CanvasRenderingContext.cpp b/WebCore/html/canvas/CanvasRenderingContext.cpp
index fed8cb2..1e897d3 100644
--- a/WebCore/html/canvas/CanvasRenderingContext.cpp
+++ b/WebCore/html/canvas/CanvasRenderingContext.cpp
@@ -25,7 +25,9 @@
#include "config.h"
#include "CanvasRenderingContext.h"
-
+#if ENABLE(ACCELERATED_2D_CANVAS) || ENABLE(3D_CANVAS)
+#include "GraphicsContext3D.h"
+#endif
#include "HTMLCanvasElement.h"
namespace WebCore {
@@ -45,4 +47,13 @@ void CanvasRenderingContext::deref()
m_canvas->deref();
}
+bool CanvasRenderingContext::paintsIntoCanvasBuffer() const
+{
+#if ENABLE(ACCELERATED_2D_CANVAS) || ENABLE(3D_CANVAS)
+ if (GraphicsContext3D* context3D = graphicsContext3D())
+ return context3D->paintsIntoCanvasBuffer();
+#endif
+ return true;
+}
+
} // namespace WebCore
diff --git a/WebCore/html/canvas/CanvasRenderingContext.h b/WebCore/html/canvas/CanvasRenderingContext.h
index cb26363..2cdbe1d 100644
--- a/WebCore/html/canvas/CanvasRenderingContext.h
+++ b/WebCore/html/canvas/CanvasRenderingContext.h
@@ -54,6 +54,7 @@ namespace WebCore {
virtual GraphicsContext3D* graphicsContext3D() const { return 0; }
virtual void paintRenderingResultsToCanvas() {}
+ bool paintsIntoCanvasBuffer() const;
private:
HTMLCanvasElement* m_canvas;
diff --git a/WebCore/html/canvas/CanvasRenderingContext2D.cpp b/WebCore/html/canvas/CanvasRenderingContext2D.cpp
index 58ec1d0..2a7b96a 100644
--- a/WebCore/html/canvas/CanvasRenderingContext2D.cpp
+++ b/WebCore/html/canvas/CanvasRenderingContext2D.cpp
@@ -1451,7 +1451,7 @@ PassRefPtr<CanvasPattern> CanvasRenderingContext2D::createPattern(HTMLImageEleme
if (!cachedImage || !image->cachedImage()->image())
return CanvasPattern::create(Image::nullImage(), repeatX, repeatY, true);
- bool originClean = !canvas()->securityOrigin().taintsCanvas(KURL(KURL(), cachedImage->url())) && cachedImage->image()->hasSingleSecurityOrigin();
+ bool originClean = !canvas()->securityOrigin().taintsCanvas(KURL(KURL(), cachedImage->response().url())) && cachedImage->image()->hasSingleSecurityOrigin();
return CanvasPattern::create(cachedImage->image(), repeatX, repeatY, originClean);
}
@@ -1727,7 +1727,19 @@ void CanvasRenderingContext2D::strokeText(const String& text, float x, float y,
PassRefPtr<TextMetrics> CanvasRenderingContext2D::measureText(const String& text)
{
RefPtr<TextMetrics> metrics = TextMetrics::create();
+
+#if PLATFORM(QT)
+ // We always use complex text shaping since it can't be turned off for QPainterPath::addText().
+ Font::CodePath oldCodePath = Font::codePath();
+ Font::setCodePath(Font::Complex);
+#endif
+
metrics->setWidth(accessFont().width(TextRun(text.characters(), text.length())));
+
+#if PLATFORM(QT)
+ Font::setCodePath(oldCodePath);
+#endif
+
return metrics;
}
@@ -1838,7 +1850,18 @@ void CanvasRenderingContext2D::drawTextInternal(const String& text, float x, flo
#endif
c->setTextDrawingMode(fill ? cTextFill : cTextStroke);
+
+#if PLATFORM(QT)
+ // We always use complex text shaping since it can't be turned off for QPainterPath::addText().
+ Font::CodePath oldCodePath = Font::codePath();
+ Font::setCodePath(Font::Complex);
+#endif
+
c->drawBidiText(font, textRun, location);
+
+#if PLATFORM(QT)
+ Font::setCodePath(oldCodePath);
+#endif
}
const Font& CanvasRenderingContext2D::accessFont()
@@ -1851,7 +1874,8 @@ const Font& CanvasRenderingContext2D::accessFont()
void CanvasRenderingContext2D::paintRenderingResultsToCanvas()
{
#if ENABLE(ACCELERATED_2D_CANVAS)
- drawingContext()->syncSoftwareCanvas();
+ if (GraphicsContext* c = drawingContext())
+ c->syncSoftwareCanvas();
#endif
}
diff --git a/WebCore/html/canvas/Float32Array.cpp b/WebCore/html/canvas/Float32Array.cpp
index c95fb48..e6e8439 100644
--- a/WebCore/html/canvas/Float32Array.cpp
+++ b/WebCore/html/canvas/Float32Array.cpp
@@ -37,7 +37,7 @@ PassRefPtr<Float32Array> Float32Array::create(unsigned length)
return TypedArrayBase<float>::create<Float32Array>(length);
}
-PassRefPtr<Float32Array> Float32Array::create(float* array, unsigned length)
+PassRefPtr<Float32Array> Float32Array::create(const float* array, unsigned length)
{
return TypedArrayBase<float>::create<Float32Array>(array, length);
}
diff --git a/WebCore/html/canvas/Float32Array.h b/WebCore/html/canvas/Float32Array.h
index 8112264..ab57087 100644
--- a/WebCore/html/canvas/Float32Array.h
+++ b/WebCore/html/canvas/Float32Array.h
@@ -35,7 +35,7 @@ namespace WebCore {
class Float32Array : public TypedArrayBase<float> {
public:
static PassRefPtr<Float32Array> create(unsigned length);
- static PassRefPtr<Float32Array> create(float* array, unsigned length);
+ static PassRefPtr<Float32Array> create(const float* array, unsigned length);
static PassRefPtr<Float32Array> create(PassRefPtr<ArrayBuffer> buffer, unsigned byteOffset, unsigned length);
using TypedArrayBase<float>::set;
diff --git a/WebCore/html/canvas/TypedArrayBase.h b/WebCore/html/canvas/TypedArrayBase.h
index c55896b..e69c2b5 100644
--- a/WebCore/html/canvas/TypedArrayBase.h
+++ b/WebCore/html/canvas/TypedArrayBase.h
@@ -67,7 +67,7 @@ class TypedArrayBase : public ArrayBufferView {
}
template <class Subclass>
- static PassRefPtr<Subclass> create(T* array, unsigned length)
+ static PassRefPtr<Subclass> create(const T* array, unsigned length)
{
RefPtr<Subclass> a = create<Subclass>(length);
if (a)
diff --git a/WebCore/html/canvas/WebGLBuffer.cpp b/WebCore/html/canvas/WebGLBuffer.cpp
index fc98a9d..d43868d 100644
--- a/WebCore/html/canvas/WebGLBuffer.cpp
+++ b/WebCore/html/canvas/WebGLBuffer.cpp
@@ -29,6 +29,7 @@
#include "WebGLBuffer.h"
+#include "ArrayBufferView.h"
#include "CheckedInt.h"
#include "WebGLRenderingContext.h"
diff --git a/WebCore/html/canvas/WebGLBuffer.h b/WebCore/html/canvas/WebGLBuffer.h
index a7a25b9..f18a9bf 100644
--- a/WebCore/html/canvas/WebGLBuffer.h
+++ b/WebCore/html/canvas/WebGLBuffer.h
@@ -33,6 +33,7 @@
#include <wtf/RefCounted.h>
namespace WebCore {
+class ArrayBufferView;
class WebGLBuffer : public WebGLObject {
public:
diff --git a/WebCore/html/canvas/WebGLFramebuffer.cpp b/WebCore/html/canvas/WebGLFramebuffer.cpp
index bfa08b7..6291705 100644
--- a/WebCore/html/canvas/WebGLFramebuffer.cpp
+++ b/WebCore/html/canvas/WebGLFramebuffer.cpp
@@ -101,7 +101,7 @@ unsigned long WebGLFramebuffer::getColorBufferFormat()
return GraphicsContext3D::RGB;
}
} else if (m_colorAttachment->isTexture())
- return (reinterpret_cast<WebGLTexture*>(m_colorAttachment))->getInternalFormat();
+ return (reinterpret_cast<WebGLTexture*>(m_colorAttachment))->getInternalFormat(0);
}
return 0;
}
diff --git a/WebCore/html/canvas/WebGLRenderingContext.cpp b/WebCore/html/canvas/WebGLRenderingContext.cpp
index 4465833..44d3e08 100644
--- a/WebCore/html/canvas/WebGLRenderingContext.cpp
+++ b/WebCore/html/canvas/WebGLRenderingContext.cpp
@@ -36,8 +36,10 @@
#include "FrameView.h"
#include "HTMLCanvasElement.h"
#include "HTMLImageElement.h"
+#include "HTMLVideoElement.h"
#include "ImageBuffer.h"
#include "ImageData.h"
+#include "IntSize.h"
#include "NotImplemented.h"
#include "RenderBox.h"
#include "RenderLayer.h"
@@ -98,6 +100,7 @@ WebGLRenderingContext::WebGLRenderingContext(HTMLCanvasElement* passedCanvas, Pa
, m_needsUpdate(true)
, m_markedCanvasDirty(false)
, m_activeTextureUnit(0)
+ , m_videoCache(4)
, m_packAlignment(4)
, m_unpackAlignment(4)
, m_unpackFlipY(false)
@@ -127,10 +130,10 @@ WebGLRenderingContext::WebGLRenderingContext(HTMLCanvasElement* passedCanvas, Pa
m_context->getIntegerv(GraphicsContext3D::MAX_CUBE_MAP_TEXTURE_SIZE, &m_maxCubeMapTextureSize);
m_maxCubeMapTextureLevel = WebGLTexture::computeLevelCount(m_maxCubeMapTextureSize, m_maxCubeMapTextureSize);
- if (!isGLES2Compliant()) {
+ if (!isGLES2NPOTStrict())
createFallbackBlackTextures1x1();
+ if (!isGLES2Compliant())
initVertexAttrib0();
- }
m_context->reshape(canvas()->width(), canvas()->height());
m_context->viewport(0, 0, canvas()->width(), canvas()->height());
}
@@ -303,7 +306,7 @@ void WebGLRenderingContext::bindTexture(unsigned long target, WebGLTexture* text
return;
}
m_context->bindTexture(target, objectOrZero(texture));
- if (!isGLES2Compliant() && texture)
+ if (texture)
texture->setTarget(target, maxLevel);
// FIXME: do we want to do this on all platforms?
@@ -335,20 +338,16 @@ void WebGLRenderingContext::blendColor(double red, double green, double blue, do
void WebGLRenderingContext::blendEquation(unsigned long mode)
{
- if (!isGLES2Compliant()) {
- if (!validateBlendEquation(mode))
- return;
- }
+ if (!validateBlendEquation(mode))
+ return;
m_context->blendEquation(mode);
cleanupAfterGraphicsCall(false);
}
void WebGLRenderingContext::blendEquationSeparate(unsigned long modeRGB, unsigned long modeAlpha)
{
- if (!isGLES2Compliant()) {
- if (!validateBlendEquation(modeRGB) || !validateBlendEquation(modeAlpha))
- return;
- }
+ if (!validateBlendEquation(modeRGB) || !validateBlendEquation(modeAlpha))
+ return;
m_context->blendEquationSeparate(modeRGB, modeAlpha);
cleanupAfterGraphicsCall(false);
}
@@ -372,9 +371,11 @@ void WebGLRenderingContext::bufferData(unsigned long target, int size, unsigned
WebGLBuffer* buffer = validateBufferDataParameters(target, usage);
if (!buffer)
return;
- if (!buffer->associateBufferData(size)) {
- m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
- return;
+ if (!isErrorGeneratedOnOutOfBoundsAccesses()) {
+ if (!buffer->associateBufferData(size)) {
+ m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
+ return;
+ }
}
m_context->bufferData(target, size, usage);
@@ -387,12 +388,14 @@ void WebGLRenderingContext::bufferData(unsigned long target, ArrayBuffer* data,
WebGLBuffer* buffer = validateBufferDataParameters(target, usage);
if (!buffer)
return;
- if (!buffer->associateBufferData(data)) {
- m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
- return;
+ if (!isErrorGeneratedOnOutOfBoundsAccesses()) {
+ if (!buffer->associateBufferData(data)) {
+ m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
+ return;
+ }
}
- m_context->bufferData(target, data, usage);
+ m_context->bufferData(target, data->byteLength(), data->data(), usage);
cleanupAfterGraphicsCall(false);
}
@@ -402,12 +405,14 @@ void WebGLRenderingContext::bufferData(unsigned long target, ArrayBufferView* da
WebGLBuffer* buffer = validateBufferDataParameters(target, usage);
if (!buffer)
return;
- if (!buffer->associateBufferData(data)) {
- m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
- return;
+ if (!isErrorGeneratedOnOutOfBoundsAccesses()) {
+ if (!buffer->associateBufferData(data)) {
+ m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
+ return;
+ }
}
- m_context->bufferData(target, data, usage);
+ m_context->bufferData(target, data->byteLength(), data->baseAddress(), usage);
cleanupAfterGraphicsCall(false);
}
@@ -417,12 +422,14 @@ void WebGLRenderingContext::bufferSubData(unsigned long target, long offset, Arr
WebGLBuffer* buffer = validateBufferDataParameters(target, GraphicsContext3D::STATIC_DRAW);
if (!buffer)
return;
- if (!buffer->associateBufferSubData(offset, data)) {
- m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
- return;
+ if (!isErrorGeneratedOnOutOfBoundsAccesses()) {
+ if (!buffer->associateBufferSubData(offset, data)) {
+ m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
+ return;
+ }
}
- m_context->bufferSubData(target, offset, data);
+ m_context->bufferSubData(target, offset, data->byteLength(), data->data());
cleanupAfterGraphicsCall(false);
}
@@ -432,22 +439,22 @@ void WebGLRenderingContext::bufferSubData(unsigned long target, long offset, Arr
WebGLBuffer* buffer = validateBufferDataParameters(target, GraphicsContext3D::STATIC_DRAW);
if (!buffer)
return;
- if (!buffer->associateBufferSubData(offset, data)) {
- m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
- return;
+ if (!isErrorGeneratedOnOutOfBoundsAccesses()) {
+ if (!buffer->associateBufferSubData(offset, data)) {
+ m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
+ return;
+ }
}
- m_context->bufferSubData(target, offset, data);
+ m_context->bufferSubData(target, offset, data->byteLength(), data->baseAddress());
cleanupAfterGraphicsCall(false);
}
unsigned long WebGLRenderingContext::checkFramebufferStatus(unsigned long target)
{
- if (!isGLES2Compliant()) {
- if (target != GraphicsContext3D::FRAMEBUFFER) {
- m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM);
- return 0;
- }
+ if (target != GraphicsContext3D::FRAMEBUFFER) {
+ m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM);
+ return 0;
}
if (!m_framebufferBinding || !m_framebufferBinding->object())
return GraphicsContext3D::FRAMEBUFFER_COMPLETE;
@@ -457,11 +464,9 @@ unsigned long WebGLRenderingContext::checkFramebufferStatus(unsigned long target
void WebGLRenderingContext::clear(unsigned long mask)
{
- if (!isGLES2Compliant()) {
- if (mask & ~(GraphicsContext3D::COLOR_BUFFER_BIT | GraphicsContext3D::DEPTH_BUFFER_BIT | GraphicsContext3D::STENCIL_BUFFER_BIT)) {
- m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
- return;
- }
+ if (mask & ~(GraphicsContext3D::COLOR_BUFFER_BIT | GraphicsContext3D::DEPTH_BUFFER_BIT | GraphicsContext3D::STENCIL_BUFFER_BIT)) {
+ m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
+ return;
}
m_context->clear(mask);
cleanupAfterGraphicsCall(true);
@@ -522,15 +527,14 @@ void WebGLRenderingContext::copyTexImage2D(unsigned long target, long level, uns
m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION);
return;
}
- if (level && WebGLTexture::isNPOT(width, height)) {
- m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
- return;
- }
+ }
+ if (!isGLES2NPOTStrict() && level && WebGLTexture::isNPOT(width, height)) {
+ m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
+ return;
}
m_context->copyTexImage2D(target, level, internalformat, x, y, width, height, border);
// FIXME: if the framebuffer is not complete, none of the below should be executed.
- if (!isGLES2Compliant())
- tex->setLevelInfo(target, level, internalformat, width, height, GraphicsContext3D::UNSIGNED_BYTE);
+ tex->setLevelInfo(target, level, internalformat, width, height, GraphicsContext3D::UNSIGNED_BYTE);
if (m_framebufferBinding)
m_framebufferBinding->onAttachedObjectChange(tex);
cleanupAfterGraphicsCall(false);
@@ -543,7 +547,7 @@ void WebGLRenderingContext::copyTexSubImage2D(unsigned long target, long level,
return;
if (!isGLES2Compliant()) {
if (m_framebufferBinding && m_framebufferBinding->object()
- && !isTexInternalFormatColorBufferCombinationValid(tex->getInternalFormat(),
+ && !isTexInternalFormatColorBufferCombinationValid(tex->getInternalFormat(level),
m_framebufferBinding->getColorBufferFormat())) {
m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION);
return;
@@ -713,10 +717,8 @@ void WebGLRenderingContext::detachShader(WebGLProgram* program, WebGLShader* sha
void WebGLRenderingContext::disable(unsigned long cap)
{
- if (!isGLES2Compliant()) {
- if (!validateCapability(cap))
- return;
- }
+ if (!validateCapability(cap))
+ return;
m_context->disable(cap);
cleanupAfterGraphicsCall(false);
}
@@ -916,26 +918,27 @@ void WebGLRenderingContext::drawArrays(unsigned long mode, long first, long coun
return;
}
- // Ensure we have a valid rendering state
- CheckedInt<int32_t> checkedFirst(first);
- CheckedInt<int32_t> checkedCount(count);
- CheckedInt<int32_t> checkedSum = checkedFirst + checkedCount;
- if (!checkedSum.valid() || !validateRenderingState(checkedSum.value())) {
- m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION);
- return;
+ if (!isErrorGeneratedOnOutOfBoundsAccesses()) {
+ // Ensure we have a valid rendering state
+ CheckedInt<int32_t> checkedFirst(first);
+ CheckedInt<int32_t> checkedCount(count);
+ CheckedInt<int32_t> checkedSum = checkedFirst + checkedCount;
+ if (!checkedSum.valid() || !validateRenderingState(checkedSum.value())) {
+ m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION);
+ return;
+ }
}
bool vertexAttrib0Simulated = false;
- if (!isGLES2Compliant()) {
+ if (!isGLES2Compliant())
vertexAttrib0Simulated = simulateVertexAttrib0(first + count - 1);
+ if (!isGLES2NPOTStrict())
handleNPOTTextures(true);
- }
m_context->drawArrays(mode, first, count);
- if (!isGLES2Compliant()) {
+ if (!isGLES2Compliant() && vertexAttrib0Simulated)
+ restoreStatesAfterVertexAttrib0Simulation();
+ if (!isGLES2NPOTStrict())
handleNPOTTextures(false);
- if (vertexAttrib0Simulated)
- restoreStatesAfterVertexAttrib0Simulation();
- }
cleanupAfterGraphicsCall(true);
}
@@ -960,40 +963,41 @@ void WebGLRenderingContext::drawElements(unsigned long mode, long count, unsigne
return;
}
- // Ensure we have a valid rendering state
- long numElements;
-
- if (!validateElementArraySize(count, type, offset)) {
- m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION);
- return;
- }
-
- if (!validateIndexArrayConservative(type, numElements) || !validateRenderingState(numElements))
- if (!validateIndexArrayPrecise(count, type, offset, numElements) || !validateRenderingState(numElements)) {
+ long numElements = 0;
+ if (!isErrorGeneratedOnOutOfBoundsAccesses()) {
+ // Ensure we have a valid rendering state
+ if (!validateElementArraySize(count, type, offset)) {
m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION);
return;
}
+ if (!validateIndexArrayConservative(type, numElements) || !validateRenderingState(numElements)) {
+ if (!validateIndexArrayPrecise(count, type, offset, numElements) || !validateRenderingState(numElements)) {
+ m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION);
+ return;
+ }
+ }
+ }
bool vertexAttrib0Simulated = false;
if (!isGLES2Compliant()) {
+ if (!numElements)
+ validateIndexArrayPrecise(count, type, offset, numElements);
vertexAttrib0Simulated = simulateVertexAttrib0(numElements);
- handleNPOTTextures(true);
}
+ if (!isGLES2NPOTStrict())
+ handleNPOTTextures(true);
m_context->drawElements(mode, count, type, offset);
- if (!isGLES2Compliant()) {
+ if (!isGLES2Compliant() && vertexAttrib0Simulated)
+ restoreStatesAfterVertexAttrib0Simulation();
+ if (!isGLES2NPOTStrict())
handleNPOTTextures(false);
- if (vertexAttrib0Simulated)
- restoreStatesAfterVertexAttrib0Simulation();
- }
cleanupAfterGraphicsCall(true);
}
void WebGLRenderingContext::enable(unsigned long cap)
{
- if (!isGLES2Compliant()) {
- if (!validateCapability(cap))
- return;
- }
+ if (!validateCapability(cap))
+ return;
m_context->enable(cap);
cleanupAfterGraphicsCall(false);
}
@@ -1116,15 +1120,12 @@ void WebGLRenderingContext::generateMipmap(unsigned long target)
WebGLTexture* tex = validateTextureBinding(target, false);
if (!tex)
return;
- if (!isGLES2Compliant()) {
- if (!tex->canGenerateMipmaps()) {
- m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION);
- return;
- }
+ if (!tex->canGenerateMipmaps()) {
+ m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION);
+ return;
}
m_context->generateMipmap(target);
- if (!isGLES2Compliant())
- tex->generateMipmapLevelInfo();
+ tex->generateMipmapLevelInfo();
cleanupAfterGraphicsCall(false);
}
@@ -1804,11 +1805,9 @@ long WebGLRenderingContext::getVertexAttribOffset(unsigned long index, unsigned
void WebGLRenderingContext::hint(unsigned long target, unsigned long mode)
{
- if (!isGLES2Compliant()) {
- if (target != GraphicsContext3D::GENERATE_MIPMAP_HINT) {
- m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM);
- return;
- }
+ if (target != GraphicsContext3D::GENERATE_MIPMAP_HINT) {
+ m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM);
+ return;
}
m_context->hint(target, mode);
cleanupAfterGraphicsCall(false);
@@ -1824,10 +1823,8 @@ bool WebGLRenderingContext::isBuffer(WebGLBuffer* buffer)
bool WebGLRenderingContext::isEnabled(unsigned long cap)
{
- if (!isGLES2Compliant()) {
- if (!validateCapability(cap))
- return false;
- }
+ if (!validateCapability(cap))
+ return false;
return m_context->isEnabled(cap);
}
@@ -2086,7 +2083,7 @@ void WebGLRenderingContext::texImage2DBase(unsigned target, unsigned level, unsi
WebGLTexture* tex = validateTextureBinding(target, true);
if (!tex)
return;
- if (!isGLES2Compliant()) {
+ if (!isGLES2NPOTStrict()) {
if (level && WebGLTexture::isNPOT(width, height)) {
m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
return;
@@ -2094,8 +2091,7 @@ void WebGLRenderingContext::texImage2DBase(unsigned target, unsigned level, unsi
}
m_context->texImage2D(target, level, internalformat, width, height,
border, format, type, pixels);
- if (!isGLES2Compliant())
- tex->setLevelInfo(target, level, internalformat, width, height, type);
+ tex->setLevelInfo(target, level, internalformat, width, height, type);
if (m_framebufferBinding)
m_framebufferBinding->onAttachedObjectChange(tex);
cleanupAfterGraphicsCall(false);
@@ -2128,11 +2124,11 @@ void WebGLRenderingContext::texImage2D(unsigned target, unsigned level, unsigned
void* data = pixels ? pixels->baseAddress() : 0;
Vector<uint8_t> tempData;
bool changeUnpackAlignment = false;
- if (pixels && (m_unpackFlipY || m_unpackPremultiplyAlpha)) {
+ if (data && (m_unpackFlipY || m_unpackPremultiplyAlpha)) {
if (!m_context->extractTextureData(width, height, format, type,
m_unpackAlignment,
m_unpackFlipY, m_unpackPremultiplyAlpha,
- pixels,
+ data,
tempData))
return;
data = tempData.data();
@@ -2188,19 +2184,32 @@ void WebGLRenderingContext::texImage2D(unsigned target, unsigned level, unsigned
m_unpackFlipY, m_unpackPremultiplyAlpha, ec);
}
+PassRefPtr<Image> WebGLRenderingContext::videoFrameToImage(HTMLVideoElement* video)
+{
+ if (!video || !video->videoWidth() || !video->videoHeight()) {
+ m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
+ return 0;
+ }
+ IntSize size(video->videoWidth(), video->videoHeight());
+ ImageBuffer* buf = m_videoCache.imageBuffer(size);
+ if (!buf) {
+ m_context->synthesizeGLError(GraphicsContext3D::OUT_OF_MEMORY);
+ return 0;
+ }
+ IntRect destRect(0, 0, size.width(), size.height());
+ // FIXME: Turn this into a GPU-GPU texture copy instead of CPU readback.
+ video->paintCurrentFrameInContext(buf->context(), destRect);
+ return buf->copyImage();
+}
+
void WebGLRenderingContext::texImage2D(unsigned target, unsigned level, unsigned internalformat,
unsigned format, unsigned type, HTMLVideoElement* video, ExceptionCode& ec)
{
- // FIXME: Need to implement this call
- UNUSED_PARAM(target);
- UNUSED_PARAM(level);
- UNUSED_PARAM(internalformat);
- UNUSED_PARAM(format);
- UNUSED_PARAM(type);
- UNUSED_PARAM(video);
-
ec = 0;
- cleanupAfterGraphicsCall(false);
+ RefPtr<Image> image = videoFrameToImage(video);
+ if (!video)
+ return;
+ texImage2DImpl(target, level, internalformat, format, type, image.get(), m_unpackFlipY, m_unpackPremultiplyAlpha, ec);
}
void WebGLRenderingContext::texParameter(unsigned long target, unsigned long pname, float paramf, int parami, bool isFloat)
@@ -2208,32 +2217,29 @@ void WebGLRenderingContext::texParameter(unsigned long target, unsigned long pna
WebGLTexture* tex = validateTextureBinding(target, false);
if (!tex)
return;
- if (!isGLES2Compliant()) {
- switch (pname) {
- case GraphicsContext3D::TEXTURE_MIN_FILTER:
- case GraphicsContext3D::TEXTURE_MAG_FILTER:
- break;
- case GraphicsContext3D::TEXTURE_WRAP_S:
- case GraphicsContext3D::TEXTURE_WRAP_T:
- if (isFloat && paramf != GraphicsContext3D::CLAMP_TO_EDGE && paramf != GraphicsContext3D::MIRRORED_REPEAT && paramf != GraphicsContext3D::REPEAT
- || !isFloat && parami != GraphicsContext3D::CLAMP_TO_EDGE && parami != GraphicsContext3D::MIRRORED_REPEAT && parami != GraphicsContext3D::REPEAT) {
- m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM);
- return;
- }
- break;
- default:
+ switch (pname) {
+ case GraphicsContext3D::TEXTURE_MIN_FILTER:
+ case GraphicsContext3D::TEXTURE_MAG_FILTER:
+ break;
+ case GraphicsContext3D::TEXTURE_WRAP_S:
+ case GraphicsContext3D::TEXTURE_WRAP_T:
+ if (isFloat && paramf != GraphicsContext3D::CLAMP_TO_EDGE && paramf != GraphicsContext3D::MIRRORED_REPEAT && paramf != GraphicsContext3D::REPEAT
+ || !isFloat && parami != GraphicsContext3D::CLAMP_TO_EDGE && parami != GraphicsContext3D::MIRRORED_REPEAT && parami != GraphicsContext3D::REPEAT) {
m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM);
return;
}
- if (isFloat)
- tex->setParameterf(pname, paramf);
- else
- tex->setParameteri(pname, parami);
+ break;
+ default:
+ m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM);
+ return;
}
- if (isFloat)
+ if (isFloat) {
+ tex->setParameterf(pname, paramf);
m_context->texParameterf(target, pname, paramf);
- else
+ } else {
+ tex->setParameteri(pname, parami);
m_context->texParameteri(target, pname, parami);
+ }
cleanupAfterGraphicsCall(false);
}
@@ -2284,11 +2290,11 @@ void WebGLRenderingContext::texSubImage2D(unsigned target, unsigned level, unsig
void* data = pixels ? pixels->baseAddress() : 0;
Vector<uint8_t> tempData;
bool changeUnpackAlignment = false;
- if (pixels && (m_unpackFlipY || m_unpackPremultiplyAlpha)) {
+ if (data && (m_unpackFlipY || m_unpackPremultiplyAlpha)) {
if (!m_context->extractTextureData(width, height, format, type,
m_unpackAlignment,
m_unpackFlipY, m_unpackPremultiplyAlpha,
- pixels,
+ data,
tempData))
return;
data = tempData.data();
@@ -2342,16 +2348,11 @@ void WebGLRenderingContext::texSubImage2D(unsigned target, unsigned level, unsig
void WebGLRenderingContext::texSubImage2D(unsigned target, unsigned level, unsigned xoffset, unsigned yoffset,
unsigned format, unsigned type, HTMLVideoElement* video, ExceptionCode& ec)
{
- // FIXME: Need to implement this call
- UNUSED_PARAM(target);
- UNUSED_PARAM(level);
- UNUSED_PARAM(xoffset);
- UNUSED_PARAM(yoffset);
- UNUSED_PARAM(format);
- UNUSED_PARAM(type);
- UNUSED_PARAM(video);
ec = 0;
- cleanupAfterGraphicsCall(false);
+ RefPtr<Image> image = videoFrameToImage(video);
+ if (!video)
+ return;
+ texSubImage2DImpl(target, level, xoffset, yoffset, format, type, image.get(), m_unpackFlipY, m_unpackPremultiplyAlpha, ec);
}
void WebGLRenderingContext::uniform1f(const WebGLUniformLocation* location, float x, ExceptionCode& ec)
@@ -2999,6 +3000,16 @@ bool WebGLRenderingContext::isGLES2Compliant()
return m_context->isGLES2Compliant();
}
+bool WebGLRenderingContext::isGLES2NPOTStrict()
+{
+ return m_context->isGLES2NPOTStrict();
+}
+
+bool WebGLRenderingContext::isErrorGeneratedOnOutOfBoundsAccesses()
+{
+ return m_context->isErrorGeneratedOnOutOfBoundsAccesses();
+}
+
void WebGLRenderingContext::handleNPOTTextures(bool prepareToDraw)
{
bool resetActiveUnit = false;
@@ -3536,14 +3547,14 @@ bool WebGLRenderingContext::simulateVertexAttrib0(long numVertex)
|| state.value[1] != m_vertexAttrib0BufferValue[1]
|| state.value[2] != m_vertexAttrib0BufferValue[2]
|| state.value[3] != m_vertexAttrib0BufferValue[3]) {
- RefPtr<Float32Array> bufferData = Float32Array::create((numVertex + 1) * 4);
+ OwnArrayPtr<float> bufferData(new float[(numVertex + 1) * 4]);
for (long ii = 0; ii < numVertex + 1; ++ii) {
- bufferData->set(ii * 4, state.value[0]);
- bufferData->set(ii * 4 + 1, state.value[1]);
- bufferData->set(ii * 4 + 2, state.value[2]);
- bufferData->set(ii * 4 + 3, state.value[3]);
+ bufferData[ii * 4] = state.value[0];
+ bufferData[ii * 4 + 1] = state.value[1];
+ bufferData[ii * 4 + 2] = state.value[2];
+ bufferData[ii * 4 + 3] = state.value[3];
}
- m_context->bufferData(GraphicsContext3D::ARRAY_BUFFER, bufferData.get(), GraphicsContext3D::DYNAMIC_DRAW);
+ m_context->bufferData(GraphicsContext3D::ARRAY_BUFFER, bufferDataSize, bufferData.get(), GraphicsContext3D::DYNAMIC_DRAW);
m_vertexAttrib0BufferSize = bufferDataSize;
m_vertexAttrib0BufferValue[0] = state.value[0];
m_vertexAttrib0BufferValue[1] = state.value[1];
@@ -3564,6 +3575,42 @@ void WebGLRenderingContext::restoreStatesAfterVertexAttrib0Simulation()
m_context->bindBuffer(GraphicsContext3D::ARRAY_BUFFER, objectOrZero(m_boundArrayBuffer.get()));
}
+WebGLRenderingContext::LRUImageBufferCache::LRUImageBufferCache(int capacity)
+ : m_buffers(new OwnPtr<ImageBuffer>[capacity])
+ , m_capacity(capacity)
+{
+}
+
+ImageBuffer* WebGLRenderingContext::LRUImageBufferCache::imageBuffer(const IntSize& size)
+{
+ int i;
+ for (i = 0; i < m_capacity; ++i) {
+ ImageBuffer* buf = m_buffers[i].get();
+ if (!buf)
+ break;
+ if (buf->size() != size)
+ continue;
+ bubbleToFront(i);
+ return buf;
+ }
+
+ OwnPtr<ImageBuffer> temp = ImageBuffer::create(size);
+ if (!temp)
+ return 0;
+ i = std::min(m_capacity - 1, i);
+ m_buffers[i] = temp.release();
+
+ ImageBuffer* buf = m_buffers[i].get();
+ bubbleToFront(i);
+ return buf;
+}
+
+void WebGLRenderingContext::LRUImageBufferCache::bubbleToFront(int idx)
+{
+ for (int i = idx; i > 0; --i)
+ m_buffers[i].swap(m_buffers[i-1]);
+}
+
} // namespace WebCore
#endif // ENABLE(3D_CANVAS)
diff --git a/WebCore/html/canvas/WebGLRenderingContext.h b/WebCore/html/canvas/WebGLRenderingContext.h
index 48fa7c8..66ec8d8 100644
--- a/WebCore/html/canvas/WebGLRenderingContext.h
+++ b/WebCore/html/canvas/WebGLRenderingContext.h
@@ -35,6 +35,8 @@
#include "Uint8Array.h"
#include "WebGLGetInfo.h"
+#include <wtf/OwnArrayPtr.h>
+
namespace WebCore {
class WebGLActiveInfo;
@@ -49,7 +51,9 @@ class WebGLTexture;
class WebGLUniformLocation;
class HTMLImageElement;
class HTMLVideoElement;
+class ImageBuffer;
class ImageData;
+class IntSize;
class WebKitCSSMatrix;
class WebGLRenderingContext : public CanvasRenderingContext {
@@ -281,8 +285,6 @@ public:
void removeObject(WebGLObject*);
- bool paintsIntoCanvasBuffer() const { return m_context->paintsIntoCanvasBuffer(); }
-
private:
friend class WebGLObject;
@@ -303,6 +305,8 @@ public:
}
bool isGLES2Compliant();
+ bool isGLES2NPOTStrict();
+ bool isErrorGeneratedOnOutOfBoundsAccesses();
// Helper to return the size in bytes of OpenGL data types
// like GL_FLOAT, GL_INT, etc.
@@ -320,6 +324,8 @@ public:
bool validateWebGLObject(WebGLObject* object);
+ PassRefPtr<Image> videoFrameToImage(HTMLVideoElement* video);
+
OwnPtr<GraphicsContext3D> m_context;
bool m_needsUpdate;
bool m_markedCanvasDirty;
@@ -387,6 +393,19 @@ public:
RefPtr<WebGLTexture> m_blackTexture2D;
RefPtr<WebGLTexture> m_blackTextureCubeMap;
+ // Fixed-size cache of reusable image buffers for video texImage2D calls.
+ class LRUImageBufferCache {
+ public:
+ LRUImageBufferCache(int capacity);
+ // The pointer returned is owned by the image buffer map.
+ ImageBuffer* imageBuffer(const IntSize& size);
+ private:
+ void bubbleToFront(int idx);
+ OwnArrayPtr<OwnPtr<ImageBuffer> > m_buffers;
+ int m_capacity;
+ };
+ LRUImageBufferCache m_videoCache;
+
int m_maxTextureSize;
int m_maxCubeMapTextureSize;
int m_maxTextureLevel;
diff --git a/WebCore/html/canvas/WebGLRenderingContext.idl b/WebCore/html/canvas/WebGLRenderingContext.idl
index 960dd0b..7a63752 100644
--- a/WebCore/html/canvas/WebGLRenderingContext.idl
+++ b/WebCore/html/canvas/WebGLRenderingContext.idl
@@ -464,213 +464,210 @@ module html {
const unsigned int UNPACK_FLIP_Y_WEBGL = 0x9240;
const unsigned int UNPACK_PREMULTIPLY_ALPHA_WEBGL = 0x9241;
- void activeTexture(in unsigned long texture) raises(DOMException);
- void attachShader(in WebGLProgram program, in WebGLShader shader) raises(DOMException);
- void bindAttribLocation(in WebGLProgram program, in unsigned long index, in DOMString name) raises(DOMException);
- void bindBuffer(in unsigned long target, in WebGLBuffer buffer) raises(DOMException);
- void bindFramebuffer(in unsigned long target, in WebGLFramebuffer framebuffer) raises(DOMException);
- void bindRenderbuffer(in unsigned long target, in WebGLRenderbuffer renderbuffer) raises(DOMException);
- void bindTexture(in unsigned long target, in WebGLTexture texture) raises(DOMException);
- void blendColor(in double red, in double green, in double blue, in double alpha);
- void blendEquation( in unsigned long mode );
- void blendEquationSeparate(in unsigned long modeRGB, in unsigned long modeAlpha);
- void blendFunc(in unsigned long sfactor, in unsigned long dfactor);
- void blendFuncSeparate(in unsigned long srcRGB, in unsigned long dstRGB, in unsigned long srcAlpha, in unsigned long dstAlpha);
- void bufferData(in unsigned long target, in ArrayBuffer data, in unsigned long usage) raises (DOMException);
- void bufferData(in unsigned long target, in ArrayBufferView data, in unsigned long usage) raises (DOMException);
- void bufferData(in unsigned long target, in long size, in unsigned long usage) raises (DOMException);
- void bufferSubData(in unsigned long target, in long offset, in ArrayBuffer data) raises (DOMException);
- void bufferSubData(in unsigned long target, in long offset, in ArrayBufferView data) raises (DOMException);
-
- unsigned long checkFramebufferStatus(in unsigned long target);
- void clear(in unsigned long mask);
- void clearColor(in double red, in double green, in double blue, in double alpha);
- void clearDepth(in double depth);
- void clearStencil(in long s);
- void colorMask(in boolean red, in boolean green, in boolean blue, in boolean alpha);
- void compileShader(in WebGLShader shader) raises(DOMException);
+ [StrictTypeChecking] void activeTexture(in unsigned long texture) raises(DOMException);
+ [StrictTypeChecking] void attachShader(in WebGLProgram program, in WebGLShader shader) raises(DOMException);
+ [StrictTypeChecking] void bindAttribLocation(in WebGLProgram program, in unsigned long index, in DOMString name) raises(DOMException);
+ [StrictTypeChecking] void bindBuffer(in unsigned long target, in WebGLBuffer buffer) raises(DOMException);
+ [StrictTypeChecking] void bindFramebuffer(in unsigned long target, in WebGLFramebuffer framebuffer) raises(DOMException);
+ [StrictTypeChecking] void bindRenderbuffer(in unsigned long target, in WebGLRenderbuffer renderbuffer) raises(DOMException);
+ [StrictTypeChecking] void bindTexture(in unsigned long target, in WebGLTexture texture) raises(DOMException);
+ [StrictTypeChecking] void blendColor(in double red, in double green, in double blue, in double alpha);
+ [StrictTypeChecking] void blendEquation( in unsigned long mode );
+ [StrictTypeChecking] void blendEquationSeparate(in unsigned long modeRGB, in unsigned long modeAlpha);
+ [StrictTypeChecking] void blendFunc(in unsigned long sfactor, in unsigned long dfactor);
+ [StrictTypeChecking] void blendFuncSeparate(in unsigned long srcRGB, in unsigned long dstRGB, in unsigned long srcAlpha, in unsigned long dstAlpha);
+ [StrictTypeChecking] void bufferData(in unsigned long target, in ArrayBuffer data, in unsigned long usage) raises (DOMException);
+ [StrictTypeChecking] void bufferData(in unsigned long target, in ArrayBufferView data, in unsigned long usage) raises (DOMException);
+ [StrictTypeChecking] void bufferData(in unsigned long target, in long size, in unsigned long usage) raises (DOMException);
+ [StrictTypeChecking] void bufferSubData(in unsigned long target, in long offset, in ArrayBuffer data) raises (DOMException);
+ [StrictTypeChecking] void bufferSubData(in unsigned long target, in long offset, in ArrayBufferView data) raises (DOMException);
+
+ [StrictTypeChecking] unsigned long checkFramebufferStatus(in unsigned long target);
+ [StrictTypeChecking] void clear(in unsigned long mask);
+ [StrictTypeChecking] void clearColor(in double red, in double green, in double blue, in double alpha);
+ [StrictTypeChecking] void clearDepth(in double depth);
+ [StrictTypeChecking] void clearStencil(in long s);
+ [StrictTypeChecking] void colorMask(in boolean red, in boolean green, in boolean blue, in boolean alpha);
+ [StrictTypeChecking] void compileShader(in WebGLShader shader) raises(DOMException);
//void compressedTexImage2D(in unsigned long target, in long level, in unsigned long internalformat, in unsigned long width, in unsigned long height, in long border, in unsigned long imageSize, const void* data);
//void compressedTexSubImage2D(in unsigned long target, in long level, in long xoffset, in long yoffset, in unsigned long width, in unsigned long height, in unsigned long format, in unsigned long imageSize, const void* data);
- void copyTexImage2D(in unsigned long target, in long level, in unsigned long internalformat, in long x, in long y, in unsigned long width, in unsigned long height, in long border);
- void copyTexSubImage2D(in unsigned long target, in long level, in long xoffset, in long yoffset, in long x, in long y, in unsigned long width, in unsigned long height);
-
- WebGLBuffer createBuffer();
- WebGLFramebuffer createFramebuffer();
- WebGLProgram createProgram();
- WebGLRenderbuffer createRenderbuffer();
- WebGLShader createShader(in unsigned long type) raises(DOMException);
- WebGLTexture createTexture();
-
- void cullFace(in unsigned long mode);
-
- void deleteBuffer(in WebGLBuffer buffer);
- void deleteFramebuffer(in WebGLFramebuffer framebuffer);
- void deleteProgram(in WebGLProgram program);
- void deleteRenderbuffer(in WebGLRenderbuffer renderbuffer);
- void deleteShader(in WebGLShader shader);
- void deleteTexture(in WebGLTexture texture);
-
- void depthFunc(in unsigned long func);
- void depthMask(in boolean flag);
+ [StrictTypeChecking] void copyTexImage2D(in unsigned long target, in long level, in unsigned long internalformat, in long x, in long y, in unsigned long width, in unsigned long height, in long border);
+ [StrictTypeChecking] void copyTexSubImage2D(in unsigned long target, in long level, in long xoffset, in long yoffset, in long x, in long y, in unsigned long width, in unsigned long height);
+
+ [StrictTypeChecking] WebGLBuffer createBuffer();
+ [StrictTypeChecking] WebGLFramebuffer createFramebuffer();
+ [StrictTypeChecking] WebGLProgram createProgram();
+ [StrictTypeChecking] WebGLRenderbuffer createRenderbuffer();
+ [StrictTypeChecking] WebGLShader createShader(in unsigned long type) raises(DOMException);
+ [StrictTypeChecking] WebGLTexture createTexture();
+
+ [StrictTypeChecking] void cullFace(in unsigned long mode);
+
+ [StrictTypeChecking] void deleteBuffer(in WebGLBuffer buffer);
+ [StrictTypeChecking] void deleteFramebuffer(in WebGLFramebuffer framebuffer);
+ [StrictTypeChecking] void deleteProgram(in WebGLProgram program);
+ [StrictTypeChecking] void deleteRenderbuffer(in WebGLRenderbuffer renderbuffer);
+ [StrictTypeChecking] void deleteShader(in WebGLShader shader);
+ [StrictTypeChecking] void deleteTexture(in WebGLTexture texture);
+
+ [StrictTypeChecking] void depthFunc(in unsigned long func);
+ [StrictTypeChecking] void depthMask(in boolean flag);
// FIXME: this differs from the current WebGL spec (depthRangef)
- void depthRange(in double zNear, in double zFar);
- void detachShader(in WebGLProgram program, in WebGLShader shader) raises(DOMException);
- void disable(in unsigned long cap);
- void disableVertexAttribArray(in unsigned long index) raises(DOMException);
- void drawArrays(in unsigned long mode, in long first, in long count) raises(DOMException);
- void drawElements(in unsigned long mode, in long count, in unsigned long type, in long offset) raises(DOMException);
-
- void enable(in unsigned long cap);
- void enableVertexAttribArray(in unsigned long index) raises(DOMException);
- void finish();
- void flush();
- void framebufferRenderbuffer(in unsigned long target, in unsigned long attachment, in unsigned long renderbuffertarget, in WebGLRenderbuffer renderbuffer) raises(DOMException);
- void framebufferTexture2D(in unsigned long target, in unsigned long attachment, in unsigned long textarget, in WebGLTexture texture, in long level) raises(DOMException);
- void frontFace(in unsigned long mode);
- void generateMipmap(in unsigned long target);
+ [StrictTypeChecking] void depthRange(in double zNear, in double zFar);
+ [StrictTypeChecking] void detachShader(in WebGLProgram program, in WebGLShader shader) raises(DOMException);
+ [StrictTypeChecking] void disable(in unsigned long cap);
+ [StrictTypeChecking] void disableVertexAttribArray(in unsigned long index) raises(DOMException);
+ [StrictTypeChecking] void drawArrays(in unsigned long mode, in long first, in long count) raises(DOMException);
+ [StrictTypeChecking] void drawElements(in unsigned long mode, in long count, in unsigned long type, in long offset) raises(DOMException);
+
+ [StrictTypeChecking] void enable(in unsigned long cap);
+ [StrictTypeChecking] void enableVertexAttribArray(in unsigned long index) raises(DOMException);
+ [StrictTypeChecking] void finish();
+ [StrictTypeChecking] void flush();
+ [StrictTypeChecking] void framebufferRenderbuffer(in unsigned long target, in unsigned long attachment, in unsigned long renderbuffertarget, in WebGLRenderbuffer renderbuffer) raises(DOMException);
+ [StrictTypeChecking] void framebufferTexture2D(in unsigned long target, in unsigned long attachment, in unsigned long textarget, in WebGLTexture texture, in long level) raises(DOMException);
+ [StrictTypeChecking] void frontFace(in unsigned long mode);
+ [StrictTypeChecking] void generateMipmap(in unsigned long target);
- WebGLActiveInfo getActiveAttrib(in WebGLProgram program, in unsigned long index)
- raises (DOMException);
- WebGLActiveInfo getActiveUniform(in WebGLProgram program, in unsigned long index)
- raises (DOMException);
+ [StrictTypeChecking] WebGLActiveInfo getActiveAttrib(in WebGLProgram program, in unsigned long index) raises (DOMException);
+ [StrictTypeChecking] WebGLActiveInfo getActiveUniform(in WebGLProgram program, in unsigned long index) raises (DOMException);
- [Custom] void getAttachedShaders(in WebGLProgram program)
- raises (DOMException);
+ [StrictTypeChecking, Custom] void getAttachedShaders(in WebGLProgram program) raises (DOMException);
- int getAttribLocation(in WebGLProgram program, in DOMString name);
+ [StrictTypeChecking] int getAttribLocation(in WebGLProgram program, in DOMString name);
// any getBufferParameter(in unsigned long target, in unsigned long pname) raises(DOMException);
- [Custom] void getBufferParameter();
+ [StrictTypeChecking, Custom] void getBufferParameter();
- WebGLContextAttributes getContextAttributes();
+ [StrictTypeChecking] WebGLContextAttributes getContextAttributes();
- unsigned long getError();
+ [StrictTypeChecking] unsigned long getError();
// any getFramebufferAttachmentParameter(in unsigned long target, in unsigned long attachment, in unsigned long pname) raises(DOMException);
- [Custom] void getFramebufferAttachmentParameter();
+ [StrictTypeChecking, Custom] void getFramebufferAttachmentParameter();
// any getParameter(in unsigned long pname) raises(DOMException);
- [Custom] void getParameter();
+ [StrictTypeChecking, Custom] void getParameter();
// any getProgramParameter(in WebGLProgram program, in unsigned long pname) raises(DOMException);
- [Custom] void getProgramParameter();
- DOMString getProgramInfoLog(in WebGLProgram program) raises(DOMException);
+ [StrictTypeChecking, Custom] void getProgramParameter();
+ [StrictTypeChecking] DOMString getProgramInfoLog(in WebGLProgram program) raises(DOMException);
// any getRenderbufferParameter(in unsigned long target, in unsigned long pname) raises(DOMException);
- [Custom] void getRenderbufferParameter();
+ [StrictTypeChecking, Custom] void getRenderbufferParameter();
// any getShaderParameter(in WebGLShader shader, in unsigned long pname) raises(DOMException);
- [Custom] void getShaderParameter() raises(DOMException);
+ [StrictTypeChecking, Custom] void getShaderParameter() raises(DOMException);
- DOMString getShaderInfoLog(in WebGLShader shader) raises(DOMException);
+ [StrictTypeChecking] DOMString getShaderInfoLog(in WebGLShader shader) raises(DOMException);
// TBD
// void glGetShaderPrecisionFormat (GLenum shadertype, GLenum precisiontype, GLint* range, GLint* precision);
- DOMString getShaderSource(in WebGLShader shader) raises(DOMException);
- DOMString getString(in unsigned long name);
+ [StrictTypeChecking] DOMString getShaderSource(in WebGLShader shader) raises(DOMException);
+ [StrictTypeChecking] DOMString getString(in unsigned long name);
// any getTexParameter(in unsigned long target, in unsigned long pname) raises(DOMException);
- [Custom] void getTexParameter();
+ [StrictTypeChecking, Custom] void getTexParameter();
// any getUniform(in WebGLProgram program, in WebGLUniformLocation location) raises(DOMException);
- [Custom] void getUniform();
+ [StrictTypeChecking, Custom] void getUniform();
- WebGLUniformLocation getUniformLocation(in WebGLProgram program, in DOMString name) raises(DOMException);
+ [StrictTypeChecking] WebGLUniformLocation getUniformLocation(in WebGLProgram program, in DOMString name) raises(DOMException);
// any getVertexAttrib(in unsigned long index, in unsigned long pname) raises(DOMException);
- [Custom] void getVertexAttrib();
-
- long getVertexAttribOffset(in unsigned long index, in unsigned long pname);
-
- void hint(in unsigned long target, in unsigned long mode);
- boolean isBuffer(in WebGLBuffer buffer);
- boolean isEnabled(in unsigned long cap);
- boolean isFramebuffer(in WebGLFramebuffer framebuffer);
- boolean isProgram(in WebGLProgram program);
- boolean isRenderbuffer(in WebGLRenderbuffer renderbuffer);
- boolean isShader(in WebGLShader shader);
- boolean isTexture(in WebGLTexture texture);
- void lineWidth(in double width);
- void linkProgram(in WebGLProgram program) raises(DOMException);
- void pixelStorei(in unsigned long pname, in long param);
- void polygonOffset(in double factor, in double units);
-
- void readPixels(in long x, in long y, in long width, in long height, in unsigned long format, in unsigned long type, in ArrayBufferView pixels);
+ [StrictTypeChecking, Custom] void getVertexAttrib();
+
+ [StrictTypeChecking] long getVertexAttribOffset(in unsigned long index, in unsigned long pname);
+
+ [StrictTypeChecking] void hint(in unsigned long target, in unsigned long mode);
+ [StrictTypeChecking] boolean isBuffer(in WebGLBuffer buffer);
+ [StrictTypeChecking] boolean isEnabled(in unsigned long cap);
+ [StrictTypeChecking] boolean isFramebuffer(in WebGLFramebuffer framebuffer);
+ [StrictTypeChecking] boolean isProgram(in WebGLProgram program);
+ [StrictTypeChecking] boolean isRenderbuffer(in WebGLRenderbuffer renderbuffer);
+ [StrictTypeChecking] boolean isShader(in WebGLShader shader);
+ [StrictTypeChecking] boolean isTexture(in WebGLTexture texture);
+ [StrictTypeChecking] void lineWidth(in double width);
+ [StrictTypeChecking] void linkProgram(in WebGLProgram program) raises(DOMException);
+ [StrictTypeChecking] void pixelStorei(in unsigned long pname, in long param);
+ [StrictTypeChecking] void polygonOffset(in double factor, in double units);
+
+ [StrictTypeChecking] void readPixels(in long x, in long y, in long width, in long height, in unsigned long format, in unsigned long type, in ArrayBufferView pixels);
- void releaseShaderCompiler();
- void renderbufferStorage(in unsigned long target, in unsigned long internalformat, in unsigned long width, in unsigned long height);
- void sampleCoverage(in double value, in boolean invert);
- void scissor(in long x, in long y, in unsigned long width, in unsigned long height);
- void shaderSource(in WebGLShader shader, in DOMString string) raises(DOMException);
- void stencilFunc(in unsigned long func, in long ref, in unsigned long mask);
- void stencilFuncSeparate(in unsigned long face, in unsigned long func, in long ref, in unsigned long mask);
- void stencilMask(in unsigned long mask);
- void stencilMaskSeparate(in unsigned long face, in unsigned long mask);
- void stencilOp(in unsigned long fail, in unsigned long zfail, in unsigned long zpass);
- void stencilOpSeparate(in unsigned long face, in unsigned long fail, in unsigned long zfail, in unsigned long zpass);
-
- void texParameterf(in unsigned long target, in unsigned long pname, in float param);
- void texParameteri(in unsigned long target, in unsigned long pname, in long param);
+ [StrictTypeChecking] void releaseShaderCompiler();
+ [StrictTypeChecking] void renderbufferStorage(in unsigned long target, in unsigned long internalformat, in unsigned long width, in unsigned long height);
+ [StrictTypeChecking] void sampleCoverage(in double value, in boolean invert);
+ [StrictTypeChecking] void scissor(in long x, in long y, in unsigned long width, in unsigned long height);
+ [StrictTypeChecking] void shaderSource(in WebGLShader shader, in DOMString string) raises(DOMException);
+ [StrictTypeChecking] void stencilFunc(in unsigned long func, in long ref, in unsigned long mask);
+ [StrictTypeChecking] void stencilFuncSeparate(in unsigned long face, in unsigned long func, in long ref, in unsigned long mask);
+ [StrictTypeChecking] void stencilMask(in unsigned long mask);
+ [StrictTypeChecking] void stencilMaskSeparate(in unsigned long face, in unsigned long mask);
+ [StrictTypeChecking] void stencilOp(in unsigned long fail, in unsigned long zfail, in unsigned long zpass);
+ [StrictTypeChecking] void stencilOpSeparate(in unsigned long face, in unsigned long fail, in unsigned long zfail, in unsigned long zpass);
+
+ [StrictTypeChecking] void texParameterf(in unsigned long target, in unsigned long pname, in float param);
+ [StrictTypeChecking] void texParameteri(in unsigned long target, in unsigned long pname, in long param);
// Supported forms:
- void texImage2D(in unsigned long target, in long level, in unsigned long internalformat, in long width, in long height,
- in long border, in unsigned long format, in unsigned long type, in ArrayBufferView pixels) raises (DOMException);
- void texImage2D(in unsigned long target, in long level, in unsigned long internalformat,
- in unsigned long format, in unsigned long type, in ImageData pixels) raises (DOMException);
- void texImage2D(in unsigned long target, in long level, in unsigned long internalformat,
- in unsigned long format, in unsigned long type, in HTMLImageElement image) raises (DOMException);
- void texImage2D(in unsigned long target, in long level, in unsigned long internalformat,
- in unsigned long format, in unsigned long type, in HTMLCanvasElement canvas) raises (DOMException);
- void texImage2D(in unsigned long target, in long level, in unsigned long internalformat,
- in unsigned long format, in unsigned long type, in HTMLVideoElement video) raises (DOMException);
-
- void texSubImage2D(in unsigned long target, in long level, in long xoffset, in long yoffset,
- in long width, in long height,
- in unsigned long format, in unsigned long type, in ArrayBufferView pixels) raises (DOMException);
- void texSubImage2D(in unsigned long target, in long level, in long xoffset, in long yoffset,
- in unsigned long format, in unsigned long type, in ImageData pixels) raises (DOMException);
- void texSubImage2D(in unsigned long target, in long level, in long xoffset, in long yoffset,
- in unsigned long format, in unsigned long type, in HTMLImageElement image) raises (DOMException);
- void texSubImage2D(in unsigned long target, in long level, in long xoffset, in long yoffset,
- in unsigned long format, in unsigned long type, in HTMLCanvasElement canvas) raises (DOMException);
- void texSubImage2D(in unsigned long target, in long level, in long xoffset, in long yoffset,
- in unsigned long format, in unsigned long type, in HTMLVideoElement video) raises (DOMException);
-
- void uniform1f(in WebGLUniformLocation location, in float x) raises(DOMException);
- [Custom] void uniform1fv(in WebGLUniformLocation location, in Float32Array v) raises(DOMException);
- void uniform1i(in WebGLUniformLocation location, in long x) raises(DOMException);
- [Custom] void uniform1iv(in WebGLUniformLocation location, in Int32Array v) raises(DOMException);
- void uniform2f(in WebGLUniformLocation location, in float x, in float y) raises(DOMException);
- [Custom] void uniform2fv(in WebGLUniformLocation location, in Float32Array v) raises(DOMException);
- void uniform2i(in WebGLUniformLocation location, in long x, in long y) raises(DOMException);
- [Custom] void uniform2iv(in WebGLUniformLocation location, in Int32Array v) raises(DOMException);
- void uniform3f(in WebGLUniformLocation location, in float x, in float y, in float z) raises(DOMException);
- [Custom] void uniform3fv(in WebGLUniformLocation location, in Float32Array v) raises(DOMException);
- void uniform3i(in WebGLUniformLocation location, in long x, in long y, in long z) raises(DOMException);
- [Custom] void uniform3iv(in WebGLUniformLocation location, in Int32Array v) raises(DOMException);
- void uniform4f(in WebGLUniformLocation location, in float x, in float y, in float z, in float w) raises(DOMException);
- [Custom] void uniform4fv(in WebGLUniformLocation location, in Float32Array v) raises(DOMException);
- void uniform4i(in WebGLUniformLocation location, in long x, in long y, in long z, in long w) raises(DOMException);
- [Custom] void uniform4iv(in WebGLUniformLocation location, in Int32Array v) raises(DOMException);
-
- [Custom] void uniformMatrix2fv(in WebGLUniformLocation location, in boolean transpose, in Float32Array array) raises(DOMException);
- [Custom] void uniformMatrix3fv(in WebGLUniformLocation location, in boolean transpose, in Float32Array array) raises(DOMException);
- [Custom] void uniformMatrix4fv(in WebGLUniformLocation location, in boolean transpose, in Float32Array array) raises(DOMException);
-
- void useProgram(in WebGLProgram program) raises(DOMException);
- void validateProgram(in WebGLProgram program) raises(DOMException);
-
- void vertexAttrib1f(in unsigned long indx, in float x);
- [Custom] void vertexAttrib1fv(in unsigned long indx, in Float32Array values);
- void vertexAttrib2f(in unsigned long indx, in float x, in float y);
- [Custom] void vertexAttrib2fv(in unsigned long indx, in Float32Array values);
- void vertexAttrib3f(in unsigned long indx, in float x, in float y, in float z);
- [Custom] void vertexAttrib3fv(in unsigned long indx, in Float32Array values);
- void vertexAttrib4f(in unsigned long indx, in float x, in float y, in float z, in float w);
- [Custom] void vertexAttrib4fv(in unsigned long indx, in Float32Array values);
- void vertexAttribPointer(in unsigned long indx, in long size, in unsigned long type, in boolean normalized,
- in long stride, in unsigned long offset) raises(DOMException);
-
- void viewport(in long x, in long y, in unsigned long width, in unsigned long height);
+ [StrictTypeChecking] void texImage2D(in unsigned long target, in long level, in unsigned long internalformat, in long width, in long height,
+ in long border, in unsigned long format, in unsigned long type, in ArrayBufferView pixels) raises (DOMException);
+ [StrictTypeChecking] void texImage2D(in unsigned long target, in long level, in unsigned long internalformat,
+ in unsigned long format, in unsigned long type, in ImageData pixels) raises (DOMException);
+ [StrictTypeChecking] void texImage2D(in unsigned long target, in long level, in unsigned long internalformat,
+ in unsigned long format, in unsigned long type, in HTMLImageElement image) raises (DOMException);
+ [StrictTypeChecking] void texImage2D(in unsigned long target, in long level, in unsigned long internalformat,
+ in unsigned long format, in unsigned long type, in HTMLCanvasElement canvas) raises (DOMException);
+ [StrictTypeChecking] void texImage2D(in unsigned long target, in long level, in unsigned long internalformat,
+ in unsigned long format, in unsigned long type, in HTMLVideoElement video) raises (DOMException);
+
+ [StrictTypeChecking] void texSubImage2D(in unsigned long target, in long level, in long xoffset, in long yoffset,
+ in long width, in long height,
+ in unsigned long format, in unsigned long type, in ArrayBufferView pixels) raises (DOMException);
+ [StrictTypeChecking] void texSubImage2D(in unsigned long target, in long level, in long xoffset, in long yoffset,
+ in unsigned long format, in unsigned long type, in ImageData pixels) raises (DOMException);
+ [StrictTypeChecking] void texSubImage2D(in unsigned long target, in long level, in long xoffset, in long yoffset,
+ in unsigned long format, in unsigned long type, in HTMLImageElement image) raises (DOMException);
+ [StrictTypeChecking] void texSubImage2D(in unsigned long target, in long level, in long xoffset, in long yoffset,
+ in unsigned long format, in unsigned long type, in HTMLCanvasElement canvas) raises (DOMException);
+ [StrictTypeChecking] void texSubImage2D(in unsigned long target, in long level, in long xoffset, in long yoffset,
+ in unsigned long format, in unsigned long type, in HTMLVideoElement video) raises (DOMException);
+
+ [StrictTypeChecking] void uniform1f(in WebGLUniformLocation location, in float x) raises(DOMException);
+ [StrictTypeChecking, Custom] void uniform1fv(in WebGLUniformLocation location, in Float32Array v) raises(DOMException);
+ [StrictTypeChecking] void uniform1i(in WebGLUniformLocation location, in long x) raises(DOMException);
+ [StrictTypeChecking, Custom] void uniform1iv(in WebGLUniformLocation location, in Int32Array v) raises(DOMException);
+ [StrictTypeChecking] void uniform2f(in WebGLUniformLocation location, in float x, in float y) raises(DOMException);
+ [StrictTypeChecking, Custom] void uniform2fv(in WebGLUniformLocation location, in Float32Array v) raises(DOMException);
+ [StrictTypeChecking] void uniform2i(in WebGLUniformLocation location, in long x, in long y) raises(DOMException);
+ [StrictTypeChecking, Custom] void uniform2iv(in WebGLUniformLocation location, in Int32Array v) raises(DOMException);
+ [StrictTypeChecking] void uniform3f(in WebGLUniformLocation location, in float x, in float y, in float z) raises(DOMException);
+ [StrictTypeChecking, Custom] void uniform3fv(in WebGLUniformLocation location, in Float32Array v) raises(DOMException);
+ [StrictTypeChecking] void uniform3i(in WebGLUniformLocation location, in long x, in long y, in long z) raises(DOMException);
+ [StrictTypeChecking, Custom] void uniform3iv(in WebGLUniformLocation location, in Int32Array v) raises(DOMException);
+ [StrictTypeChecking] void uniform4f(in WebGLUniformLocation location, in float x, in float y, in float z, in float w) raises(DOMException);
+ [StrictTypeChecking, Custom] void uniform4fv(in WebGLUniformLocation location, in Float32Array v) raises(DOMException);
+ [StrictTypeChecking] void uniform4i(in WebGLUniformLocation location, in long x, in long y, in long z, in long w) raises(DOMException);
+ [StrictTypeChecking, Custom] void uniform4iv(in WebGLUniformLocation location, in Int32Array v) raises(DOMException);
+
+ [StrictTypeChecking, Custom] void uniformMatrix2fv(in WebGLUniformLocation location, in boolean transpose, in Float32Array array) raises(DOMException);
+ [StrictTypeChecking, Custom] void uniformMatrix3fv(in WebGLUniformLocation location, in boolean transpose, in Float32Array array) raises(DOMException);
+ [StrictTypeChecking, Custom] void uniformMatrix4fv(in WebGLUniformLocation location, in boolean transpose, in Float32Array array) raises(DOMException);
+
+ [StrictTypeChecking] void useProgram(in WebGLProgram program) raises(DOMException);
+ [StrictTypeChecking] void validateProgram(in WebGLProgram program) raises(DOMException);
+
+ [StrictTypeChecking] void vertexAttrib1f(in unsigned long indx, in float x);
+ [StrictTypeChecking, Custom] void vertexAttrib1fv(in unsigned long indx, in Float32Array values);
+ [StrictTypeChecking] void vertexAttrib2f(in unsigned long indx, in float x, in float y);
+ [StrictTypeChecking, Custom] void vertexAttrib2fv(in unsigned long indx, in Float32Array values);
+ [StrictTypeChecking] void vertexAttrib3f(in unsigned long indx, in float x, in float y, in float z);
+ [StrictTypeChecking, Custom] void vertexAttrib3fv(in unsigned long indx, in Float32Array values);
+ [StrictTypeChecking] void vertexAttrib4f(in unsigned long indx, in float x, in float y, in float z, in float w);
+ [StrictTypeChecking, Custom] void vertexAttrib4fv(in unsigned long indx, in Float32Array values);
+ [StrictTypeChecking] void vertexAttribPointer(in unsigned long indx, in long size, in unsigned long type, in boolean normalized,
+ in long stride, in unsigned long offset) raises(DOMException);
+
+ [StrictTypeChecking] void viewport(in long x, in long y, in unsigned long width, in unsigned long height);
};
}
diff --git a/WebCore/html/canvas/WebGLTexture.cpp b/WebCore/html/canvas/WebGLTexture.cpp
index e6dfd0a..7b2869f 100644
--- a/WebCore/html/canvas/WebGLTexture.cpp
+++ b/WebCore/html/canvas/WebGLTexture.cpp
@@ -169,11 +169,12 @@ void WebGLTexture::generateMipmapLevelInfo()
m_needToUseBlackTexture = false;
}
-unsigned long WebGLTexture::getInternalFormat() const
+unsigned long WebGLTexture::getInternalFormat(int level) const
{
if (!object() || !m_target)
return 0;
- return m_info[0][0].internalFormat;
+ // We assume level has been validated already.
+ return m_info[0][level].internalFormat;
}
bool WebGLTexture::isNPOT(unsigned width, unsigned height)
diff --git a/WebCore/html/canvas/WebGLTexture.h b/WebCore/html/canvas/WebGLTexture.h
index 64bd6e0..a1ce348 100644
--- a/WebCore/html/canvas/WebGLTexture.h
+++ b/WebCore/html/canvas/WebGLTexture.h
@@ -60,7 +60,7 @@ public:
// Generate all level information.
void generateMipmapLevelInfo();
- unsigned long getInternalFormat() const;
+ unsigned long getInternalFormat(int level) const;
// Whether width/height is NotPowerOfTwo.
static bool isNPOT(unsigned, unsigned);
diff --git a/WebCore/inspector/CodeGeneratorInspector.pm b/WebCore/inspector/CodeGeneratorInspector.pm
index cd9052a..be0948b 100644
--- a/WebCore/inspector/CodeGeneratorInspector.pm
+++ b/WebCore/inspector/CodeGeneratorInspector.pm
@@ -17,30 +17,35 @@ $typeTransform{"InspectorClient"} = {
$typeTransform{"Backend"} = {
"forward" => "InspectorBackend",
"header" => "InspectorBackend.h",
- "handlerAccessor" => "m_inspectorController->inspectorBackend()",
+ "domainAccessor" => "m_inspectorController->inspectorBackend()",
};
$typeTransform{"Controller"} = {
"forwardHeader" => "InspectorController.h",
- "handlerAccessor" => "m_inspectorController",
+ "domainAccessor" => "m_inspectorController",
};
$typeTransform{"Debug"} = {
"forward" => "InspectorDebuggerAgent",
"header" => "InspectorDebuggerAgent.h",
- "handlerAccessor" => "m_inspectorController->debuggerAgent()",
+ "domainAccessor" => "m_inspectorController->debuggerAgent()",
};
$typeTransform{"DOM"} = {
"forward" => "InspectorDOMAgent",
"header" => "InspectorDOMAgent.h",
- "handlerAccessor" => "m_inspectorController->domAgent()",
+ "domainAccessor" => "m_inspectorController->domAgent()",
};
$typeTransform{"ApplicationCache"} = {
"forward" => "InspectorApplicationCacheAgent",
"header" => "InspectorApplicationCacheAgent.h",
- "handlerAccessor" => "m_inspectorController->applicationCacheAgent()",
+ "domainAccessor" => "m_inspectorController->applicationCacheAgent()",
+};
+$typeTransform{"Profiler"} = {
+ "forward" => "InspectorProfilerAgent",
+ "header" => "InspectorProfilerAgent.h",
+ "domainAccessor" => "m_inspectorController->profilerAgent()",
};
$typeTransform{"Frontend"} = {
- "forward" => "RemoteInspectorFrontend",
- "header" => "RemoteInspectorFrontend.h",
+ "forward" => "InspectorFrontend",
+ "header" => "InspectorFrontend.h",
};
$typeTransform{"PassRefPtr"} = {
"forwardHeader" => "wtf/PassRefPtr.h",
@@ -51,7 +56,7 @@ $typeTransform{"Object"} = {
"defaultValue" => "InspectorObject::create()",
"forward" => "InspectorObject",
"header" => "InspectorValues.h",
- "accessorSuffix" => "Object"
+ "JSONType" => "Object"
};
$typeTransform{"Array"} = {
"param" => "PassRefPtr<InspectorArray>",
@@ -59,7 +64,7 @@ $typeTransform{"Array"} = {
"defaultValue" => "InspectorArray::create()",
"forward" => "InspectorArray",
"header" => "InspectorValues.h",
- "accessorSuffix" => "Array"
+ "JSONType" => "Array"
};
$typeTransform{"Value"} = {
"param" => "PassRefPtr<InspectorValue>",
@@ -67,14 +72,15 @@ $typeTransform{"Value"} = {
"defaultValue" => "InspectorValue::null()",
"forward" => "InspectorValue",
"header" => "InspectorValues.h",
- "accessorSuffix" => "Value"
+ "JSONType" => "Value"
};
$typeTransform{"String"} = {
"param" => "const String&",
"variable" => "String",
+ "defaultValue" => "\"\"",
"forwardHeader" => "wtf/Forward.h",
"header" => "PlatformString.h",
- "accessorSuffix" => "String"
+ "JSONType" => "String"
};
$typeTransform{"long"} = {
"param" => "long",
@@ -82,7 +88,7 @@ $typeTransform{"long"} = {
"defaultValue" => "0",
"forward" => "",
"header" => "",
- "accessorSuffix" => "Number"
+ "JSONType" => "Number"
};
$typeTransform{"int"} = {
"param" => "int",
@@ -90,7 +96,7 @@ $typeTransform{"int"} = {
"defaultValue" => "0",
"forward" => "",
"header" => "",
- "accessorSuffix" => "Number",
+ "JSONType" => "Number",
};
$typeTransform{"unsigned long"} = {
"param" => "unsigned long",
@@ -98,7 +104,7 @@ $typeTransform{"unsigned long"} = {
"defaultValue" => "0u",
"forward" => "",
"header" => "",
- "accessorSuffix" => "Number"
+ "JSONType" => "Number"
};
$typeTransform{"unsigned int"} = {
"param" => "unsigned int",
@@ -106,7 +112,7 @@ $typeTransform{"unsigned int"} = {
"defaultValue" => "0u",
"forward" => "",
"header" => "",
- "accessorSuffix" => "Number"
+ "JSONType" => "Number"
};
$typeTransform{"boolean"} = {
"param" => "bool",
@@ -114,7 +120,7 @@ $typeTransform{"boolean"} = {
"defaultValue" => "false",
"forward" => "",
"header" => "",
- "accessorSuffix" => "Bool"
+ "JSONType" => "Bool"
};
$typeTransform{"void"} = {
"forward" => "",
@@ -157,10 +163,6 @@ my @frontendConstantDeclarations;
my @frontendConstantDefinitions;
my $frontendFooter;
-my $callId = new domSignature(); # it is just structure for describing parameters from IDLStructure.pm.
-$callId->type("long");
-$callId->name("callId");
-
# Default constructor
sub new
{
@@ -198,7 +200,7 @@ sub GenerateInterface
my $className = $interface->name;
- $frontendClassName = "Remote" . $className . "Frontend";
+ $frontendClassName = $className . "Frontend";
$frontendConstructor = " ${frontendClassName}(InspectorClient* inspectorClient) : m_inspectorClient(inspectorClient) { }";
$frontendFooter = " InspectorClient* m_inspectorClient;";
$frontendTypes{"String"} = 1;
@@ -217,9 +219,8 @@ sub GenerateInterface
$backendTypes{"Controller"} = 1;
$backendTypes{"InspectorClient"} = 1;
$backendTypes{"PassRefPtr"} = 1;
- $backendTypes{"Array"} = 1;
+ $backendTypes{"Object"} = 1;
- push(@backendMethodsImpl, generateBackendPrivateFunctions());
push(@backendMethodsImpl, generateBackendMessageParser());
generateFunctions($interface);
@@ -254,7 +255,6 @@ sub generateFrontendFunction
my @argsFiltered = grep($_->direction eq "out", @{$function->parameters}); # just keep only out parameters for frontend interface.
map($frontendTypes{$_->type} = 1, @argsFiltered); # register required types.
my $arguments = join(", ", map($typeTransform{$_->type}->{"param"} . " " . $_->name, @argsFiltered)); # prepare arguments for function signature.
- my @pushArguments = map(" arguments->push" . $typeTransform{$_->type}->{"accessorSuffix"} . "(" . $_->name . ");", @argsFiltered);
my $signature = " void ${functionName}(${arguments});";
if (!$frontendMethods{${signature}}) {
@@ -263,10 +263,14 @@ sub generateFrontendFunction
my @function;
push(@function, "void ${frontendClassName}::${functionName}(${arguments})");
push(@function, "{");
- push(@function, " RefPtr<InspectorArray> arguments = InspectorArray::create();");
- push(@function, " arguments->pushString(\"$functionName\");");
+ push(@function, " RefPtr<InspectorObject> ${functionName}Message = InspectorObject::create();");
+ push(@function, " ${functionName}Message->setString(\"type\", \"event\");");
+ push(@function, " ${functionName}Message->setString(\"event\", \"$functionName\");");
+ push(@function, " RefPtr<InspectorObject> payloadDataObject = InspectorObject::create();");
+ my @pushArguments = map(" payloadDataObject->set" . $typeTransform{$_->type}->{"JSONType"} . "(\"" . $_->name . "\", " . $_->name . ");", @argsFiltered);
push(@function, @pushArguments);
- push(@function, " m_inspectorClient->sendMessageToFrontend(arguments->toJSONString());");
+ push(@function, " ${functionName}Message->setObject(\"data\", payloadDataObject);");
+ push(@function, " m_inspectorClient->sendMessageToFrontend(${functionName}Message->toJSONString());");
push(@function, "}");
push(@function, "");
@@ -274,22 +278,6 @@ sub generateFrontendFunction
}
}
-sub generateBackendPrivateFunctions
-{
- my $privateFunctions = << "EOF";
-static String formatWrongArgumentsCountMessage(unsigned expected, unsigned actual)
-{
- return String::format("Wrong number of parameters: %d (expected: %d)", actual, expected);
-}
-
-static String formatWrongArgumentTypeMessage(unsigned position, const char* name, const char* expectedType)
-{
- return String::format("Failed to convert parameter %d (%s) to %s", position, name, expectedType);
-}
-EOF
- return split("\n", $privateFunctions);
-}
-
sub generateBackendFunction
{
my $function = shift;
@@ -300,74 +288,90 @@ sub generateBackendFunction
push(@backendConstantDefinitions, "const char* ${backendClassName}::${functionName}Cmd = \"${functionName}\";");
map($backendTypes{$_->type} = 1, @{$function->parameters}); # register required types
- my @inArgs = grep($_->direction eq "in", @{$function->parameters});
+ my @inArgs = grep($_->direction eq "in" && !($_->name eq "callId") , @{$function->parameters});
my @outArgs = grep($_->direction eq "out", @{$function->parameters});
- my $signature = " void ${functionName}(PassRefPtr<InspectorArray> args);";
+ my $signature = " void ${functionName}(long callId, InspectorObject* requestMessageObject);";
!$backendMethods{${signature}} || die "Duplicate function was detected for signature '$signature'.";
$backendMethods{${signature}} = $functionName;
my @function;
- push(@function, "void ${backendClassName}::${functionName}(PassRefPtr<InspectorArray> args)");
+ my $requestMessageObject = scalar(@inArgs) ? " requestMessageObject" : "";
+ push(@function, "void ${backendClassName}::${functionName}(long callId, InspectorObject*$requestMessageObject)");
push(@function, "{");
- push(@function, " long callId = 0;");
+ push(@function, " RefPtr<InspectorArray> protocolErrors = InspectorArray::create();");
push(@function, "");
- my $expectedParametersCount = scalar(@inArgs);
- my $expectedParametersCountWithMethodName = scalar(@inArgs) + 1;
- push(@function, " if (args->length() != $expectedParametersCountWithMethodName) {");
- push(@function, " ASSERT_NOT_REACHED();");
- push(@function, " reportProtocolError(callId, ${functionName}Cmd, formatWrongArgumentsCountMessage(args->length() - 1, $expectedParametersCount));");
- push(@function, " return;");
- push(@function, " }");
+ my $domain = $function->signature->extendedAttributes->{"handler"} || "Controller";
+ my $domainAccessor = $typeTransform{$domain}->{"domainAccessor"};
+ $backendTypes{$domain} = 1;
+ push(@function, " if (!$domainAccessor)");
+ push(@function, " protocolErrors->pushString(String::format(\"Error: %s handler is not available.\", \"$domain\"));");
push(@function, "");
- my $i = 1; # zero element is the method name.
- foreach my $parameter (@inArgs) {
- my $type = $parameter->type;
- my $argumentType = $typeTransform{$type}->{"variable"};
- push(@function, " $argumentType " . $parameter->name . ";") if !($parameter->name eq "callId");
- push(@function, " if (!args->get($i)->as" . $typeTransform{$type}->{"accessorSuffix"} . "(&" . $parameter->name . ")) {");
+ if (scalar(@inArgs)) {
+ # declare variables for all 'in' args;
+ push(@function, map(" " . $typeTransform{$_->type}->{"variable"} . " " . $_->name . " = " . $typeTransform{$_->type}->{"defaultValue"} . ";", @inArgs));
+
+ push(@function, "");
+ push(@function, " RefPtr<InspectorObject> argumentsContainer;");
+ push(@function, " if (!(argumentsContainer = requestMessageObject->getObject(\"arguments\"))) {");
push(@function, " ASSERT_NOT_REACHED();");
- push(@function, " reportProtocolError(callId, ${functionName}Cmd, formatWrongArgumentTypeMessage($i, \"" . $parameter->name . "\", \"$type\"));");
- push(@function, " return;");
+ push(@function, " protocolErrors->pushString(String::format(\"Error: arguments object was not found.\"));");
+ push(@function, " } else {");
+ push(@function, " InspectorObject::const_iterator argumentsEndIterator = argumentsContainer->end();");
+
+ foreach my $parameter (@inArgs) {
+ my $name = $parameter->name;
+ my $type = $parameter->type;
+ my $variableType = $typeTransform{$type}->{"variable"};
+ my $JSONType = $typeTransform{$type}->{"JSONType"};
+
+ push(@function, "");
+ push(@function, " InspectorObject::const_iterator ${name}ValueIterator = argumentsContainer->find(\"$name\");");
+ push(@function, " if (${name}ValueIterator == argumentsEndIterator) {");
+ push(@function, " ASSERT_NOT_REACHED();");
+ push(@function, " protocolErrors->pushString(String::format(\"Error: Argument '%s' with type '%s' was not found.\", \"$name\", \"$JSONType\"));");
+ push(@function, " } else {");
+ push(@function, " if (!${name}ValueIterator->second->as$JSONType(&$name)) {");
+ push(@function, " ASSERT_NOT_REACHED();");
+ push(@function, " protocolErrors->pushString(String::format(\"Error: Argument '%s' has wrong type. It should be '%s'.\", \"$name\", \"$JSONType\"));");
+ push(@function, " }");
+ push(@function, " }");
+ }
push(@function, " }");
- push(@function, "");
- ++$i;
}
- my $handler = $function->signature->extendedAttributes->{"handler"} || "Controller";
- my $handlerAccessor = $typeTransform{$handler}->{"handlerAccessor"};
- $backendTypes{$handler} = 1;
- push(@function, " if (!$handlerAccessor) {");
- push(@function, " reportProtocolError(callId, ${functionName}Cmd, \"Error: $handler handler is not available.\");");
- push(@function, " return;");
- push(@function, " }");
- push(@function, "");
+ # declare local variables for out arguments.
+ push(@function, map(" " . $typeTransform{$_->type}->{"variable"} . " " . $_->name . " = " . $typeTransform{$_->type}->{"defaultValue"} . ";", @outArgs));
+ my $args = join(", ", (map($_->name, @inArgs), map("&" . $_->name, @outArgs)));
+ push(@function, " if (!protocolErrors->length())");
+ push(@function, " $domainAccessor->$functionName($args);");
+ push(@function, "");
- foreach (@outArgs) { # declare local variables for out arguments.
- my $initializer = $typeTransform{$_->type}->{"defaultValue"} ? " = " . $typeTransform{$_->type}->{"defaultValue"} : "";
- push(@function, " " . $typeTransform{$_->type}->{"variable"} . " " . $_->name . "$initializer;");
+ push(@function, " // use InspectorFrontend as a marker of WebInspector availability");
+ push(@function, " if (callId && m_inspectorController->hasFrontend()) {");
+ push(@function, " RefPtr<InspectorObject> responseMessage = InspectorObject::create();");
+ push(@function, " responseMessage->setNumber(\"seq\", callId);");
+ push(@function, " responseMessage->setString(\"type\", \"response\");");
+ push(@function, " responseMessage->setString(\"domain\", \"$domain\");");
+ push(@function, " responseMessage->setString(\"command\", \"$functionName\");");
+ push(@function, " responseMessage->setBool(\"success\", !protocolErrors->length());");
+ push(@function, "");
+ push(@function, " if (protocolErrors->length())");
+ push(@function, " responseMessage->setArray(\"errors\", protocolErrors);");
+ if (scalar(@outArgs)) {
+ push(@function, " else {");
+ push(@function, " RefPtr<InspectorObject> responseData = InspectorObject::create();");
+ push(@function, map(" responseData->set" . $typeTransform{$_->type}->{"JSONType"} . "(\"" . $_->name . "\", " . $_->name . ");", @outArgs));
+ push(@function, " responseMessage->setObject(\"data\", responseData);");
+ push(@function, " }");
}
+ push(@function, " m_inspectorController->inspectorClient()->sendMessageToFrontend(responseMessage->toJSONString());");
+ push(@function, " }");
- my $args = join(", ", (grep(!($_ eq "callId"), map($_->name, @inArgs)), map("&" . $_->name, @outArgs)));
- push(@function, " $handlerAccessor->$functionName($args);");
-
- # The results of function call should be transfered back to frontend.
- if (scalar(grep($_->name eq "callId", @inArgs))) {
- my @pushArguments = map(" arguments->push" . $typeTransform{$_->type}->{"accessorSuffix"} . "(" . $_->name . ");", @outArgs);
- push(@function, "");
- push(@function, " // use InspectorFrontend as a marker of WebInspector availability");
- push(@function, " if (m_inspectorController->hasFrontend()) {");
- push(@function, " RefPtr<InspectorArray> arguments = InspectorArray::create();");
- push(@function, " arguments->pushString(\"processResponse\");");
- push(@function, " arguments->pushNumber(callId);");
- push(@function, @pushArguments);
- push(@function, " m_inspectorController->inspectorClient()->sendMessageToFrontend(arguments->toJSONString());");
- push(@function, " }");
- }
push(@function, "}");
push(@function, "");
push(@backendMethodsImpl, @function);
@@ -379,17 +383,22 @@ sub generateBackendReportProtocolError
void ${backendClassName}::reportProtocolError(const long callId, const String& method, const String& errorText) const
{
- RefPtr<InspectorArray> arguments = InspectorArray::create();
- arguments->pushString("reportProtocolError");
- arguments->pushNumber(callId);
- arguments->pushString(method);
- arguments->pushString(errorText);
- m_inspectorController->inspectorClient()->sendMessageToFrontend(arguments->toJSONString());
+ RefPtr<InspectorObject> message = InspectorObject::create();
+ message->setNumber("seq", callId);
+ message->setString("type", "error");
+ message->setString("domain", "inspectorProtocol");
+ message->setString("command", method);
+ message->setBool("success", false);
+ RefPtr<InspectorArray> errors = InspectorArray::create();
+ errors->pushString(errorText);
+ message->setArray("errors", errors);
+ m_inspectorController->inspectorClient()->sendMessageToFrontend(message->toJSONString());
}
EOF
return split("\n", $reportProtocolError);
}
+
sub generateBackendDispatcher
{
my @body;
@@ -400,9 +409,11 @@ sub generateBackendDispatcher
my $backendDispatcherBody = << "EOF";
void ${backendClassName}::dispatch(const String& message)
{
- typedef void (${backendClassName}::*CallHandler)(PassRefPtr<InspectorArray> args);
+ typedef void (${backendClassName}::*CallHandler)(long callId, InspectorObject* messageObject);
typedef HashMap<String, CallHandler> DispatchMap;
DEFINE_STATIC_LOCAL(DispatchMap, dispatchMap, );
+ long callId = 0;
+
if (dispatchMap.isEmpty()) {
$mapEntries
}
@@ -410,38 +421,52 @@ $mapEntries
RefPtr<InspectorValue> parsedMessage = InspectorValue::parseJSON(message);
if (!parsedMessage) {
ASSERT_NOT_REACHED();
- reportProtocolError(0, "dispatch", "Error: Invalid message format. Message should be in JSON format.");
+ reportProtocolError(callId, "dispatch", "Error: Invalid message format. Message should be in JSON format.");
+ return;
+ }
+
+ RefPtr<InspectorObject> messageObject = parsedMessage->asObject();
+ if (!messageObject) {
+ ASSERT_NOT_REACHED();
+ reportProtocolError(callId, "dispatch", "Error: Invalid message format. The message should be a JSONified object.");
return;
}
- RefPtr<InspectorArray> messageArray = parsedMessage->asArray();
- if (!messageArray) {
+ RefPtr<InspectorValue> callIdValue = messageObject->get("seq");
+ if (!callIdValue) {
ASSERT_NOT_REACHED();
- reportProtocolError(0, "dispatch", "Error: Invalid message format. The message should be a JSONified array of arguments.");
+ reportProtocolError(callId, "dispatch", "Error: Invalid message format. 'seq' property was not found in the request.");
return;
}
- if (!messageArray->length()) {
+ if (!callIdValue->asNumber(&callId)) {
ASSERT_NOT_REACHED();
- reportProtocolError(0, "dispatch", "Error: Invalid message format. Empty message was received.");
+ reportProtocolError(callId, "dispatch", "Error: Invalid message format. the type of 'seq' property should be number.");
return;
}
- String methodName;
- if (!messageArray->get(0)->asString(&methodName)) {
+ RefPtr<InspectorValue> commandValue = messageObject->get("command");
+ if (!commandValue) {
ASSERT_NOT_REACHED();
- reportProtocolError(0, "dispatch", "Error: Invalid message format. The first element of the message should be method name.");
+ reportProtocolError(callId, "dispatch", "Error: Invalid message format. 'command' property wasn't found.");
return;
}
- HashMap<String, CallHandler>::iterator it = dispatchMap.find(methodName);
+ String command;
+ if (!commandValue->asString(&command)) {
+ ASSERT_NOT_REACHED();
+ reportProtocolError(callId, "dispatch", "Error: Invalid message format. The type of 'command' property should be string.");
+ return;
+ }
+
+ HashMap<String, CallHandler>::iterator it = dispatchMap.find(command);
if (it == dispatchMap.end()) {
ASSERT_NOT_REACHED();
- reportProtocolError(0, "dispatch", String::format("Error: Invalid method name. '%s' wasn't found.", methodName.utf8().data()));
+ reportProtocolError(callId, "dispatch", String::format("Error: Invalid command was received. '%s' wasn't found.", command.utf8().data()));
return;
}
- ((*this).*it->second)(messageArray);
+ ((*this).*it->second)(callId, messageObject.get());
}
EOF
return split("\n", $backendDispatcherBody);
@@ -455,14 +480,18 @@ bool ${backendClassName}::getCommandName(const String& message, String* result)
RefPtr<InspectorValue> value = InspectorValue::parseJSON(message);
if (!value)
return false;
- RefPtr<InspectorArray> array = value->asArray();
- if (!array)
+
+ RefPtr<InspectorObject> object = value->asObject();
+ if (!object)
return false;
- if (!array->length())
+ RefPtr<InspectorValue> commandValue = object->get("command");
+ if (!commandValue)
return false;
- return array->get(0)->asString(result);
+
+ return commandValue->asString(result);
}
+
EOF
return split("\n", $messageParserBody);
}
@@ -471,7 +500,20 @@ sub generateBackendStubJS
{
my $interface = shift;
my @backendFunctions = grep(!$_->signature->extendedAttributes->{"notify"}, @{$interface->functions});
- my @JSStubs = map(" this._registerDelegate(\"" . $_->signature->name . "\");", @backendFunctions);
+ my @JSStubs;
+
+ foreach my $function (@backendFunctions) {
+ my $name = $function->signature->name;
+ my $domain = $function->signature->extendedAttributes->{"handler"};
+ my $argumentNames = join(",", map("\"" . $_->name . "\": null", grep($_->direction eq "in", @{$function->parameters})));
+ push(@JSStubs, " this._registerDelegate('{" .
+ "\"seq\": 0, " .
+ "\"type\": \"request\", " .
+ "\"domain\": \"$domain\", " .
+ "\"command\": \"$name\", " .
+ "\"arguments\": {$argumentNames}" .
+ "}');");
+ }
my $JSStubs = join("\n", @JSStubs);
my $inspectorBackendStubJS = << "EOF";
@@ -483,14 +525,26 @@ $JSStubs
}
WebInspector.InspectorBackendStub.prototype = {
- _registerDelegate: function(methodName)
+ _registerDelegate: function(commandInfo)
{
- this[methodName] = this.sendMessageToBackend.bind(this, methodName);
+ var commandObject = JSON.parse(commandInfo);
+ this[commandObject.command] = this.sendMessageToBackend.bind(this, commandInfo);
},
sendMessageToBackend: function()
{
- var message = JSON.stringify(Array.prototype.slice.call(arguments));
+ var args = Array.prototype.slice.call(arguments);
+ var request = JSON.parse(args.shift());
+ for (var key in request.arguments) {
+ if (key === "callId")
+ request.seq = args.shift();
+ else
+ request.arguments[key] = args.shift();
+ }
+ if (args.length === 1 && typeof args[0] === "function")
+ request.seq = WebInspector.Callback.wrap(args[0]);
+
+ var message = JSON.stringify(request);
InspectorFrontendHost.sendMessageToBackend(message);
}
}
diff --git a/WebCore/inspector/ConsoleMessage.cpp b/WebCore/inspector/ConsoleMessage.cpp
index 6f19d2a..f3bd6bc 100644
--- a/WebCore/inspector/ConsoleMessage.cpp
+++ b/WebCore/inspector/ConsoleMessage.cpp
@@ -38,7 +38,7 @@
#include "ScriptValue.h"
#if ENABLE(INSPECTOR)
-#include "RemoteInspectorFrontend.h"
+#include "InspectorFrontend.h"
#endif
namespace WebCore {
@@ -114,7 +114,7 @@ ConsoleMessage::ConsoleMessage(MessageSource s, MessageType t, MessageLevel l, c
}
#if ENABLE(INSPECTOR)
-void ConsoleMessage::addToFrontend(RemoteInspectorFrontend* frontend, InjectedScriptHost* injectedScriptHost)
+void ConsoleMessage::addToFrontend(InspectorFrontend* frontend, InjectedScriptHost* injectedScriptHost)
{
RefPtr<InspectorObject> jsonObj = InspectorObject::create();
jsonObj->setNumber("source", static_cast<int>(m_source));
@@ -149,7 +149,7 @@ void ConsoleMessage::addToFrontend(RemoteInspectorFrontend* frontend, InjectedSc
frontend->addConsoleMessage(jsonObj);
}
-void ConsoleMessage::updateRepeatCountInConsole(RemoteInspectorFrontend* frontend)
+void ConsoleMessage::updateRepeatCountInConsole(InspectorFrontend* frontend)
{
frontend->updateConsoleMessageRepeatCount(m_repeatCount);
}
diff --git a/WebCore/inspector/ConsoleMessage.h b/WebCore/inspector/ConsoleMessage.h
index e286f0a..d10fa3d 100644
--- a/WebCore/inspector/ConsoleMessage.h
+++ b/WebCore/inspector/ConsoleMessage.h
@@ -39,8 +39,8 @@
namespace WebCore {
class InjectedScriptHost;
+class InspectorFrontend;
class InspectorObject;
-class RemoteInspectorFrontend;
class ScriptCallFrame;
class ScriptCallStack;
class ScriptValue;
@@ -51,8 +51,8 @@ public:
ConsoleMessage(MessageSource, MessageType, MessageLevel, const String& m, ScriptCallStack*, unsigned g, bool storeTrace = false);
#if ENABLE(INSPECTOR)
- void addToFrontend(RemoteInspectorFrontend*, InjectedScriptHost*);
- void updateRepeatCountInConsole(RemoteInspectorFrontend* frontend);
+ void addToFrontend(InspectorFrontend*, InjectedScriptHost*);
+ void updateRepeatCountInConsole(InspectorFrontend* frontend);
#endif
void incrementCount() { ++m_repeatCount; }
bool isEqual(ScriptState*, ConsoleMessage* msg) const;
diff --git a/WebCore/inspector/InjectedScript.h b/WebCore/inspector/InjectedScript.h
index 17389ba..f80cfb4 100644
--- a/WebCore/inspector/InjectedScript.h
+++ b/WebCore/inspector/InjectedScript.h
@@ -54,6 +54,7 @@ public:
#endif
PassRefPtr<InspectorValue> wrapForConsole(ScriptValue);
void releaseWrapperObjectGroup(const String&);
+ ScriptState* scriptState() const { return m_injectedScriptObject.scriptState(); }
private:
friend InjectedScript InjectedScriptHost::injectedScriptFor(ScriptState*);
diff --git a/WebCore/inspector/InjectedScriptHost.cpp b/WebCore/inspector/InjectedScriptHost.cpp
index 37512be..06b25fe 100644
--- a/WebCore/inspector/InjectedScriptHost.cpp
+++ b/WebCore/inspector/InjectedScriptHost.cpp
@@ -42,9 +42,9 @@
#include "InspectorClient.h"
#include "InspectorController.h"
#include "InspectorDOMAgent.h"
+#include "InspectorFrontend.h"
#include "InspectorResource.h"
#include "Pasteboard.h"
-#include "RemoteInspectorFrontend.h"
#if ENABLE(JAVASCRIPT_DEBUGGER)
#include "ScriptDebugServer.h"
@@ -98,15 +98,14 @@ Node* InjectedScriptHost::nodeForId(long nodeId)
long InjectedScriptHost::pushNodePathToFrontend(Node* node, bool withChildren, bool selectInUI)
{
- RemoteInspectorFrontend* frontend = remoteFrontend();
InspectorDOMAgent* domAgent = inspectorDOMAgent();
- if (!domAgent || !frontend)
+ if (!domAgent || !frontend())
return 0;
long id = domAgent->pushNodePathToFrontend(node);
if (withChildren)
domAgent->pushChildNodesToFrontend(id);
if (selectInUI)
- frontend->updateFocusedNode(id);
+ frontend()->updateFocusedNode(id);
return id;
}
@@ -149,6 +148,9 @@ InjectedScript InjectedScriptHost::injectedScriptForId(long id)
void InjectedScriptHost::discardInjectedScripts()
{
+ IdToInjectedScriptMap::iterator end = m_idToInjectedScript.end();
+ for (IdToInjectedScriptMap::iterator it = m_idToInjectedScript.begin(); it != end; ++it)
+ discardInjectedScript(it->second.scriptState());
m_idToInjectedScript.clear();
}
@@ -172,11 +174,11 @@ InspectorDOMAgent* InjectedScriptHost::inspectorDOMAgent()
return m_inspectorController->domAgent();
}
-RemoteInspectorFrontend* InjectedScriptHost::remoteFrontend()
+InspectorFrontend* InjectedScriptHost::frontend()
{
if (!m_inspectorController)
return 0;
- return m_inspectorController->m_remoteFrontend.get();
+ return m_inspectorController->m_frontend.get();
}
pair<long, ScriptObject> InjectedScriptHost::injectScript(const String& source, ScriptState* scriptState)
diff --git a/WebCore/inspector/InjectedScriptHost.h b/WebCore/inspector/InjectedScriptHost.h
index 997f340..6b70f62 100644
--- a/WebCore/inspector/InjectedScriptHost.h
+++ b/WebCore/inspector/InjectedScriptHost.h
@@ -43,8 +43,8 @@ namespace WebCore {
class Database;
class InjectedScript;
class InspectorDOMAgent;
+class InspectorFrontend;
class Node;
-class RemoteInspectorFrontend;
class ScriptObject;
class Storage;
@@ -58,6 +58,7 @@ public:
~InjectedScriptHost();
+ String injectedScriptSource() { return m_injectedScriptSource; }
void setInjectedScriptSource(const String& source) { m_injectedScriptSource = source; }
InspectorController* inspectorController() { return m_inspectorController; }
@@ -94,8 +95,9 @@ public:
private:
InjectedScriptHost(InspectorController* inspectorController);
InspectorDOMAgent* inspectorDOMAgent();
- RemoteInspectorFrontend* remoteFrontend();
+ InspectorFrontend* frontend();
ScriptObject createInjectedScript(const String& source, ScriptState* scriptState, long id);
+ void discardInjectedScript(ScriptState*);
InspectorController* m_inspectorController;
String m_injectedScriptSource;
diff --git a/WebCore/inspector/Inspector.idl b/WebCore/inspector/Inspector.idl
index 1c66b59..a56ef14 100644
--- a/WebCore/inspector/Inspector.idl
+++ b/WebCore/inspector/Inspector.idl
@@ -47,9 +47,6 @@ module core {
[notify] void inspectedURLChanged(out String url);
[notify] void monitoringXHRWasEnabled();
[notify] void monitoringXHRWasDisabled();
- [notify] void populateApplicationSettings(out String settings);
- [notify] void populateInterface();
- [notify] void populateSessionSettings(out String settings);
[notify] void removeResource(out unsigned long identifier);
[notify] void reset();
[notify] void resetProfilesPanel();
@@ -102,6 +99,10 @@ module core {
[notify] void didDestroyWorker(out long id);
#endif
+ // This method is going to be broken down into smaller parts.
+ [handler=Controller] void populateScriptObjects();
+
+ [handler=Controller] void getSettings(in long callId, out Object settings);
[handler=Controller] void storeLastActivePanel(in String panelName);
[handler=Controller] void saveApplicationSettings(in String settings);
@@ -145,14 +146,14 @@ module core {
[handler=Controller] void enableProfiler(in boolean always);
[handler=Controller] void disableProfiler(in boolean always);
- [handler=Controller] void startProfiling();
- [handler=Controller] void stopProfiling();
+ [handler=Profiler] void startProfiling();
+ [handler=Profiler] void stopProfiling();
- [handler=Controller] void getProfileHeaders(in long callId, out Array headers);
- [handler=Controller] void getProfile(in long callId, in unsigned long uid, out Object profile);
+ [handler=Profiler] void getProfileHeaders(in long callId, out Array headers);
+ [handler=Profiler] void getProfile(in long callId, in unsigned long uid, out Object profile);
- [handler=Controller] void removeProfile(in unsigned long uid);
- [handler=Controller] void clearProfiles();
+ [handler=Profiler] void removeProfile(in unsigned long uid);
+ [handler=Profiler] void clearProfiles();
[handler=Backend] void takeHeapSnapshot();
[handler=Backend] void getProfilerLogLines(in long callId, in long inPosition, out long outPosition, out String log);
@@ -176,6 +177,8 @@ module core {
[handler=DOM] void performSearch(in String query, in boolean runSynchronously);
[handler=DOM] void searchCanceled();
[handler=DOM] void pushNodeByPathToFrontend(in long callId, in String path, out long nodeId);
+ [handler=DOM] void setDOMBreakpoint(in long nodeId, in long type);
+ [handler=DOM] void removeDOMBreakpoint(in long nodeId, in long type);
[handler=Controller] void clearConsoleMessages();
[handler=Controller] void highlightDOMNode(in long nodeId);
@@ -194,6 +197,7 @@ module core {
[handler=DOM] void toggleStyleEnabled(in long callId, in long styleId, in String propertyName, in boolean disabled, out Value style);
[handler=DOM] void setRuleSelector(in long callId, in long ruleId, in String selector, in long selectedNodeId, out Value rule, out boolean selectorAffectsNode);
[handler=DOM] void addRule(in long callId, in String selector, in long selectedNodeId, out Value rule, out boolean selectorAffectsNode);
+ [handler=DOM] void getSupportedCSSProperties(in long callId, out Array cssProperties);
[handler=Controller] void getCookies(in long callId, out Array cookies, out String cookiesString);
[handler=Controller] void deleteCookie(in String cookieName, in String domain);
diff --git a/WebCore/inspector/InspectorApplicationCacheAgent.cpp b/WebCore/inspector/InspectorApplicationCacheAgent.cpp
index 1206184..918643b 100644
--- a/WebCore/inspector/InspectorApplicationCacheAgent.cpp
+++ b/WebCore/inspector/InspectorApplicationCacheAgent.cpp
@@ -33,14 +33,14 @@
#include "Frame.h"
#include "FrameLoader.h"
#include "InspectorController.h"
+#include "InspectorFrontend.h"
#include "InspectorValues.h"
#include "Page.h"
-#include "RemoteInspectorFrontend.h"
#include "ResourceResponse.h"
namespace WebCore {
-InspectorApplicationCacheAgent::InspectorApplicationCacheAgent(InspectorController* inspectorController, RemoteInspectorFrontend* frontend)
+InspectorApplicationCacheAgent::InspectorApplicationCacheAgent(InspectorController* inspectorController, InspectorFrontend* frontend)
: m_inspectorController(inspectorController)
, m_frontend(frontend)
{
diff --git a/WebCore/inspector/InspectorApplicationCacheAgent.h b/WebCore/inspector/InspectorApplicationCacheAgent.h
index 3338f84..11f10ce 100644
--- a/WebCore/inspector/InspectorApplicationCacheAgent.h
+++ b/WebCore/inspector/InspectorApplicationCacheAgent.h
@@ -35,14 +35,14 @@ namespace WebCore {
class InspectorArray;
class InspectorController;
+class InspectorFrontend;
class InspectorObject;
class InspectorValue;
-class RemoteInspectorFrontend;
class ResourceResponse;
class InspectorApplicationCacheAgent : public Noncopyable {
public:
- InspectorApplicationCacheAgent(InspectorController* inspectorController, RemoteInspectorFrontend* frontend);
+ InspectorApplicationCacheAgent(InspectorController* inspectorController, InspectorFrontend* frontend);
~InspectorApplicationCacheAgent() { }
// Backend to Frontend
@@ -59,7 +59,7 @@ private:
PassRefPtr<InspectorObject> buildObjectForApplicationCacheResource(const ApplicationCacheHost::ResourceInfo&);
InspectorController* m_inspectorController;
- RemoteInspectorFrontend* m_frontend;
+ InspectorFrontend* m_frontend;
};
} // namespace WebCore
diff --git a/WebCore/inspector/InspectorBackend.cpp b/WebCore/inspector/InspectorBackend.cpp
index f0ed94b..99f40a9 100644
--- a/WebCore/inspector/InspectorBackend.cpp
+++ b/WebCore/inspector/InspectorBackend.cpp
@@ -40,8 +40,8 @@
#include "InjectedScriptHost.h"
#include "InspectorController.h"
#include "InspectorDOMAgent.h"
+#include "InspectorFrontend.h"
#include "InspectorStorageAgent.h"
-#include "RemoteInspectorFrontend.h"
#include "ScriptBreakpoint.h"
#include "ScriptProfiler.h"
#include "SerializedScriptValue.h"
@@ -88,7 +88,7 @@ void InspectorBackend::setInjectedScriptSource(const String& source)
void InspectorBackend::dispatchOnInjectedScript(long injectedScriptId, const String& methodName, const String& arguments, RefPtr<InspectorValue>* result, bool* hadException)
{
- if (!remoteFrontend())
+ if (!frontend())
return;
// FIXME: explicitly pass injectedScriptId along with node id to the frontend.
@@ -137,9 +137,9 @@ void InspectorBackend::executeSQL(long databaseId, const String& query, bool* su
#endif
-RemoteInspectorFrontend* InspectorBackend::remoteFrontend()
+InspectorFrontend* InspectorBackend::frontend()
{
- return m_inspectorController->m_remoteFrontend.get();
+ return m_inspectorController->m_frontend.get();
}
} // namespace WebCore
diff --git a/WebCore/inspector/InspectorBackend.h b/WebCore/inspector/InspectorBackend.h
index 27a93eb..23b31a3 100644
--- a/WebCore/inspector/InspectorBackend.h
+++ b/WebCore/inspector/InspectorBackend.h
@@ -40,7 +40,6 @@ namespace WebCore {
class InspectorApplicationCacheAgent;
class InspectorDOMAgent;
class InspectorFrontend;
-class RemoteInspectorFrontend;
class InspectorBackend : public RefCounted<InspectorBackend>
{
@@ -78,7 +77,7 @@ public:
private:
InspectorBackend(InspectorController* inspectorController);
- RemoteInspectorFrontend* remoteFrontend();
+ InspectorFrontend* frontend();
InspectorController* m_inspectorController;
};
diff --git a/WebCore/inspector/InspectorCSSStore.cpp b/WebCore/inspector/InspectorCSSStore.cpp
index 16d2508..c2dc4f1 100644
--- a/WebCore/inspector/InspectorCSSStore.cpp
+++ b/WebCore/inspector/InspectorCSSStore.cpp
@@ -41,7 +41,6 @@
#include "InspectorController.h"
#include "InspectorResource.h"
#include "PlatformString.h"
-#include "RemoteInspectorFrontend.h"
#include "StyleSheetList.h"
namespace WebCore {
diff --git a/WebCore/inspector/InspectorCSSStore.h b/WebCore/inspector/InspectorCSSStore.h
index ee435e5..82de622 100644
--- a/WebCore/inspector/InspectorCSSStore.h
+++ b/WebCore/inspector/InspectorCSSStore.h
@@ -38,7 +38,6 @@ namespace WebCore {
class Document;
class InspectorController;
-class InspectorFrontend;
class CSSMutableStyleDeclaration;
class CSSStyleDeclaration;
class CSSRuleList;
diff --git a/WebCore/inspector/InspectorController.cpp b/WebCore/inspector/InspectorController.cpp
index ac670cb..f47b321 100644
--- a/WebCore/inspector/InspectorController.cpp
+++ b/WebCore/inspector/InspectorController.cpp
@@ -59,10 +59,12 @@
#include "InspectorBackendDispatcher.h"
#include "InspectorCSSStore.h"
#include "InspectorClient.h"
+#include "InspectorFrontend.h"
#include "InspectorFrontendClient.h"
#include "InspectorDOMStorageResource.h"
#include "InspectorDatabaseResource.h"
#include "InspectorDebuggerAgent.h"
+#include "InspectorProfilerAgent.h"
#include "InspectorResource.h"
#include "InspectorStorageAgent.h"
#include "InspectorTimelineAgent.h"
@@ -71,7 +73,6 @@
#include "Page.h"
#include "ProgressTracker.h"
#include "Range.h"
-#include "RemoteInspectorFrontend.h"
#include "RenderInline.h"
#include "ResourceRequest.h"
#include "ResourceResponse.h"
@@ -115,8 +116,6 @@ using namespace std;
namespace WebCore {
-static const char* const UserInitiatedProfileName = "org.webkit.profiles.user-initiated";
-static const char* const CPUProfileType = "CPU";
static const char* const resourceTrackingEnabledSettingName = "resourceTrackingEnabled";
static const char* const debuggerEnabledSettingName = "debuggerEnabled";
static const char* const profilerEnabledSettingName = "profilerEnabled";
@@ -170,11 +169,7 @@ InspectorController::InspectorController(Page* page, InspectorClient* client)
, m_injectedScriptHost(InjectedScriptHost::create(this))
#if ENABLE(JAVASCRIPT_DEBUGGER)
, m_attachDebuggerWhenShown(false)
- , m_profilerEnabled(!WTF_USE_JSC)
- , m_recordingUserInitiatedProfile(false)
- , m_currentUserInitiatedProfileNumber(-1)
- , m_nextUserInitiatedProfileNumber(1)
- , m_startProfiling(this, &InspectorController::startUserInitiatedProfiling)
+ , m_profilerAgent(InspectorProfilerAgent::create(this))
#endif
{
ASSERT_ARG(page, page);
@@ -202,8 +197,8 @@ InspectorController::~InspectorController()
void InspectorController::inspectedPageDestroyed()
{
- if (m_remoteFrontend)
- m_remoteFrontend->inspectedPageDestroyed();
+ if (m_frontend)
+ m_frontend->inspectedPageDestroyed();
hideHighlight();
@@ -252,6 +247,13 @@ void InspectorController::saveSessionSettings(const String& settingsJSON)
m_sessionSettings = InspectorValue::parseJSON(settingsJSON);
}
+void InspectorController::getSettings(RefPtr<InspectorObject>* settings)
+{
+ *settings = InspectorObject::create();
+ (*settings)->setString("application", setting(frontendSettingsSettingName()));
+ (*settings)->setString("session", m_sessionSettings->toJSONString());
+}
+
void InspectorController::inspect(Node* node)
{
if (!enabled())
@@ -263,7 +265,7 @@ void InspectorController::inspect(Node* node)
node = node->parentNode();
m_nodeToFocus = node;
- if (!m_remoteFrontend) {
+ if (!m_frontend) {
m_showAfterVisible = ElementsPanel;
return;
}
@@ -276,11 +278,11 @@ void InspectorController::focusNode()
if (!enabled())
return;
- ASSERT(m_remoteFrontend);
+ ASSERT(m_frontend);
ASSERT(m_nodeToFocus);
long id = m_domAgent->pushNodePathToFrontend(m_nodeToFocus.get());
- m_remoteFrontend->updateFocusedNode(id);
+ m_frontend->updateFocusedNode(id);
m_nodeToFocus = 0;
}
@@ -308,11 +310,6 @@ void InspectorController::hideHighlight()
m_client->hideHighlight();
}
-bool InspectorController::windowVisible()
-{
- return m_remoteFrontend;
-}
-
void InspectorController::addMessageToConsole(MessageSource source, MessageType type, MessageLevel level, ScriptCallStack* callStack, const String& message)
{
if (!enabled())
@@ -337,16 +334,16 @@ void InspectorController::addConsoleMessage(ScriptState* scriptState, PassOwnPtr
if (m_previousMessage && m_previousMessage->isEqual(scriptState, consoleMessage.get())) {
m_previousMessage->incrementCount();
- if (m_remoteFrontend)
- m_previousMessage->updateRepeatCountInConsole(m_remoteFrontend.get());
+ if (m_frontend)
+ m_previousMessage->updateRepeatCountInConsole(m_frontend.get());
} else {
m_previousMessage = consoleMessage.get();
m_consoleMessages.append(consoleMessage);
- if (m_remoteFrontend)
- m_previousMessage->addToFrontend(m_remoteFrontend.get(), m_injectedScriptHost.get());
+ if (m_frontend)
+ m_previousMessage->addToFrontend(m_frontend.get(), m_injectedScriptHost.get());
}
- if (!m_remoteFrontend && m_consoleMessages.size() >= maximumConsoleMessages) {
+ if (!m_frontend && m_consoleMessages.size() >= maximumConsoleMessages) {
m_expiredConsoleMessageCount += expireConsoleMessagesStep;
m_consoleMessages.remove(0, expireConsoleMessagesStep);
}
@@ -361,8 +358,8 @@ void InspectorController::clearConsoleMessages()
m_injectedScriptHost->releaseWrapperObjectGroup(0 /* release the group in all scripts */, "console");
if (m_domAgent)
m_domAgent->releaseDanglingNodes();
- if (m_remoteFrontend)
- m_remoteFrontend->consoleMessagesCleared();
+ if (m_frontend)
+ m_frontend->consoleMessagesCleared();
}
void InspectorController::startGroup(MessageSource source, ScriptCallStack* callStack, bool collapsed)
@@ -433,7 +430,7 @@ void InspectorController::inspectedWindowScriptObjectCleared(Frame* frame)
m_inspectorFrontendClient->windowObjectCleared();
if (enabled()) {
- if (m_remoteFrontend && frame == m_inspectedPage->mainFrame())
+ if (m_frontend && frame == m_inspectedPage->mainFrame())
m_injectedScriptHost->discardInjectedScripts();
if (m_scriptsToEvaluateOnLoad.size()) {
ScriptState* scriptState = mainWorldScriptState(frame);
@@ -454,11 +451,11 @@ void InspectorController::setSearchingForNode(bool enabled)
m_searchingForNode = enabled;
if (!m_searchingForNode)
hideHighlight();
- if (m_remoteFrontend) {
+ if (m_frontend) {
if (enabled)
- m_remoteFrontend->searchingForNodeWasEnabled();
+ m_frontend->searchingForNodeWasEnabled();
else
- m_remoteFrontend->searchingForNodeWasDisabled();
+ m_frontend->searchingForNodeWasDisabled();
}
}
@@ -468,11 +465,11 @@ void InspectorController::setMonitoringXHR(bool enabled)
return;
m_monitoringXHR = enabled;
setSetting(monitoringXHRSettingName, enabled ? "true" : "false");
- if (m_remoteFrontend) {
+ if (m_frontend) {
if (enabled)
- m_remoteFrontend->monitoringXHRWasEnabled();
+ m_frontend->monitoringXHRWasEnabled();
else
- m_remoteFrontend->monitoringXHRWasDisabled();
+ m_frontend->monitoringXHRWasDisabled();
}
}
@@ -480,20 +477,18 @@ void InspectorController::connectFrontend()
{
m_openingFrontend = false;
releaseFrontendLifetimeAgents();
- m_remoteFrontend = new RemoteInspectorFrontend(m_client);
- m_domAgent = InspectorDOMAgent::create(m_cssStore.get(), m_remoteFrontend.get());
+ m_frontend = new InspectorFrontend(m_client);
+ m_domAgent = InspectorDOMAgent::create(m_cssStore.get(), m_frontend.get());
#if ENABLE(DATABASE)
- m_storageAgent = InspectorStorageAgent::create(m_remoteFrontend.get());
+ m_storageAgent = InspectorStorageAgent::create(m_frontend.get());
#endif
if (m_timelineAgent)
- m_timelineAgent->resetFrontendProxyObject(m_remoteFrontend.get());
+ m_timelineAgent->resetFrontendProxyObject(m_frontend.get());
// Initialize Web Inspector title.
- m_remoteFrontend->inspectedURLChanged(m_inspectedPage->mainFrame()->loader()->url().string());
-
- populateScriptObjects();
+ m_frontend->inspectedURLChanged(m_inspectedPage->mainFrame()->loader()->url().string());
#if ENABLE(JAVASCRIPT_DEBUGGER)
if (InspectorDebuggerAgent::isDebuggerAlwaysEnabled()) {
@@ -504,21 +499,17 @@ void InspectorController::connectFrontend()
String debuggerEnabled = setting(debuggerEnabledSettingName);
if (debuggerEnabled == "true" || m_attachDebuggerWhenShown)
enableDebugger();
- String profilerEnabled = setting(profilerEnabledSettingName);
- if (profilerEnabled == "true")
+ }
+ m_profilerAgent->setFrontend(m_frontend.get());
+ if (!ScriptProfiler::isProfilerAlwaysEnabled()) {
+ String profilerEnabledSetting = setting(profilerEnabledSettingName);
+ if (profilerEnabledSetting == "true")
enableProfiler();
}
#endif
- if (m_showAfterVisible == lastActivePanel)
- m_showAfterVisible = setting(lastActivePanel);
-
- if (m_nodeToFocus)
- focusNode();
- showPanel(m_showAfterVisible);
-
#if ENABLE(OFFLINE_WEB_APPLICATIONS)
- m_applicationCacheAgent = new InspectorApplicationCacheAgent(this, m_remoteFrontend.get());
+ m_applicationCacheAgent = new InspectorApplicationCacheAgent(this, m_frontend.get());
#endif
if (!connectedFrontendCount)
@@ -534,8 +525,8 @@ void InspectorController::show()
if (m_openingFrontend)
return;
- if (m_remoteFrontend)
- m_remoteFrontend->bringToFront();
+ if (m_frontend)
+ m_frontend->bringToFront();
else {
m_openingFrontend = true;
m_client->openInspectorFrontend(this);
@@ -549,7 +540,7 @@ void InspectorController::showPanel(const String& panel)
show();
- if (!m_remoteFrontend) {
+ if (!m_frontend) {
m_showAfterVisible = panel;
return;
}
@@ -557,21 +548,21 @@ void InspectorController::showPanel(const String& panel)
if (panel == lastActivePanel)
return;
- m_remoteFrontend->showPanel(panel);
+ m_frontend->showPanel(panel);
}
void InspectorController::close()
{
- if (!m_remoteFrontend)
+ if (!m_frontend)
return;
- m_remoteFrontend->close();
+ m_frontend->close();
}
void InspectorController::disconnectFrontend()
{
- if (!m_remoteFrontend)
+ if (!m_frontend)
return;
- m_remoteFrontend.clear();
+ m_frontend.clear();
connectedFrontendCount--;
if (!connectedFrontendCount)
@@ -594,7 +585,8 @@ void InspectorController::disconnectFrontend()
hideHighlight();
#if ENABLE(JAVASCRIPT_DEBUGGER)
- stopUserInitiatedProfiling();
+ m_profilerAgent->setFrontend(0);
+ m_profilerAgent->stopUserInitiatedProfiling();
#endif
releaseFrontendLifetimeAgents();
@@ -622,66 +614,67 @@ void InspectorController::releaseFrontendLifetimeAgents()
void InspectorController::populateScriptObjects()
{
- ASSERT(m_remoteFrontend);
- if (!m_remoteFrontend)
+ ASSERT(m_frontend);
+ if (!m_frontend)
return;
- m_remoteFrontend->populateApplicationSettings(setting(frontendSettingsSettingName()));
+ if (m_showAfterVisible == lastActivePanel)
+ m_showAfterVisible = setting(lastActivePanel);
+ if (m_nodeToFocus)
+ focusNode();
+ showPanel(m_showAfterVisible);
if (m_resourceTrackingEnabled)
- m_remoteFrontend->resourceTrackingWasEnabled();
+ m_frontend->resourceTrackingWasEnabled();
if (m_searchingForNode)
- m_remoteFrontend->searchingForNodeWasEnabled();
+ m_frontend->searchingForNodeWasEnabled();
if (m_monitoringXHR)
- m_remoteFrontend->monitoringXHRWasEnabled();
+ m_frontend->monitoringXHRWasEnabled();
#if ENABLE(JAVASCRIPT_DEBUGGER)
- if (m_profilerEnabled)
- m_remoteFrontend->profilerWasEnabled();
+ if (m_profilerAgent->enabled())
+ m_frontend->profilerWasEnabled();
#endif
ResourcesMap::iterator resourcesEnd = m_resources.end();
for (ResourcesMap::iterator it = m_resources.begin(); it != resourcesEnd; ++it)
- it->second->updateScriptObject(m_remoteFrontend.get());
+ it->second->updateScriptObject(m_frontend.get());
m_domAgent->setDocument(m_inspectedPage->mainFrame()->document());
if (m_expiredConsoleMessageCount)
- m_remoteFrontend->updateConsoleMessageExpiredCount(m_expiredConsoleMessageCount);
+ m_frontend->updateConsoleMessageExpiredCount(m_expiredConsoleMessageCount);
unsigned messageCount = m_consoleMessages.size();
for (unsigned i = 0; i < messageCount; ++i)
- m_consoleMessages[i]->addToFrontend(m_remoteFrontend.get(), m_injectedScriptHost.get());
+ m_consoleMessages[i]->addToFrontend(m_frontend.get(), m_injectedScriptHost.get());
#if ENABLE(JAVASCRIPT_DEBUGGER)
if (debuggerEnabled())
- m_remoteFrontend->updatePauseOnExceptionsState(ScriptDebugServer::shared().pauseOnExceptionsState());
+ m_frontend->updatePauseOnExceptionsState(ScriptDebugServer::shared().pauseOnExceptionsState());
#endif
#if ENABLE(DATABASE)
DatabaseResourcesMap::iterator databasesEnd = m_databaseResources.end();
for (DatabaseResourcesMap::iterator it = m_databaseResources.begin(); it != databasesEnd; ++it)
- it->second->bind(m_remoteFrontend.get());
+ it->second->bind(m_frontend.get());
#endif
#if ENABLE(DOM_STORAGE)
DOMStorageResourcesMap::iterator domStorageEnd = m_domStorageResources.end();
for (DOMStorageResourcesMap::iterator it = m_domStorageResources.begin(); it != domStorageEnd; ++it)
- it->second->bind(m_remoteFrontend.get());
+ it->second->bind(m_frontend.get());
#endif
#if ENABLE(WORKERS)
WorkersMap::iterator workersEnd = m_workers.end();
for (WorkersMap::iterator it = m_workers.begin(); it != workersEnd; ++it) {
InspectorWorkerResource* worker = it->second.get();
- m_remoteFrontend->didCreateWorker(worker->id(), worker->url(), worker->isSharedWorker());
+ m_frontend->didCreateWorker(worker->id(), worker->url(), worker->isSharedWorker());
}
#endif
- m_remoteFrontend->populateSessionSettings(m_sessionSettings->toJSONString());
- m_remoteFrontend->populateInterface();
-
// Dispatch pending frontend commands
for (Vector<pair<long, String> >::iterator it = m_pendingEvaluateTestCommands.begin(); it != m_pendingEvaluateTestCommands.end(); ++it)
- m_remoteFrontend->evaluateForTestInFrontend((*it).first, (*it).second);
+ m_frontend->evaluateForTestInFrontend((*it).first, (*it).second);
m_pendingEvaluateTestCommands.clear();
}
@@ -718,8 +711,8 @@ void InspectorController::pruneResources(ResourcesMap* resourceMap, DocumentLoad
if (!loaderToKeep || !resource->isSameLoader(loaderToKeep)) {
removeResource(resource);
- if (m_remoteFrontend)
- resource->releaseScriptObject(m_remoteFrontend.get());
+ if (m_frontend)
+ resource->releaseScriptObject(m_frontend.get());
}
}
}
@@ -732,8 +725,8 @@ void InspectorController::didCommitLoad(DocumentLoader* loader)
ASSERT(m_inspectedPage);
if (loader->frame() == m_inspectedPage->mainFrame()) {
- if (m_remoteFrontend)
- m_remoteFrontend->inspectedURLChanged(loader->url().string());
+ if (m_frontend)
+ m_frontend->inspectedURLChanged(loader->url().string());
m_injectedScriptHost->discardInjectedScripts();
clearConsoleMessages();
@@ -745,11 +738,7 @@ void InspectorController::didCommitLoad(DocumentLoader* loader)
m_debuggerAgent->clearForPageNavigation();
#endif
#if ENABLE(JAVASCRIPT_DEBUGGER) && USE(JSC)
- m_profiles.clear();
- m_currentUserInitiatedProfileNumber = 1;
- m_nextUserInitiatedProfileNumber = 1;
- if (m_remoteFrontend)
- m_remoteFrontend->resetProfilesPanel();
+ m_profilerAgent->resetState();
#endif
// unbindAllResources should be called before database and DOM storage
// resources are cleared so that it has a chance to unbind them.
@@ -757,8 +746,8 @@ void InspectorController::didCommitLoad(DocumentLoader* loader)
m_cssStore->reset();
m_sessionSettings = InspectorObject::create();
- if (m_remoteFrontend) {
- m_remoteFrontend->reset();
+ if (m_frontend) {
+ m_frontend->reset();
m_domAgent->reset();
}
#if ENABLE(WORKERS)
@@ -771,13 +760,13 @@ void InspectorController::didCommitLoad(DocumentLoader* loader)
m_domStorageResources.clear();
#endif
- if (m_remoteFrontend) {
+ if (m_frontend) {
if (!loader->frameLoader()->isLoadingFromCachedPage()) {
ASSERT(m_mainResource && m_mainResource->isSameLoader(loader));
// We don't add the main resource until its load is committed. This is
// needed to keep the load for a user-entered URL from showing up in the
// list of resources for the page they are navigating away from.
- m_mainResource->updateScriptObject(m_remoteFrontend.get());
+ m_mainResource->updateScriptObject(m_frontend.get());
} else {
// Pages loaded from the page cache are committed before
// m_mainResource is the right resource for this load, so we
@@ -785,7 +774,7 @@ void InspectorController::didCommitLoad(DocumentLoader* loader)
// identifierForInitialRequest.
m_mainResource = 0;
}
- m_remoteFrontend->didCommitLoad();
+ m_frontend->didCommitLoad();
m_domAgent->setDocument(m_inspectedPage->mainFrame()->document());
}
}
@@ -888,8 +877,8 @@ void InspectorController::didLoadResourceFromMemoryCache(DocumentLoader* loader,
addResource(resource.get());
- if (m_remoteFrontend)
- resource->updateScriptObject(m_remoteFrontend.get());
+ if (m_frontend)
+ resource->updateScriptObject(m_frontend.get());
}
void InspectorController::identifierForInitialRequest(unsigned long identifier, DocumentLoader* loader, const ResourceRequest& request)
@@ -912,8 +901,8 @@ void InspectorController::identifierForInitialRequest(unsigned long identifier,
addResource(resource.get());
- if (m_remoteFrontend && loader->frameLoader()->isLoadingFromCachedPage() && resource == m_mainResource)
- resource->updateScriptObject(m_remoteFrontend.get());
+ if (m_frontend && loader->frameLoader()->isLoadingFromCachedPage() && resource == m_mainResource)
+ resource->updateScriptObject(m_frontend.get());
}
void InspectorController::mainResourceFiredDOMContentEvent(DocumentLoader* loader, const KURL& url)
@@ -925,8 +914,8 @@ void InspectorController::mainResourceFiredDOMContentEvent(DocumentLoader* loade
m_mainResource->markDOMContentEventTime();
if (m_timelineAgent)
m_timelineAgent->didMarkDOMContentEvent();
- if (m_remoteFrontend)
- m_mainResource->updateScriptObject(m_remoteFrontend.get());
+ if (m_frontend)
+ m_mainResource->updateScriptObject(m_frontend.get());
}
}
@@ -939,8 +928,8 @@ void InspectorController::mainResourceFiredLoadEvent(DocumentLoader* loader, con
m_mainResource->markLoadEventTime();
if (m_timelineAgent)
m_timelineAgent->didMarkLoadEvent();
- if (m_remoteFrontend)
- m_mainResource->updateScriptObject(m_remoteFrontend.get());
+ if (m_frontend)
+ m_mainResource->updateScriptObject(m_frontend.get());
}
}
@@ -987,8 +976,8 @@ void InspectorController::willSendRequest(unsigned long identifier, ResourceRequ
resource->startTiming();
resource->updateRequest(request);
- if (resource != m_mainResource && m_remoteFrontend)
- resource->updateScriptObject(m_remoteFrontend.get());
+ if (resource != m_mainResource && m_frontend)
+ resource->updateScriptObject(m_frontend.get());
}
void InspectorController::didReceiveResponse(unsigned long identifier, const ResourceResponse& response)
@@ -999,8 +988,8 @@ void InspectorController::didReceiveResponse(unsigned long identifier, const Res
if (RefPtr<InspectorResource> resource = getTrackedResource(identifier)) {
resource->updateResponse(response);
- if (resource != m_mainResource && m_remoteFrontend)
- resource->updateScriptObject(m_remoteFrontend.get());
+ if (resource != m_mainResource && m_frontend)
+ resource->updateScriptObject(m_frontend.get());
}
if (response.httpStatusCode() >= 400) {
// The ugly code below is due to that String::format() is not utf8-safe at the moment.
@@ -1021,8 +1010,8 @@ void InspectorController::didReceiveContentLength(unsigned long identifier, int
resource->addLength(lengthReceived);
- if (resource != m_mainResource && m_remoteFrontend)
- resource->updateScriptObject(m_remoteFrontend.get());
+ if (resource != m_mainResource && m_frontend)
+ resource->updateScriptObject(m_frontend.get());
}
void InspectorController::didFinishLoading(unsigned long identifier)
@@ -1040,8 +1029,8 @@ void InspectorController::didFinishLoading(unsigned long identifier)
resource->endTiming();
// No need to mute this event for main resource since it happens after did commit load.
- if (m_remoteFrontend)
- resource->updateScriptObject(m_remoteFrontend.get());
+ if (m_frontend)
+ resource->updateScriptObject(m_frontend.get());
}
void InspectorController::didFailLoading(unsigned long identifier, const ResourceError& error)
@@ -1065,8 +1054,8 @@ void InspectorController::didFailLoading(unsigned long identifier, const Resourc
resource->endTiming();
// No need to mute this event for main resource since it happens after did commit load.
- if (m_remoteFrontend)
- resource->updateScriptObject(m_remoteFrontend.get());
+ if (m_frontend)
+ resource->updateScriptObject(m_frontend.get());
}
void InspectorController::resourceRetrievedByXMLHttpRequest(unsigned long identifier, const ScriptString& sourceString, const String& url, const String& sendURL, unsigned sendLineNumber)
@@ -1086,8 +1075,8 @@ void InspectorController::resourceRetrievedByXMLHttpRequest(unsigned long identi
resource->setOverrideContent(sourceString, InspectorResource::XHR);
- if (m_remoteFrontend)
- resource->updateScriptObject(m_remoteFrontend.get());
+ if (m_frontend)
+ resource->updateScriptObject(m_frontend.get());
}
void InspectorController::scriptImported(unsigned long identifier, const String& sourceString)
@@ -1101,8 +1090,8 @@ void InspectorController::scriptImported(unsigned long identifier, const String&
resource->setOverrideContent(ScriptString(sourceString), InspectorResource::Script);
- if (m_remoteFrontend)
- resource->updateScriptObject(m_remoteFrontend.get());
+ if (m_frontend)
+ resource->updateScriptObject(m_frontend.get());
}
void InspectorController::enableResourceTracking(bool always, bool reload)
@@ -1118,8 +1107,8 @@ void InspectorController::enableResourceTracking(bool always, bool reload)
ASSERT(m_inspectedPage);
m_resourceTrackingEnabled = true;
- if (m_remoteFrontend)
- m_remoteFrontend->resourceTrackingWasEnabled();
+ if (m_frontend)
+ m_frontend->resourceTrackingWasEnabled();
m_client->resourceTrackingWasEnabled();
if (reload)
@@ -1136,8 +1125,8 @@ void InspectorController::disableResourceTracking(bool always)
ASSERT(m_inspectedPage);
m_resourceTrackingEnabled = false;
- if (m_remoteFrontend)
- m_remoteFrontend->resourceTrackingWasDisabled();
+ if (m_frontend)
+ m_frontend->resourceTrackingWasDisabled();
m_client->resourceTrackingWasDisabled();
}
@@ -1165,9 +1154,9 @@ void InspectorController::startTimelineProfiler()
if (m_timelineAgent)
return;
- m_timelineAgent = new InspectorTimelineAgent(m_remoteFrontend.get());
- if (m_remoteFrontend)
- m_remoteFrontend->timelineProfilerWasStarted();
+ m_timelineAgent = new InspectorTimelineAgent(m_frontend.get());
+ if (m_frontend)
+ m_frontend->timelineProfilerWasStarted();
m_client->timelineProfilerWasStarted();
}
@@ -1180,8 +1169,8 @@ void InspectorController::stopTimelineProfiler()
return;
m_timelineAgent = 0;
- if (m_remoteFrontend)
- m_remoteFrontend->timelineProfilerWasStopped();
+ if (m_frontend)
+ m_frontend->timelineProfilerWasStopped();
m_client->timelineProfilerWasStopped();
}
@@ -1213,14 +1202,14 @@ private:
void InspectorController::postWorkerNotificationToFrontend(const InspectorWorkerResource& worker, InspectorController::WorkerAction action)
{
- if (!m_remoteFrontend)
+ if (!m_frontend)
return;
switch (action) {
case InspectorController::WorkerCreated:
- m_remoteFrontend->didCreateWorker(worker.id(), worker.url(), worker.isSharedWorker());
+ m_frontend->didCreateWorker(worker.id(), worker.url(), worker.isSharedWorker());
break;
case InspectorController::WorkerDestroyed:
- m_remoteFrontend->didDestroyWorker(worker.id());
+ m_frontend->didDestroyWorker(worker.id());
break;
}
}
@@ -1232,7 +1221,7 @@ void InspectorController::didCreateWorker(intptr_t id, const String& url, bool i
RefPtr<InspectorWorkerResource> workerResource(InspectorWorkerResource::create(id, url, isSharedWorker));
m_workers.set(id, workerResource);
- if (m_inspectedPage && m_remoteFrontend)
+ if (m_inspectedPage && m_frontend)
m_inspectedPage->mainFrame()->document()->postTask(PostWorkerNotificationToFrontendTask::create(workerResource, InspectorController::WorkerCreated));
}
@@ -1244,7 +1233,7 @@ void InspectorController::didDestroyWorker(intptr_t id)
WorkersMap::iterator workerResource = m_workers.find(id);
if (workerResource == m_workers.end())
return;
- if (m_inspectedPage && m_remoteFrontend)
+ if (m_inspectedPage && m_frontend)
m_inspectedPage->mainFrame()->document()->postTask(PostWorkerNotificationToFrontendTask::create(workerResource->second, InspectorController::WorkerDestroyed));
m_workers.remove(workerResource);
}
@@ -1253,12 +1242,12 @@ void InspectorController::didDestroyWorker(intptr_t id)
#if ENABLE(DATABASE)
void InspectorController::selectDatabase(Database* database)
{
- if (!m_remoteFrontend)
+ if (!m_frontend)
return;
for (DatabaseResourcesMap::iterator it = m_databaseResources.begin(); it != m_databaseResources.end(); ++it) {
if (it->second->database() == database) {
- m_remoteFrontend->selectDatabase(it->first);
+ m_frontend->selectDatabase(it->first);
break;
}
}
@@ -1282,8 +1271,8 @@ void InspectorController::didOpenDatabase(PassRefPtr<Database> database, const S
m_databaseResources.set(resource->id(), resource);
// Resources are only bound while visible.
- if (m_remoteFrontend)
- resource->bind(m_remoteFrontend.get());
+ if (m_frontend)
+ resource->bind(m_frontend.get());
}
#endif
@@ -1383,14 +1372,14 @@ void InspectorController::didUseDOMStorage(StorageArea* storageArea, bool isLoca
m_domStorageResources.set(resource->id(), resource);
// Resources are only bound while visible.
- if (m_remoteFrontend)
- resource->bind(m_remoteFrontend.get());
+ if (m_frontend)
+ resource->bind(m_frontend.get());
}
void InspectorController::selectDOMStorage(Storage* storage)
{
ASSERT(storage);
- if (!m_remoteFrontend)
+ if (!m_frontend)
return;
Frame* frame = storage->frame();
@@ -1405,7 +1394,7 @@ void InspectorController::selectDOMStorage(Storage* storage)
}
}
if (storageResourceId)
- m_remoteFrontend->selectDOMStorage(storageResourceId);
+ m_frontend->selectDOMStorage(storageResourceId);
}
void InspectorController::getDOMStorageEntries(long storageId, RefPtr<InspectorArray>* entries)
@@ -1458,176 +1447,61 @@ void InspectorController::addProfile(PassRefPtr<ScriptProfile> prpProfile, unsig
{
if (!enabled())
return;
-
- RefPtr<ScriptProfile> profile = prpProfile;
- m_profiles.add(profile->uid(), profile);
-
- if (m_remoteFrontend) {
- m_remoteFrontend->addProfileHeader(createProfileHeader(*profile));
- }
-
- addProfileFinishedMessageToConsole(profile, lineNumber, sourceURL);
+ m_profilerAgent->addProfile(prpProfile, lineNumber, sourceURL);
}
void InspectorController::addProfileFinishedMessageToConsole(PassRefPtr<ScriptProfile> prpProfile, unsigned lineNumber, const String& sourceURL)
{
- RefPtr<ScriptProfile> profile = prpProfile;
-
- String title = profile->title();
- String message = String::format("Profile \"webkit-profile://%s/%s#%d\" finished.", CPUProfileType, encodeWithURLEscapeSequences(title).utf8().data(), profile->uid());
- addMessageToConsole(JSMessageSource, LogMessageType, LogMessageLevel, message, lineNumber, sourceURL);
+ m_profilerAgent->addProfileFinishedMessageToConsole(prpProfile, lineNumber, sourceURL);
}
void InspectorController::addStartProfilingMessageToConsole(const String& title, unsigned lineNumber, const String& sourceURL)
{
- String message = String::format("Profile \"webkit-profile://%s/%s#0\" started.", CPUProfileType, encodeWithURLEscapeSequences(title).utf8().data());
- addMessageToConsole(JSMessageSource, LogMessageType, LogMessageLevel, message, lineNumber, sourceURL);
-}
-
-void InspectorController::removeProfile(unsigned uid)
-{
- if (!enabled())
- return;
-
- if (m_profiles.contains(uid))
- m_profiles.remove(uid);
-}
-
-void InspectorController::clearProfiles()
-{
- if (!enabled())
- return;
-
- m_profiles.clear();
- m_currentUserInitiatedProfileNumber = 1;
- m_nextUserInitiatedProfileNumber = 1;
-}
-
-void InspectorController::getProfileHeaders(RefPtr<InspectorArray>* headers)
-{
- ProfilesMap::iterator profilesEnd = m_profiles.end();
- for (ProfilesMap::iterator it = m_profiles.begin(); it != profilesEnd; ++it)
- (*headers)->pushObject(createProfileHeader(*it->second));
+ m_profilerAgent->addStartProfilingMessageToConsole(title, lineNumber, sourceURL);
}
-void InspectorController::getProfile(unsigned uid, RefPtr<InspectorObject>* profileObject)
-{
- ProfilesMap::iterator it = m_profiles.find(uid);
- if (it != m_profiles.end()) {
- *profileObject = createProfileHeader(*it->second);
- (*profileObject)->setObject("head", it->second->buildInspectorObjectForHead());
- }
-}
-PassRefPtr<InspectorObject> InspectorController::createProfileHeader(const ScriptProfile& profile)
+bool InspectorController::isRecordingUserInitiatedProfile() const
{
- RefPtr<InspectorObject> header = InspectorObject::create();
- header->setString("title", profile.title());
- header->setNumber("uid", profile.uid());
- header->setString("typeId", String(CPUProfileType));
- return header;
+ return m_profilerAgent->isRecordingUserInitiatedProfile();
}
-String InspectorController::getCurrentUserInitiatedProfileName(bool incrementProfileNumber = false)
+String InspectorController::getCurrentUserInitiatedProfileName(bool incrementProfileNumber)
{
- if (incrementProfileNumber)
- m_currentUserInitiatedProfileNumber = m_nextUserInitiatedProfileNumber++;
-
- return String::format("%s.%d", UserInitiatedProfileName, m_currentUserInitiatedProfileNumber);
+ return m_profilerAgent->getCurrentUserInitiatedProfileName(incrementProfileNumber);
}
-void InspectorController::startUserInitiatedProfilingSoon()
-{
- m_startProfiling.startOneShot(0);
-}
-
-void InspectorController::startUserInitiatedProfiling(Timer<InspectorController>*)
+void InspectorController::startUserInitiatedProfiling()
{
if (!enabled())
return;
-
- if (!profilerEnabled()) {
- enableProfiler(false, true);
- ScriptDebugServer::shared().recompileAllJSFunctions();
- }
-
- m_recordingUserInitiatedProfile = true;
-
- String title = getCurrentUserInitiatedProfileName(true);
-
-#if USE(JSC)
- JSC::ExecState* scriptState = toJSDOMWindow(m_inspectedPage->mainFrame(), debuggerWorld())->globalExec();
-#else
- ScriptState* scriptState = 0;
-#endif
- ScriptProfiler::start(scriptState, title);
-
- addStartProfilingMessageToConsole(title, 0, String());
-
- toggleRecordButton(true);
+ m_profilerAgent->startUserInitiatedProfiling();
}
void InspectorController::stopUserInitiatedProfiling()
{
if (!enabled())
return;
-
- m_recordingUserInitiatedProfile = false;
-
- String title = getCurrentUserInitiatedProfileName();
-
-#if USE(JSC)
- JSC::ExecState* scriptState = toJSDOMWindow(m_inspectedPage->mainFrame(), debuggerWorld())->globalExec();
-#else
- // Use null script state to avoid filtering by context security token.
- // All functions from all iframes should be visible from Inspector UI.
- ScriptState* scriptState = 0;
-#endif
- RefPtr<ScriptProfile> profile = ScriptProfiler::stop(scriptState, title);
- if (profile)
- addProfile(profile, 0, String());
-
- toggleRecordButton(false);
+ m_profilerAgent->stopUserInitiatedProfiling();
}
-void InspectorController::toggleRecordButton(bool isProfiling)
+bool InspectorController::profilerEnabled() const
{
- if (!m_remoteFrontend)
- return;
- m_remoteFrontend->setRecordingProfile(isProfiling);
+ return enabled() && m_profilerAgent->enabled();
}
void InspectorController::enableProfiler(bool always, bool skipRecompile)
{
if (always)
setSetting(profilerEnabledSettingName, "true");
-
- if (m_profilerEnabled)
- return;
-
- m_profilerEnabled = true;
-
- if (!skipRecompile)
- ScriptDebugServer::shared().recompileAllJSFunctionsSoon();
-
- if (m_remoteFrontend)
- m_remoteFrontend->profilerWasEnabled();
+ m_profilerAgent->enable(skipRecompile);
}
void InspectorController::disableProfiler(bool always)
{
if (always)
setSetting(profilerEnabledSettingName, "false");
-
- if (!m_profilerEnabled)
- return;
-
- m_profilerEnabled = false;
-
- ScriptDebugServer::shared().recompileAllJSFunctionsSoon();
-
- if (m_remoteFrontend)
- m_remoteFrontend->profilerWasDisabled();
+ m_profilerAgent->disable();
}
#endif
@@ -1640,9 +1514,9 @@ void InspectorController::enableDebuggerFromFrontend(bool always)
ASSERT(m_inspectedPage);
- m_debuggerAgent = InspectorDebuggerAgent::create(this, m_remoteFrontend.get());
+ m_debuggerAgent = InspectorDebuggerAgent::create(this, m_frontend.get());
- m_remoteFrontend->debuggerWasEnabled();
+ m_frontend->debuggerWasEnabled();
}
void InspectorController::enableDebugger()
@@ -1653,10 +1527,10 @@ void InspectorController::enableDebugger()
if (debuggerEnabled())
return;
- if (!m_remoteFrontend)
+ if (!m_frontend)
m_attachDebuggerWhenShown = true;
else {
- m_remoteFrontend->attachDebuggerWhenShown();
+ m_frontend->attachDebuggerWhenShown();
m_attachDebuggerWhenShown = false;
}
}
@@ -1675,8 +1549,8 @@ void InspectorController::disableDebugger(bool always)
m_attachDebuggerWhenShown = false;
- if (m_remoteFrontend)
- m_remoteFrontend->debuggerWasDisabled();
+ if (m_frontend)
+ m_frontend->debuggerWasDisabled();
}
void InspectorController::resume()
@@ -1690,8 +1564,8 @@ void InspectorController::resume()
void InspectorController::evaluateForTestInFrontend(long callId, const String& script)
{
- if (m_remoteFrontend)
- m_remoteFrontend->evaluateForTestInFrontend(callId, script);
+ if (m_frontend)
+ m_frontend->evaluateForTestInFrontend(callId, script);
else
m_pendingEvaluateTestCommands.append(pair<long, String>(callId, script));
}
diff --git a/WebCore/inspector/InspectorController.h b/WebCore/inspector/InspectorController.h
index 8d96005..7ed2549 100644
--- a/WebCore/inspector/InspectorController.h
+++ b/WebCore/inspector/InspectorController.h
@@ -33,9 +33,7 @@
#include "Cookie.h"
#include "InspectorDOMAgent.h"
#include "PlatformString.h"
-#include "ScriptProfile.h"
#include "ScriptState.h"
-#include "Timer.h"
#include <wtf/HashMap.h>
#include <wtf/HashSet.h>
#include <wtf/ListHashSet.h>
@@ -63,8 +61,10 @@ class InspectorCSSStore;
class InspectorDOMStorageResource;
class InspectorDatabaseResource;
class InspectorDebuggerAgent;
+class InspectorFrontend;
class InspectorFrontendClient;
class InspectorObject;
+class InspectorProfilerAgent;
class InspectorResource;
class InspectorStorageAgent;
class InspectorTimelineAgent;
@@ -73,11 +73,11 @@ class InspectorWorkerResource;
class KURL;
class Node;
class Page;
-class RemoteInspectorFrontend;
class ResourceRequest;
class ResourceResponse;
class ResourceError;
class ScriptCallStack;
+class ScriptProfile;
class ScriptString;
class SharedBuffer;
class Storage;
@@ -118,7 +118,7 @@ public:
void setSetting(const String& key, const String& value);
void saveApplicationSettings(const String& settings);
void saveSessionSettings(const String&);
-
+ void getSettings(RefPtr<InspectorObject>*);
void inspect(Node*);
void highlight(Node*);
@@ -150,8 +150,6 @@ public:
void inspectedWindowScriptObjectCleared(Frame*);
- bool windowVisible();
-
void didCommitLoad(DocumentLoader*);
void frameDetachedFromParent(Frame*);
void didLoadResourceFromMemoryCache(DocumentLoader*, const CachedResource*);
@@ -209,7 +207,7 @@ public:
const ResourcesMap& resources() const { return m_resources; }
InspectorResource* resourceForURL(const String& url);
- bool hasFrontend() const { return m_remoteFrontend; }
+ bool hasFrontend() const { return m_frontend; }
void drawNodeHighlight(GraphicsContext&) const;
void openInInspectedWindow(const String& url);
@@ -228,20 +226,14 @@ public:
void addProfile(PassRefPtr<ScriptProfile>, unsigned lineNumber, const String& sourceURL);
void addProfileFinishedMessageToConsole(PassRefPtr<ScriptProfile>, unsigned lineNumber, const String& sourceURL);
void addStartProfilingMessageToConsole(const String& title, unsigned lineNumber, const String& sourceURL);
- void removeProfile(unsigned);
- void clearProfiles();
-
- bool isRecordingUserInitiatedProfile() const { return m_recordingUserInitiatedProfile; }
-
- String getCurrentUserInitiatedProfileName(bool incrementProfileNumber);
- void startUserInitiatedProfiling(Timer<InspectorController>* = 0);
+ bool isRecordingUserInitiatedProfile() const;
+ String getCurrentUserInitiatedProfileName(bool incrementProfileNumber = false);
+ void startUserInitiatedProfiling();
void stopUserInitiatedProfiling();
- void startProfiling() { startUserInitiatedProfiling(); }
- void stopProfiling() { stopUserInitiatedProfiling(); }
-
void enableProfiler(bool always = false, bool skipRecompile = false);
void disableProfiler(bool always = false);
- bool profilerEnabled() const { return enabled() && m_profilerEnabled; }
+ bool profilerEnabled() const;
+ InspectorProfilerAgent* profilerAgent() const { return m_profilerAgent.get(); }
void enableDebugger();
void disableDebugger(bool always = false);
@@ -283,14 +275,9 @@ private:
void releaseFrontendLifetimeAgents();
#if ENABLE(JAVASCRIPT_DEBUGGER)
- typedef HashMap<unsigned int, RefPtr<ScriptProfile> > ProfilesMap;
- void startUserInitiatedProfilingSoon();
void toggleRecordButton(bool);
void enableDebuggerFromFrontend(bool always);
- void getProfileHeaders(RefPtr<InspectorArray>* headers);
- void getProfile(unsigned uid, RefPtr<InspectorObject>* profileObject);
- PassRefPtr<InspectorObject> createProfileHeader(const ScriptProfile& profile);
#endif
#if ENABLE(DATABASE)
void selectDatabase(Database* database);
@@ -330,7 +317,7 @@ private:
InspectorClient* m_client;
OwnPtr<InspectorFrontendClient> m_inspectorFrontendClient;
bool m_openingFrontend;
- OwnPtr<RemoteInspectorFrontend> m_remoteFrontend;
+ OwnPtr<InspectorFrontend> m_frontend;
RefPtr<InspectorDOMAgent> m_domAgent;
RefPtr<InspectorStorageAgent> m_storageAgent;
OwnPtr<InspectorCSSStore> m_cssStore;
@@ -380,12 +367,7 @@ private:
bool m_attachDebuggerWhenShown;
OwnPtr<InspectorDebuggerAgent> m_debuggerAgent;
- bool m_profilerEnabled;
- bool m_recordingUserInitiatedProfile;
- int m_currentUserInitiatedProfileNumber;
- unsigned m_nextUserInitiatedProfileNumber;
- Timer<InspectorController> m_startProfiling;
- ProfilesMap m_profiles;
+ OwnPtr<InspectorProfilerAgent> m_profilerAgent;
#endif
#if ENABLE(WORKERS)
typedef HashMap<intptr_t, RefPtr<InspectorWorkerResource> > WorkersMap;
diff --git a/WebCore/inspector/InspectorDOMAgent.cpp b/WebCore/inspector/InspectorDOMAgent.cpp
index 6243299..b8ae047 100644
--- a/WebCore/inspector/InspectorDOMAgent.cpp
+++ b/WebCore/inspector/InspectorDOMAgent.cpp
@@ -35,6 +35,7 @@
#include "CSSComputedStyleDeclaration.h"
#include "CSSMutableStyleDeclaration.h"
+#include "CSSPropertyNames.h"
#include "CSSRule.h"
#include "CSSRuleList.h"
#include "CSSStyleRule.h"
@@ -54,14 +55,15 @@
#include "FrameTree.h"
#include "HTMLElement.h"
#include "HTMLFrameOwnerElement.h"
+#include "InspectorFrontend.h"
#include "MutationEvent.h"
#include "Node.h"
#include "NodeList.h"
#include "Pasteboard.h"
#include "PlatformString.h"
-#include "RemoteInspectorFrontend.h"
#include "RenderStyle.h"
#include "RenderStyleConstants.h"
+#include "ScriptDebugServer.h"
#include "ScriptEventListener.h"
#include "StyleSheetList.h"
#include "Text.h"
@@ -196,9 +198,20 @@ public:
virtual ~MatchPlainTextJob() { }
};
+enum DOMBreakpointType {
+ SubtreeModified = 0,
+ AttributeModified,
+ NodeRemoved
+};
+
+const uint32_t inheritableDOMBreakpointTypesMask = (1 << SubtreeModified);
+const int domBreakpointDerivedTypeShift = 16;
+
}
-InspectorDOMAgent::InspectorDOMAgent(InspectorCSSStore* cssStore, RemoteInspectorFrontend* frontend)
+InspectorDOMAgent* InspectorDOMAgent::s_domAgentOnBreakpoint = 0;
+
+InspectorDOMAgent::InspectorDOMAgent(InspectorCSSStore* cssStore, InspectorFrontend* frontend)
: EventListener(InspectorDOMAgentType)
, m_cssStore(cssStore)
, m_frontend(frontend)
@@ -210,6 +223,9 @@ InspectorDOMAgent::InspectorDOMAgent(InspectorCSSStore* cssStore, RemoteInspecto
InspectorDOMAgent::~InspectorDOMAgent()
{
reset();
+
+ if (this == s_domAgentOnBreakpoint)
+ s_domAgentOnBreakpoint = 0;
}
void InspectorDOMAgent::reset()
@@ -371,6 +387,7 @@ void InspectorDOMAgent::discardBindings()
releaseDanglingNodes();
m_childrenRequested.clear();
m_inspectedNodes.clear();
+ m_breakpoints.clear();
}
Node* InspectorDOMAgent::nodeForId(long id)
@@ -720,6 +737,39 @@ void InspectorDOMAgent::searchCanceled()
m_searchResults.clear();
}
+void InspectorDOMAgent::setDOMBreakpoint(long nodeId, long type)
+{
+ Node* node = nodeForId(nodeId);
+ if (!node)
+ return;
+
+ uint32_t rootBit = 1 << type;
+ m_breakpoints.set(node, m_breakpoints.get(node) | rootBit);
+ if (rootBit & inheritableDOMBreakpointTypesMask) {
+ for (Node* child = innerFirstChild(node); child; child = innerNextSibling(child))
+ updateSubtreeBreakpoints(child, rootBit, true);
+ }
+}
+
+void InspectorDOMAgent::removeDOMBreakpoint(long nodeId, long type)
+{
+ Node* node = nodeForId(nodeId);
+ if (!node)
+ return;
+
+ uint32_t rootBit = 1 << type;
+ uint32_t mask = m_breakpoints.get(node) & ~rootBit;
+ if (mask)
+ m_breakpoints.set(node, mask);
+ else
+ m_breakpoints.remove(node);
+
+ if ((rootBit & inheritableDOMBreakpointTypesMask) && !(mask & (rootBit << domBreakpointDerivedTypeShift))) {
+ for (Node* child = innerFirstChild(node); child; child = innerNextSibling(child))
+ updateSubtreeBreakpoints(child, rootBit, false);
+ }
+}
+
String InspectorDOMAgent::documentURLString(Document* document) const
{
if (!document || document->url().isNull())
@@ -920,6 +970,18 @@ void InspectorDOMAgent::didInsertDOMNode(Node* node)
if (isWhitespace(node))
return;
+ if (m_breakpoints.size()) {
+ Node* parent = innerParentNode(node);
+ if (hasBreakpoint(parent, SubtreeModified)) {
+ if (!pauseOnBreakpoint())
+ return;
+ }
+ uint32_t mask = m_breakpoints.get(parent);
+ uint32_t inheritableTypesMask = (mask | (mask >> domBreakpointDerivedTypeShift)) & inheritableDOMBreakpointTypesMask;
+ if (inheritableTypesMask)
+ updateSubtreeBreakpoints(node, inheritableTypesMask, true);
+ }
+
// We could be attaching existing subtree. Forget the bindings.
unbind(node, &m_documentNodeToIdMap);
@@ -946,6 +1008,25 @@ void InspectorDOMAgent::didRemoveDOMNode(Node* node)
if (isWhitespace(node))
return;
+ if (m_breakpoints.size()) {
+ if (hasBreakpoint(node, NodeRemoved) || hasBreakpoint(innerParentNode(node), SubtreeModified)) {
+ if (!pauseOnBreakpoint())
+ return;
+ }
+ // Remove subtree breakpoints.
+ m_breakpoints.remove(node);
+ Vector<Node*> stack(1, innerFirstChild(node));
+ do {
+ Node* node = stack.last();
+ stack.removeLast();
+ if (!node)
+ continue;
+ m_breakpoints.remove(node);
+ stack.append(innerFirstChild(node));
+ stack.append(innerNextSibling(node));
+ } while (!stack.isEmpty());
+ }
+
Node* parent = node->parentNode();
long parentId = m_documentNodeToIdMap.get(parent);
// If parent is not mapped yet -> ignore the event.
@@ -968,9 +1049,52 @@ void InspectorDOMAgent::didModifyDOMAttr(Element* element)
if (!id)
return;
+ if (hasBreakpoint(element, AttributeModified)) {
+ if (!pauseOnBreakpoint())
+ return;
+ }
+
m_frontend->attributesUpdated(id, buildArrayForElementAttributes(element));
}
+bool InspectorDOMAgent::hasBreakpoint(Node* node, long type)
+{
+ uint32_t rootBit = 1 << type;
+ uint32_t derivedBit = rootBit << domBreakpointDerivedTypeShift;
+ return m_breakpoints.get(node) & (rootBit | derivedBit);
+}
+
+bool InspectorDOMAgent::pauseOnBreakpoint()
+{
+#if ENABLE(JAVASCRIPT_DEBUGGER)
+ s_domAgentOnBreakpoint = this;
+ ScriptDebugServer::shared().breakProgram();
+ bool deleted = !s_domAgentOnBreakpoint;
+ s_domAgentOnBreakpoint = 0;
+ return !deleted;
+#else
+ return true;
+#endif
+}
+
+void InspectorDOMAgent::updateSubtreeBreakpoints(Node* node, uint32_t rootMask, bool set)
+{
+ uint32_t oldMask = m_breakpoints.get(node);
+ uint32_t derivedMask = rootMask << domBreakpointDerivedTypeShift;
+ uint32_t newMask = set ? oldMask | derivedMask : oldMask & ~derivedMask;
+ if (newMask)
+ m_breakpoints.set(node, newMask);
+ else
+ m_breakpoints.remove(node);
+
+ uint32_t newRootMask = rootMask & ~newMask;
+ if (!newRootMask)
+ return;
+
+ for (Node* child = innerFirstChild(node); child; child = innerNextSibling(child))
+ updateSubtreeBreakpoints(child, newRootMask, set);
+}
+
void InspectorDOMAgent::getStyles(long nodeId, bool authorOnly, RefPtr<InspectorValue>* styles)
{
Node* node = nodeForId(nodeId);
@@ -1297,6 +1421,14 @@ void InspectorDOMAgent::addRule(const String& selector, long selectedNodeId, Ref
*ruleObject = buildObjectForRule(node->ownerDocument(), newRule);
}
+void InspectorDOMAgent::getSupportedCSSProperties(RefPtr<InspectorArray>* cssProperties)
+{
+ RefPtr<InspectorArray> properties = InspectorArray::create();
+ for (int i = 0; i < numCSSProperties; ++i)
+ properties->pushString(propertyNameStrings[i]);
+ *cssProperties = properties.release();
+}
+
PassRefPtr<InspectorObject> InspectorDOMAgent::buildObjectForStyle(CSSStyleDeclaration* style, bool bind)
{
RefPtr<InspectorObject> result = InspectorObject::create();
diff --git a/WebCore/inspector/InspectorDOMAgent.h b/WebCore/inspector/InspectorDOMAgent.h
index 5317a22..fd3c5b5 100644
--- a/WebCore/inspector/InspectorDOMAgent.h
+++ b/WebCore/inspector/InspectorDOMAgent.h
@@ -57,7 +57,7 @@ namespace WebCore {
class Element;
class Event;
class InspectorDOMAgent;
- class RemoteInspectorFrontend;
+ class InspectorFrontend;
class MatchJob;
class NameNodeMap;
class Node;
@@ -80,7 +80,7 @@ namespace WebCore {
class InspectorDOMAgent : public EventListener {
public:
- static PassRefPtr<InspectorDOMAgent> create(InspectorCSSStore* cssStore, RemoteInspectorFrontend* frontend)
+ static PassRefPtr<InspectorDOMAgent> create(InspectorCSSStore* cssStore, InspectorFrontend* frontend)
{
return adoptRef(new InspectorDOMAgent(cssStore, frontend));
}
@@ -92,7 +92,7 @@ namespace WebCore {
: 0;
}
- InspectorDOMAgent(InspectorCSSStore* cssStore, RemoteInspectorFrontend* frontend);
+ InspectorDOMAgent(InspectorCSSStore* cssStore, InspectorFrontend* frontend);
~InspectorDOMAgent();
void reset();
@@ -112,6 +112,8 @@ namespace WebCore {
void addInspectedNode(long nodeId);
void performSearch(const String& whitespaceTrimmedQuery, bool runSynchronously);
void searchCanceled();
+ void setDOMBreakpoint(long nodeId, long type);
+ void removeDOMBreakpoint(long nodeId, long type);
// Methods called from the frontend for CSS styles inspection.
void getStyles(long nodeId, bool authorOnly, RefPtr<InspectorValue>* styles);
@@ -126,6 +128,7 @@ namespace WebCore {
void toggleStyleEnabled(long styleId, const String& propertyName, bool disabled, RefPtr<InspectorValue>* styleObject);
void setRuleSelector(long ruleId, const String& selector, long selectedNodeId, RefPtr<InspectorValue>* ruleObject, bool* selectorAffectsNode);
void addRule(const String& selector, long selectedNodeId, RefPtr<InspectorValue>* ruleObject, bool* selectorAffectsNode);
+ void getSupportedCSSProperties(RefPtr<InspectorArray>* cssProperties);
// Methods called from the InspectorController.
void setDocument(Document* document);
@@ -156,6 +159,10 @@ namespace WebCore {
bool pushDocumentToFrontend();
+ bool hasBreakpoint(Node* node, long type);
+ bool pauseOnBreakpoint();
+ void updateSubtreeBreakpoints(Node* root, uint32_t rootMask, bool value);
+
PassRefPtr<InspectorObject> buildObjectForAttributeStyles(Element* element);
PassRefPtr<InspectorArray> buildArrayForCSSRules(Document* ownerDocument, CSSRuleList*);
PassRefPtr<InspectorArray> buildArrayForPseudoElements(Element* element, bool authorOnly);
@@ -196,7 +203,7 @@ namespace WebCore {
void discardBindings();
InspectorCSSStore* m_cssStore;
- RemoteInspectorFrontend* m_frontend;
+ InspectorFrontend* m_frontend;
NodeToIdMap m_documentNodeToIdMap;
// Owns node mappings for dangling nodes.
Vector<NodeToIdMap*> m_danglingNodeToIdMaps;
@@ -209,6 +216,9 @@ namespace WebCore {
Timer<InspectorDOMAgent> m_matchJobsTimer;
HashSet<RefPtr<Node> > m_searchResults;
Vector<long> m_inspectedNodes;
+ HashMap<Node*, uint32_t> m_breakpoints;
+
+ static InspectorDOMAgent* s_domAgentOnBreakpoint;
};
#endif
diff --git a/WebCore/inspector/InspectorDOMStorageResource.cpp b/WebCore/inspector/InspectorDOMStorageResource.cpp
index 61095a0..72b4e10 100644
--- a/WebCore/inspector/InspectorDOMStorageResource.cpp
+++ b/WebCore/inspector/InspectorDOMStorageResource.cpp
@@ -37,8 +37,8 @@
#include "DOMWindow.h"
#include "EventNames.h"
#include "Frame.h"
+#include "InspectorFrontend.h"
#include "InspectorValues.h"
-#include "RemoteInspectorFrontend.h"
#include "Storage.h"
#include "StorageEvent.h"
@@ -64,7 +64,7 @@ bool InspectorDOMStorageResource::isSameHostAndType(Frame* frame, bool isLocalSt
return equalIgnoringCase(m_frame->document()->securityOrigin()->host(), frame->document()->securityOrigin()->host()) && m_isLocalStorage == isLocalStorage;
}
-void InspectorDOMStorageResource::bind(RemoteInspectorFrontend* frontend)
+void InspectorDOMStorageResource::bind(InspectorFrontend* frontend)
{
ASSERT(!m_frontend);
m_frontend = frontend;
diff --git a/WebCore/inspector/InspectorDOMStorageResource.h b/WebCore/inspector/InspectorDOMStorageResource.h
index a47e74c..ee09974 100644
--- a/WebCore/inspector/InspectorDOMStorageResource.h
+++ b/WebCore/inspector/InspectorDOMStorageResource.h
@@ -43,7 +43,7 @@ namespace WebCore {
class Storage;
class Frame;
- class RemoteInspectorFrontend;
+ class InspectorFrontend;
class InspectorDOMStorageResource : public EventListener {
public:
@@ -56,7 +56,7 @@ namespace WebCore {
return listener->type() == InspectorDOMStorageResourceType ? static_cast<const InspectorDOMStorageResource*>(listener) : 0;
}
- void bind(RemoteInspectorFrontend* frontend);
+ void bind(InspectorFrontend* frontend);
void unbind();
void startReportingChangesToFrontend();
@@ -74,7 +74,7 @@ namespace WebCore {
RefPtr<Storage> m_domStorage;
bool m_isLocalStorage;
RefPtr<Frame> m_frame;
- RemoteInspectorFrontend* m_frontend;
+ InspectorFrontend* m_frontend;
int m_id;
bool m_reportingChangesToFrontend;
diff --git a/WebCore/inspector/InspectorDatabaseResource.cpp b/WebCore/inspector/InspectorDatabaseResource.cpp
index 036148f..ba67818 100644
--- a/WebCore/inspector/InspectorDatabaseResource.cpp
+++ b/WebCore/inspector/InspectorDatabaseResource.cpp
@@ -33,8 +33,8 @@
#if ENABLE(DATABASE) && ENABLE(INSPECTOR)
#include "Database.h"
+#include "InspectorFrontend.h"
#include "InspectorValues.h"
-#include "RemoteInspectorFrontend.h"
namespace WebCore {
@@ -55,7 +55,7 @@ InspectorDatabaseResource::InspectorDatabaseResource(PassRefPtr<Database> databa
{
}
-void InspectorDatabaseResource::bind(RemoteInspectorFrontend* frontend)
+void InspectorDatabaseResource::bind(InspectorFrontend* frontend)
{
if (m_scriptObjectCreated)
return;
diff --git a/WebCore/inspector/InspectorDatabaseResource.h b/WebCore/inspector/InspectorDatabaseResource.h
index 8e0e1b3..203995b 100644
--- a/WebCore/inspector/InspectorDatabaseResource.h
+++ b/WebCore/inspector/InspectorDatabaseResource.h
@@ -39,13 +39,13 @@
namespace WebCore {
class Database;
-class RemoteInspectorFrontend;
+class InspectorFrontend;
class InspectorDatabaseResource : public RefCounted<InspectorDatabaseResource> {
public:
static PassRefPtr<InspectorDatabaseResource> create(PassRefPtr<Database> database, const String& domain, const String& name, const String& version);
- void bind(RemoteInspectorFrontend* frontend);
+ void bind(InspectorFrontend* frontend);
void unbind();
Database* database() { return m_database.get(); }
long id() const { return m_id; }
diff --git a/WebCore/inspector/InspectorDebuggerAgent.cpp b/WebCore/inspector/InspectorDebuggerAgent.cpp
index e1c0dc0..357a043 100644
--- a/WebCore/inspector/InspectorDebuggerAgent.cpp
+++ b/WebCore/inspector/InspectorDebuggerAgent.cpp
@@ -33,9 +33,9 @@
#if ENABLE(JAVASCRIPT_DEBUGGER)
#include "InjectedScript.h"
#include "InjectedScriptHost.h"
+#include "InspectorFrontend.h"
#include "InspectorValues.h"
#include "PlatformString.h"
-#include "RemoteInspectorFrontend.h"
#include "ScriptDebugServer.h"
#include <wtf/MD5.h>
@@ -46,17 +46,19 @@ static String formatBreakpointId(const String& sourceID, unsigned lineNumber)
return String::format("%s:%d", sourceID.utf8().data(), lineNumber);
}
-PassOwnPtr<InspectorDebuggerAgent> InspectorDebuggerAgent::create(InspectorController* inspectorController, RemoteInspectorFrontend* remoteFrontend)
+PassOwnPtr<InspectorDebuggerAgent> InspectorDebuggerAgent::create(InspectorController* inspectorController, InspectorFrontend* frontend)
{
- OwnPtr<InspectorDebuggerAgent> agent = adoptPtr(new InspectorDebuggerAgent(inspectorController, remoteFrontend));
+ OwnPtr<InspectorDebuggerAgent> agent = adoptPtr(new InspectorDebuggerAgent(inspectorController, frontend));
ScriptDebugServer::shared().clearBreakpoints();
+ // FIXME(WK44513): breakpoints activated flag should be synchronized between all front-ends
+ ScriptDebugServer::shared().setBreakpointsActivated(true);
ScriptDebugServer::shared().addListener(agent.get(), inspectorController->inspectedPage());
return agent.release();
}
-InspectorDebuggerAgent::InspectorDebuggerAgent(InspectorController* inspectorController, RemoteInspectorFrontend* remoteFrontend)
+InspectorDebuggerAgent::InspectorDebuggerAgent(InspectorController* inspectorController, InspectorFrontend* frontend)
: m_inspectorController(inspectorController)
- , m_remoteFrontend(remoteFrontend)
+ , m_frontend(frontend)
, m_pausedScriptState(0)
, m_breakpointsLoaded(false)
{
@@ -167,7 +169,7 @@ void InspectorDebuggerAgent::stepOutOfFunction()
void InspectorDebuggerAgent::setPauseOnExceptionsState(long pauseState)
{
ScriptDebugServer::shared().setPauseOnExceptionsState(static_cast<ScriptDebugServer::PauseOnExceptionsState>(pauseState));
- m_remoteFrontend->updatePauseOnExceptionsState(ScriptDebugServer::shared().pauseOnExceptionsState());
+ m_frontend->updatePauseOnExceptionsState(ScriptDebugServer::shared().pauseOnExceptionsState());
}
void InspectorDebuggerAgent::clearForPageNavigation()
@@ -246,7 +248,7 @@ void InspectorDebuggerAgent::saveBreakpoints()
void InspectorDebuggerAgent::didParseSource(const String& sourceID, const String& url, const String& data, int firstLine, ScriptWorldType worldType)
{
// Don't send script content to the front end until it's really needed.
- m_remoteFrontend->parsedScriptSource(sourceID, url, "", firstLine, worldType);
+ m_frontend->parsedScriptSource(sourceID, url, "", firstLine, worldType);
m_scriptIDToContent.set(sourceID, data);
@@ -264,7 +266,7 @@ void InspectorDebuggerAgent::didParseSource(const String& sourceID, const String
bool success = ScriptDebugServer::shared().setBreakpoint(sourceID, breakpointIt->second, lineNumber, &actualLineNumber);
if (!success)
continue;
- m_remoteFrontend->restoredBreakpoint(sourceID, url, actualLineNumber, breakpointIt->second.enabled, breakpointIt->second.condition);
+ m_frontend->restoredBreakpoint(sourceID, url, actualLineNumber, breakpointIt->second.enabled, breakpointIt->second.condition);
String breakpointId = formatBreakpointId(sourceID, actualLineNumber);
m_breakpointsMapping.set(breakpointId, lineNumber);
}
@@ -274,7 +276,7 @@ void InspectorDebuggerAgent::didParseSource(const String& sourceID, const String
void InspectorDebuggerAgent::failedToParseSource(const String& url, const String& data, int firstLine, int errorLine, const String& errorMessage)
{
- m_remoteFrontend->failedToParseScriptSource(url, data, firstLine, errorLine, errorMessage);
+ m_frontend->failedToParseScriptSource(url, data, firstLine, errorLine, errorMessage);
}
void InspectorDebuggerAgent::didPause(ScriptState* scriptState)
@@ -282,13 +284,13 @@ void InspectorDebuggerAgent::didPause(ScriptState* scriptState)
ASSERT(scriptState && !m_pausedScriptState);
m_pausedScriptState = scriptState;
RefPtr<InspectorValue> callFrames = currentCallFrames();
- m_remoteFrontend->pausedScript(callFrames.get());
+ m_frontend->pausedScript(callFrames.get());
}
void InspectorDebuggerAgent::didContinue()
{
m_pausedScriptState = 0;
- m_remoteFrontend->resumedScript();
+ m_frontend->resumedScript();
}
} // namespace WebCore
diff --git a/WebCore/inspector/InspectorDebuggerAgent.h b/WebCore/inspector/InspectorDebuggerAgent.h
index 2cfbf55..91bcd49 100644
--- a/WebCore/inspector/InspectorDebuggerAgent.h
+++ b/WebCore/inspector/InspectorDebuggerAgent.h
@@ -42,12 +42,12 @@
namespace WebCore {
class InjectedScriptHost;
class InspectorController;
+class InspectorFrontend;
class InspectorValue;
-class RemoteInspectorFrontend;
class InspectorDebuggerAgent : public ScriptDebugListener, public Noncopyable {
public:
- static PassOwnPtr<InspectorDebuggerAgent> create(InspectorController*, RemoteInspectorFrontend*);
+ static PassOwnPtr<InspectorDebuggerAgent> create(InspectorController*, InspectorFrontend*);
virtual ~InspectorDebuggerAgent();
static bool isDebuggerAlwaysEnabled();
@@ -73,7 +73,7 @@ public:
static String md5Base16(const String& string);
private:
- InspectorDebuggerAgent(InspectorController*, RemoteInspectorFrontend*);
+ InspectorDebuggerAgent(InspectorController*, InspectorFrontend*);
PassRefPtr<InspectorValue> currentCallFrames();
@@ -86,7 +86,7 @@ private:
virtual void didContinue();
InspectorController* m_inspectorController;
- RemoteInspectorFrontend* m_remoteFrontend;
+ InspectorFrontend* m_frontend;
ScriptState* m_pausedScriptState;
HashMap<String, String> m_sourceIDToURL;
HashMap<String, String> m_scriptIDToContent;
diff --git a/WebCore/inspector/InspectorFrontendClientLocal.cpp b/WebCore/inspector/InspectorFrontendClientLocal.cpp
index b45dd34..77616da 100644
--- a/WebCore/inspector/InspectorFrontendClientLocal.cpp
+++ b/WebCore/inspector/InspectorFrontendClientLocal.cpp
@@ -126,8 +126,7 @@ void InspectorFrontendClientLocal::setAttachedWindow(bool attached)
ASSERT_NOT_REACHED();
return;
}
- ScriptFunctionCall function(webInspectorObj, "dispatch");
- function.appendArgument("setAttachedWindow");
+ ScriptFunctionCall function(webInspectorObj, "setAttachedWindow");
function.appendArgument(attached);
function.call();
}
diff --git a/WebCore/inspector/InspectorFrontendHost.cpp b/WebCore/inspector/InspectorFrontendHost.cpp
index f9bf176..8dc00ae 100644
--- a/WebCore/inspector/InspectorFrontendHost.cpp
+++ b/WebCore/inspector/InspectorFrontendHost.cpp
@@ -92,8 +92,7 @@ private:
if (m_frontendHost) {
int itemNumber = item->action() - ContextMenuItemBaseCustomTag;
- ScriptFunctionCall function(m_webInspector, "dispatch");
- function.appendArgument("contextMenuItemSelected");
+ ScriptFunctionCall function(m_webInspector, "contextMenuItemSelected");
function.appendArgument(itemNumber);
function.call();
}
@@ -102,8 +101,7 @@ private:
virtual void contextMenuCleared()
{
if (m_frontendHost) {
- ScriptFunctionCall function(m_webInspector, "dispatch");
- function.appendArgument("contextMenuCleared");
+ ScriptFunctionCall function(m_webInspector, "contextMenuCleared");
function.call();
m_frontendHost->m_menuProvider = 0;
diff --git a/WebCore/inspector/InspectorProfilerAgent.cpp b/WebCore/inspector/InspectorProfilerAgent.cpp
new file mode 100644
index 0000000..a73469a
--- /dev/null
+++ b/WebCore/inspector/InspectorProfilerAgent.cpp
@@ -0,0 +1,210 @@
+/*
+ * Copyright (C) 2010 Apple Inc. All rights reserved.
+ * Copyright (C) 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:
+ *
+ * 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.
+ * 3. Neither the name of Apple Computer, Inc. ("Apple") 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 APPLE 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 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 "InspectorProfilerAgent.h"
+
+#if ENABLE(JAVASCRIPT_DEBUGGER)
+
+#include "Console.h"
+#include "InspectorController.h"
+#include "InspectorFrontend.h"
+#include "InspectorValues.h"
+#include "KURL.h"
+#include "Page.h"
+#include "ScriptDebugServer.h"
+#include "ScriptProfile.h"
+#include "ScriptProfiler.h"
+#include <wtf/OwnPtr.h>
+
+#if USE(JSC)
+#include "JSDOMWindow.h"
+#endif
+
+namespace WebCore {
+
+static const char* const UserInitiatedProfileName = "org.webkit.profiles.user-initiated";
+static const char* const CPUProfileType = "CPU";
+
+PassOwnPtr<InspectorProfilerAgent> InspectorProfilerAgent::create(InspectorController* inspectorController)
+{
+ OwnPtr<InspectorProfilerAgent> agent = adoptPtr(new InspectorProfilerAgent(inspectorController));
+ return agent.release();
+}
+
+InspectorProfilerAgent::InspectorProfilerAgent(InspectorController* inspectorController)
+ : m_inspectorController(inspectorController)
+ , m_frontend(0)
+ , m_enabled(ScriptProfiler::isProfilerAlwaysEnabled())
+ , m_recordingUserInitiatedProfile(false)
+ , m_currentUserInitiatedProfileNumber(-1)
+ , m_nextUserInitiatedProfileNumber(1)
+{
+}
+
+InspectorProfilerAgent::~InspectorProfilerAgent()
+{
+}
+
+void InspectorProfilerAgent::addProfile(PassRefPtr<ScriptProfile> prpProfile, unsigned lineNumber, const String& sourceURL)
+{
+ RefPtr<ScriptProfile> profile = prpProfile;
+ m_profiles.add(profile->uid(), profile);
+ if (m_frontend)
+ m_frontend->addProfileHeader(createProfileHeader(*profile));
+ addProfileFinishedMessageToConsole(profile, lineNumber, sourceURL);
+}
+
+void InspectorProfilerAgent::addProfileFinishedMessageToConsole(PassRefPtr<ScriptProfile> prpProfile, unsigned lineNumber, const String& sourceURL)
+{
+ RefPtr<ScriptProfile> profile = prpProfile;
+ String title = profile->title();
+ String message = String::format("Profile \"webkit-profile://%s/%s#%d\" finished.", CPUProfileType, encodeWithURLEscapeSequences(title).utf8().data(), profile->uid());
+ m_inspectorController->addMessageToConsole(JSMessageSource, LogMessageType, LogMessageLevel, message, lineNumber, sourceURL);
+}
+
+void InspectorProfilerAgent::addStartProfilingMessageToConsole(const String& title, unsigned lineNumber, const String& sourceURL)
+{
+ String message = String::format("Profile \"webkit-profile://%s/%s#0\" started.", CPUProfileType, encodeWithURLEscapeSequences(title).utf8().data());
+ m_inspectorController->addMessageToConsole(JSMessageSource, LogMessageType, LogMessageLevel, message, lineNumber, sourceURL);
+}
+
+PassRefPtr<InspectorObject> InspectorProfilerAgent::createProfileHeader(const ScriptProfile& profile)
+{
+ RefPtr<InspectorObject> header = InspectorObject::create();
+ header->setString("title", profile.title());
+ header->setNumber("uid", profile.uid());
+ header->setString("typeId", String(CPUProfileType));
+ return header;
+}
+
+void InspectorProfilerAgent::disable()
+{
+ if (!m_enabled)
+ return;
+ m_enabled = false;
+ ScriptDebugServer::shared().recompileAllJSFunctionsSoon();
+ if (m_frontend)
+ m_frontend->profilerWasDisabled();
+}
+
+void InspectorProfilerAgent::enable(bool skipRecompile)
+{
+ if (m_enabled)
+ return;
+ m_enabled = true;
+ if (!skipRecompile)
+ ScriptDebugServer::shared().recompileAllJSFunctionsSoon();
+ if (m_frontend)
+ m_frontend->profilerWasEnabled();
+}
+
+String InspectorProfilerAgent::getCurrentUserInitiatedProfileName(bool incrementProfileNumber)
+{
+ if (incrementProfileNumber)
+ m_currentUserInitiatedProfileNumber = m_nextUserInitiatedProfileNumber++;
+
+ return String::format("%s.%d", UserInitiatedProfileName, m_currentUserInitiatedProfileNumber);
+}
+
+void InspectorProfilerAgent::getProfileHeaders(RefPtr<InspectorArray>* headers)
+{
+ ProfilesMap::iterator profilesEnd = m_profiles.end();
+ for (ProfilesMap::iterator it = m_profiles.begin(); it != profilesEnd; ++it)
+ (*headers)->pushObject(createProfileHeader(*it->second));
+}
+
+void InspectorProfilerAgent::getProfile(unsigned uid, RefPtr<InspectorObject>* profileObject)
+{
+ ProfilesMap::iterator it = m_profiles.find(uid);
+ if (it != m_profiles.end()) {
+ *profileObject = createProfileHeader(*it->second);
+ (*profileObject)->setObject("head", it->second->buildInspectorObjectForHead());
+ }
+}
+
+void InspectorProfilerAgent::removeProfile(unsigned uid)
+{
+ if (m_profiles.contains(uid))
+ m_profiles.remove(uid);
+}
+
+void InspectorProfilerAgent::resetState()
+{
+ m_profiles.clear();
+ m_currentUserInitiatedProfileNumber = 1;
+ m_nextUserInitiatedProfileNumber = 1;
+ if (m_frontend)
+ m_frontend->resetProfilesPanel();
+}
+
+void InspectorProfilerAgent::startUserInitiatedProfiling()
+{
+ if (!enabled()) {
+ enable(false);
+ ScriptDebugServer::shared().recompileAllJSFunctions();
+ }
+ m_recordingUserInitiatedProfile = true;
+ String title = getCurrentUserInitiatedProfileName(true);
+#if USE(JSC)
+ JSC::ExecState* scriptState = toJSDOMWindow(m_inspectorController->inspectedPage()->mainFrame(), debuggerWorld())->globalExec();
+#else
+ ScriptState* scriptState = 0;
+#endif
+ ScriptProfiler::start(scriptState, title);
+ addStartProfilingMessageToConsole(title, 0, String());
+ toggleRecordButton(true);
+}
+
+void InspectorProfilerAgent::stopUserInitiatedProfiling()
+{
+ m_recordingUserInitiatedProfile = false;
+ String title = getCurrentUserInitiatedProfileName();
+#if USE(JSC)
+ JSC::ExecState* scriptState = toJSDOMWindow(m_inspectorController->inspectedPage()->mainFrame(), debuggerWorld())->globalExec();
+#else
+ // Use null script state to avoid filtering by context security token.
+ // All functions from all iframes should be visible from Inspector UI.
+ ScriptState* scriptState = 0;
+#endif
+ RefPtr<ScriptProfile> profile = ScriptProfiler::stop(scriptState, title);
+ if (profile)
+ addProfile(profile, 0, String());
+ toggleRecordButton(false);
+}
+
+void InspectorProfilerAgent::toggleRecordButton(bool isProfiling)
+{
+ if (m_frontend)
+ m_frontend->setRecordingProfile(isProfiling);
+}
+
+} // namespace WebCore
+
+#endif // ENABLE(JAVASCRIPT_DEBUGGER)
diff --git a/WebCore/inspector/InspectorProfilerAgent.h b/WebCore/inspector/InspectorProfilerAgent.h
new file mode 100644
index 0000000..9593eba
--- /dev/null
+++ b/WebCore/inspector/InspectorProfilerAgent.h
@@ -0,0 +1,93 @@
+/*
+ * Copyright (C) 2010 Apple Inc. All rights reserved.
+ * Copyright (C) 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:
+ *
+ * 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.
+ * 3. Neither the name of Apple Computer, Inc. ("Apple") 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 APPLE 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 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 InspectorProfilerAgent_h
+#define InspectorProfilerAgent_h
+
+#if ENABLE(JAVASCRIPT_DEBUGGER)
+
+#include "PlatformString.h"
+#include <wtf/Forward.h>
+#include <wtf/HashMap.h>
+#include <wtf/Noncopyable.h>
+#include <wtf/PassOwnPtr.h>
+
+namespace WebCore {
+
+class InspectorArray;
+class InspectorController;
+class InspectorFrontend;
+class InspectorObject;
+class ScriptProfile;
+
+class InspectorProfilerAgent : public Noncopyable {
+public:
+ static PassOwnPtr<InspectorProfilerAgent> create(InspectorController*);
+ virtual ~InspectorProfilerAgent();
+
+ void addProfile(PassRefPtr<ScriptProfile> prpProfile, unsigned lineNumber, const String& sourceURL);
+ void addProfileFinishedMessageToConsole(PassRefPtr<ScriptProfile>, unsigned lineNumber, const String& sourceURL);
+ void addStartProfilingMessageToConsole(const String& title, unsigned lineNumber, const String& sourceURL);
+ void clearProfiles() { resetState(); }
+ void disable();
+ void enable(bool skipRecompile);
+ bool enabled() { return m_enabled; }
+ String getCurrentUserInitiatedProfileName(bool incrementProfileNumber = false);
+ void getProfileHeaders(RefPtr<InspectorArray>* headers);
+ void getProfile(unsigned uid, RefPtr<InspectorObject>* profileObject);
+ bool isRecordingUserInitiatedProfile() { return m_recordingUserInitiatedProfile; }
+ void removeProfile(unsigned uid);
+ void resetState();
+ void setFrontend(InspectorFrontend* frontend) { m_frontend = frontend; }
+ void startProfiling() { startUserInitiatedProfiling(); }
+ void startUserInitiatedProfiling();
+ void stopProfiling() { stopUserInitiatedProfiling(); }
+ void stopUserInitiatedProfiling();
+ void toggleRecordButton(bool isProfiling);
+
+private:
+ typedef HashMap<unsigned int, RefPtr<ScriptProfile> > ProfilesMap;
+
+ InspectorProfilerAgent(InspectorController*);
+ PassRefPtr<InspectorObject> createProfileHeader(const ScriptProfile& profile);
+
+ InspectorController* m_inspectorController;
+ InspectorFrontend* m_frontend;
+ bool m_enabled;
+ bool m_recordingUserInitiatedProfile;
+ int m_currentUserInitiatedProfileNumber;
+ unsigned m_nextUserInitiatedProfileNumber;
+ ProfilesMap m_profiles;
+};
+
+} // namespace WebCore
+
+#endif // ENABLE(JAVASCRIPT_DEBUGGER)
+
+#endif // !defined(InspectorProfilerAgent_h)
diff --git a/WebCore/inspector/InspectorResource.cpp b/WebCore/inspector/InspectorResource.cpp
index a2b55b0..ed07339 100644
--- a/WebCore/inspector/InspectorResource.cpp
+++ b/WebCore/inspector/InspectorResource.cpp
@@ -38,8 +38,8 @@
#include "DocLoader.h"
#include "DocumentLoader.h"
#include "Frame.h"
+#include "InspectorFrontend.h"
#include "InspectorValues.h"
-#include "RemoteInspectorFrontend.h"
#include "ResourceLoadTiming.h"
#include "ResourceRequest.h"
#include "ResourceResponse.h"
@@ -175,7 +175,7 @@ static PassRefPtr<InspectorObject> buildObjectForTiming(ResourceLoadTiming* timi
}
-void InspectorResource::updateScriptObject(RemoteInspectorFrontend* frontend)
+void InspectorResource::updateScriptObject(InspectorFrontend* frontend)
{
if (m_changes.hasChange(NoChange))
return;
@@ -251,7 +251,7 @@ void InspectorResource::updateScriptObject(RemoteInspectorFrontend* frontend)
m_changes.clearAll();
}
-void InspectorResource::releaseScriptObject(RemoteInspectorFrontend* frontend)
+void InspectorResource::releaseScriptObject(InspectorFrontend* frontend)
{
m_changes.setAll();
diff --git a/WebCore/inspector/InspectorResource.h b/WebCore/inspector/InspectorResource.h
index 4c12ea0..4004142 100644
--- a/WebCore/inspector/InspectorResource.h
+++ b/WebCore/inspector/InspectorResource.h
@@ -46,7 +46,7 @@ namespace WebCore {
class CachedResource;
class DocumentLoader;
class Frame;
- class RemoteInspectorFrontend;
+ class InspectorFrontend;
class ResourceLoadTiming;
class ResourceRequest;
class ResourceResponse;
@@ -76,8 +76,8 @@ namespace WebCore {
~InspectorResource();
PassRefPtr<InspectorResource> appendRedirect(unsigned long identifier, const KURL& redirectURL);
- void updateScriptObject(RemoteInspectorFrontend* frontend);
- void releaseScriptObject(RemoteInspectorFrontend* frontend);
+ void updateScriptObject(InspectorFrontend* frontend);
+ void releaseScriptObject(InspectorFrontend* frontend);
void updateRequest(const ResourceRequest&);
void updateResponse(const ResourceResponse&);
diff --git a/WebCore/inspector/InspectorStorageAgent.cpp b/WebCore/inspector/InspectorStorageAgent.cpp
index 66d3372..1f565fa 100644
--- a/WebCore/inspector/InspectorStorageAgent.cpp
+++ b/WebCore/inspector/InspectorStorageAgent.cpp
@@ -34,6 +34,7 @@
#include "Database.h"
#include "ExceptionCode.h"
+#include "InspectorFrontend.h"
#include "InspectorValues.h"
#include "SQLError.h"
#include "SQLStatementCallback.h"
@@ -43,7 +44,6 @@
#include "SQLTransactionCallback.h"
#include "SQLTransactionErrorCallback.h"
#include "SQLValue.h"
-#include "RemoteInspectorFrontend.h"
#include "VoidCallback.h"
#include <wtf/Vector.h>
@@ -200,7 +200,7 @@ private:
} // namespace
-InspectorStorageAgent::InspectorStorageAgent(RemoteInspectorFrontend* frontend)
+InspectorStorageAgent::InspectorStorageAgent(InspectorFrontend* frontend)
: m_frontend(frontend)
{
}
diff --git a/WebCore/inspector/InspectorStorageAgent.h b/WebCore/inspector/InspectorStorageAgent.h
index b47e0d3..b1ceee4 100644
--- a/WebCore/inspector/InspectorStorageAgent.h
+++ b/WebCore/inspector/InspectorStorageAgent.h
@@ -35,11 +35,11 @@
namespace WebCore {
class Database;
-class RemoteInspectorFrontend;
+class InspectorFrontend;
class InspectorStorageAgent : public RefCounted<InspectorStorageAgent> {
public:
- static PassRefPtr<InspectorStorageAgent> create(RemoteInspectorFrontend* frontend)
+ static PassRefPtr<InspectorStorageAgent> create(InspectorFrontend* frontend)
{
return adoptRef(new InspectorStorageAgent(frontend));
}
@@ -48,13 +48,13 @@ public:
long executeSQL(Database*, const String& query);
- RemoteInspectorFrontend* frontend() { return m_frontend; }
+ InspectorFrontend* frontend() { return m_frontend; }
void clearFrontend();
private:
- InspectorStorageAgent(RemoteInspectorFrontend*);
+ InspectorStorageAgent(InspectorFrontend*);
- RemoteInspectorFrontend* m_frontend;
+ InspectorFrontend* m_frontend;
};
} // namespace WebCore
diff --git a/WebCore/inspector/InspectorTimelineAgent.cpp b/WebCore/inspector/InspectorTimelineAgent.cpp
index aa42a54..fbb17c4 100644
--- a/WebCore/inspector/InspectorTimelineAgent.cpp
+++ b/WebCore/inspector/InspectorTimelineAgent.cpp
@@ -34,8 +34,8 @@
#if ENABLE(INSPECTOR)
#include "Event.h"
+#include "InspectorFrontend.h"
#include "IntRect.h"
-#include "RemoteInspectorFrontend.h"
#include "ResourceRequest.h"
#include "ResourceResponse.h"
#include "TimelineRecordFactory.h"
@@ -46,7 +46,7 @@ namespace WebCore {
int InspectorTimelineAgent::s_instanceCount = 0;
-InspectorTimelineAgent::InspectorTimelineAgent(RemoteInspectorFrontend* frontend)
+InspectorTimelineAgent::InspectorTimelineAgent(InspectorFrontend* frontend)
: m_frontend(frontend)
{
++s_instanceCount;
@@ -279,7 +279,7 @@ void InspectorTimelineAgent::reset()
m_recordStack.clear();
}
-void InspectorTimelineAgent::resetFrontendProxyObject(RemoteInspectorFrontend* frontend)
+void InspectorTimelineAgent::resetFrontendProxyObject(InspectorFrontend* frontend)
{
ASSERT(frontend);
reset();
diff --git a/WebCore/inspector/InspectorTimelineAgent.h b/WebCore/inspector/InspectorTimelineAgent.h
index 16d7b83..6b3324b 100644
--- a/WebCore/inspector/InspectorTimelineAgent.h
+++ b/WebCore/inspector/InspectorTimelineAgent.h
@@ -42,7 +42,7 @@
namespace WebCore {
class Event;
-class RemoteInspectorFrontend;
+class InspectorFrontend;
class IntRect;
class ResourceRequest;
class ResourceResponse;
@@ -74,11 +74,11 @@ enum TimelineRecordType {
class InspectorTimelineAgent : ScriptGCEventListener, public Noncopyable {
public:
- InspectorTimelineAgent(RemoteInspectorFrontend* frontend);
+ InspectorTimelineAgent(InspectorFrontend* frontend);
~InspectorTimelineAgent();
void reset();
- void resetFrontendProxyObject(RemoteInspectorFrontend*);
+ void resetFrontendProxyObject(InspectorFrontend*);
// Methods called from WebCore.
void willCallFunction(const String& scriptName, int scriptLine);
@@ -152,7 +152,7 @@ private:
void pushGCEventRecords();
- RemoteInspectorFrontend* m_frontend;
+ InspectorFrontend* m_frontend;
Vector<TimelineRecordEntry> m_recordStack;
static int s_instanceCount;
diff --git a/WebCore/inspector/InspectorValues.h b/WebCore/inspector/InspectorValues.h
index 4bc36f2..473ad21 100644
--- a/WebCore/inspector/InspectorValues.h
+++ b/WebCore/inspector/InspectorValues.h
@@ -176,6 +176,7 @@ public:
void setObject(const String& name, PassRefPtr<InspectorObject>);
void setArray(const String& name, PassRefPtr<InspectorArray>);
+ const_iterator find(const String& name) const;
bool getBool(const String& name, bool* output) const;
bool getNumber(const String& name, double* output) const;
bool getString(const String& name, String* output) const;
@@ -224,6 +225,11 @@ private:
Vector<RefPtr<InspectorValue> > m_data;
};
+inline InspectorObject::const_iterator InspectorObject::find(const String& name) const
+{
+ return m_data.find(name);
+}
+
inline void InspectorObject::setBool(const String& name, bool value)
{
setValue(name, InspectorBasicValue::create(value));
diff --git a/WebCore/inspector/front-end/BreakpointManager.js b/WebCore/inspector/front-end/BreakpointManager.js
index 21fa6a4..824bc31 100644
--- a/WebCore/inspector/front-end/BreakpointManager.js
+++ b/WebCore/inspector/front-end/BreakpointManager.js
@@ -50,22 +50,16 @@ WebInspector.BreakpointManager.prototype = {
}
},
- setBreakpoint: function(sourceID, sourceURL, line, enabled, condition)
+ setBreakpoint: function(sourceID, url, line, enabled, condition)
{
- var breakpoint = this._setBreakpoint(sourceID, sourceURL, line, enabled, condition);
+ var breakpoint = this._setBreakpoint(sourceID, url, line, enabled, condition);
if (breakpoint)
this._setBreakpointOnBackend(breakpoint);
},
- restoredBreakpoint: function(sourceID, sourceURL, line, enabled, condition)
+ restoredBreakpoint: function(sourceID, url, line, enabled, condition)
{
- this._setBreakpoint(sourceID, sourceURL, line, enabled, condition);
- },
-
- removeBreakpoint: function(breakpoint)
- {
- if (this._removeBreakpoint(breakpoint))
- InspectorBackend.removeBreakpoint(breakpoint.sourceID, breakpoint.line);
+ this._setBreakpoint(sourceID, url, line, enabled, condition);
},
breakpointsForSourceID: function(sourceID)
@@ -94,27 +88,22 @@ WebInspector.BreakpointManager.prototype = {
delete this._oneTimeBreakpoint;
},
- _setBreakpoint: function(sourceID, sourceURL, line, enabled, condition)
+ _setBreakpoint: function(sourceID, url, line, enabled, condition)
{
- var breakpoint = new WebInspector.Breakpoint(this, sourceID, sourceURL, line, enabled, condition);
+ var breakpoint = new WebInspector.Breakpoint(this, sourceID, url, line, enabled, condition);
if (this._breakpoints[breakpoint.id])
return;
if (this._oneTimeBreakpoint && (this._oneTimeBreakpoint.id == breakpoint.id))
delete this._oneTimeBreakpoint;
this._breakpoints[breakpoint.id] = breakpoint;
+ breakpoint.addEventListener("removed", this._breakpointRemoved, this);
this.dispatchEventToListeners("breakpoint-added", breakpoint);
return breakpoint;
},
- _removeBreakpoint: function(breakpoint)
+ _breakpointRemoved: function(event)
{
- if (!(breakpoint.id in this._breakpoints))
- return false;
- breakpoint.removeAllListeners();
- delete breakpoint._breakpointManager;
- delete this._breakpoints[breakpoint.id];
- this.dispatchEventToListeners("breakpoint-removed", breakpoint);
- return true;
+ delete this._breakpoints[event.target.id];
},
_setBreakpointOnBackend: function(breakpoint, isOneTime)
@@ -129,9 +118,9 @@ WebInspector.BreakpointManager.prototype = {
else
delete this._oneTimeBreakpoint;
} else {
- this._removeBreakpoint(breakpoint);
+ breakpoint.remove();
if (success)
- this._setBreakpoint(breakpoint.sourceID, breakpoint.sourceURL, line, breakpoint.enabled, breakpoint.condition);
+ this._setBreakpoint(breakpoint.sourceID, breakpoint.url, line, breakpoint.enabled, breakpoint.condition);
}
}
var callbackId = WebInspector.Callback.wrap(didSetBreakpoint.bind(this));
@@ -141,9 +130,9 @@ WebInspector.BreakpointManager.prototype = {
WebInspector.BreakpointManager.prototype.__proto__ = WebInspector.Object.prototype;
-WebInspector.Breakpoint = function(breakpointManager, sourceID, sourceURL, line, enabled, condition)
+WebInspector.Breakpoint = function(breakpointManager, sourceID, url, line, enabled, condition)
{
- this.url = sourceURL;
+ this.url = url;
this.line = line;
this.sourceID = sourceID;
this._enabled = enabled;
@@ -165,10 +154,7 @@ WebInspector.Breakpoint.prototype = {
this._enabled = x;
this._breakpointManager._setBreakpointOnBackend(this);
- if (this._enabled)
- this.dispatchEventToListeners("enabled");
- else
- this.dispatchEventToListeners("disabled");
+ this.dispatchEventToListeners("enable-changed");
},
get sourceText()
@@ -182,12 +168,6 @@ WebInspector.Breakpoint.prototype = {
this.dispatchEventToListeners("text-changed");
},
- get label()
- {
- var displayName = (this.url ? WebInspector.displayNameForURL(this.url) : WebInspector.UIString("(program)"));
- return displayName + ":" + this.line;
- },
-
get id()
{
return this.sourceID + ":" + this.line;
@@ -208,8 +188,15 @@ WebInspector.Breakpoint.prototype = {
if (this.enabled)
this._breakpointManager._setBreakpointOnBackend(this);
this.dispatchEventToListeners("condition-changed");
+ },
+
+ remove: function()
+ {
+ InspectorBackend.removeBreakpoint(this.sourceID, this.line);
+ this.dispatchEventToListeners("removed");
+ this.removeAllListeners();
+ delete this._breakpointManager;
}
}
WebInspector.Breakpoint.prototype.__proto__ = WebInspector.Object.prototype;
-
diff --git a/WebCore/inspector/front-end/BreakpointsSidebarPane.js b/WebCore/inspector/front-end/BreakpointsSidebarPane.js
index a4daa2d..ccf45b6 100644
--- a/WebCore/inspector/front-end/BreakpointsSidebarPane.js
+++ b/WebCore/inspector/front-end/BreakpointsSidebarPane.js
@@ -23,9 +23,9 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-WebInspector.BreakpointsSidebarPane = function()
+WebInspector.BreakpointsSidebarPane = function(title)
{
- WebInspector.SidebarPane.call(this, WebInspector.UIString("Breakpoints"));
+ WebInspector.SidebarPane.call(this, title);
this.listElement = document.createElement("ol");
this.listElement.className = "breakpoint-list";
@@ -35,9 +35,6 @@ WebInspector.BreakpointsSidebarPane = function()
this.emptyElement.textContent = WebInspector.UIString("No Breakpoints");
this.bodyElement.appendChild(this.emptyElement);
-
- WebInspector.breakpointManager.addEventListener("breakpoint-added", this._breakpointAdded, this);
- WebInspector.breakpointManager.addEventListener("breakpoint-removed", this._breakpointRemoved, this);
}
WebInspector.BreakpointsSidebarPane.prototype = {
@@ -50,15 +47,25 @@ WebInspector.BreakpointsSidebarPane.prototype = {
}
},
- _breakpointAdded: function(event)
+ addBreakpoint: function(breakpointItem)
{
- var breakpoint = event.data;
+ breakpointItem.addEventListener("removed", this._breakpointRemoved, this);
+
+ var element = breakpointItem.element();
+ element._breakpointItem = breakpointItem;
- breakpoint.addEventListener("enabled", this._breakpointEnableChanged, this);
- breakpoint.addEventListener("disabled", this._breakpointEnableChanged, this);
- breakpoint.addEventListener("text-changed", this._breakpointTextChanged, this);
+ var currentElement = this.listElement.firstChild;
+ while (currentElement) {
+ if (currentElement._breakpointItem.compareTo(element._breakpointItem) > 0) {
+ this.listElement.insertBefore(element, currentElement);
+ break;
+ }
+ currentElement = currentElement.nextSibling;
+ }
+ if (!currentElement)
+ this.listElement.appendChild(element);
- this._appendBreakpointElement(breakpoint);
+ element.addEventListener("contextmenu", this._contextMenuEventFired.bind(this, breakpointItem), true);
if (this.emptyElement.parentElement) {
this.bodyElement.removeChild(this.emptyElement);
@@ -66,88 +73,136 @@ WebInspector.BreakpointsSidebarPane.prototype = {
}
},
- _appendBreakpointElement: function(breakpoint)
+ _breakpointRemoved: function(event)
{
- function checkboxClicked(event)
- {
- breakpoint.enabled = !breakpoint.enabled;
-
- // without this, we'd switch to the source of the clicked breakpoint
- event.stopPropagation();
+ this.listElement.removeChild(event.target.element());
+ if (!this.listElement.firstChild) {
+ this.bodyElement.removeChild(this.listElement);
+ this.bodyElement.appendChild(this.emptyElement);
}
+ },
- function breakpointClicked()
- {
- WebInspector.panels.scripts.showSourceLine(breakpoint.url, breakpoint.line);
- }
+ _contextMenuEventFired: function(breakpointItem, event)
+ {
+ var contextMenu = new WebInspector.ContextMenu();
+ contextMenu.appendItem(WebInspector.UIString("Remove Breakpoint"), breakpointItem.remove.bind(breakpointItem));
+ contextMenu.show(event);
+ }
+}
- var breakpointElement = document.createElement("li");
- breakpoint._breakpointListElement = breakpointElement;
- breakpointElement._breakpointObject = breakpoint;
- breakpointElement.addEventListener("click", breakpointClicked, false);
+WebInspector.BreakpointsSidebarPane.prototype.__proto__ = WebInspector.SidebarPane.prototype;
- var checkboxElement = document.createElement("input");
- checkboxElement.className = "checkbox-elem";
- checkboxElement.type = "checkbox";
- checkboxElement.checked = breakpoint.enabled;
- checkboxElement.addEventListener("click", checkboxClicked, false);
- breakpointElement.appendChild(checkboxElement);
+WebInspector.BreakpointItem = function(breakpoint)
+{
+ this._breakpoint = breakpoint;
- var labelElement = document.createTextNode(breakpoint.label);
- breakpointElement.appendChild(labelElement);
+ this._element = document.createElement("li");
- var sourceTextElement = document.createElement("div");
- sourceTextElement.textContent = breakpoint.sourceText;
- sourceTextElement.className = "source-text monospace";
- breakpointElement.appendChild(sourceTextElement);
+ var checkboxElement = document.createElement("input");
+ checkboxElement.className = "checkbox-elem";
+ checkboxElement.type = "checkbox";
+ checkboxElement.checked = this._breakpoint.enabled;
+ checkboxElement.addEventListener("click", this._checkboxClicked.bind(this), false);
+ this._element.appendChild(checkboxElement);
- var currentElement = this.listElement.firstChild;
- while (currentElement) {
- var currentBreak = currentElement._breakpointObject;
- if (currentBreak.url > breakpoint.url) {
- this.listElement.insertBefore(breakpointElement, currentElement);
- return;
- } else if (currentBreak.url == breakpoint.url && currentBreak.line > breakpoint.line) {
- this.listElement.insertBefore(breakpointElement, currentElement);
- return;
- }
- currentElement = currentElement.nextSibling;
- }
- this.listElement.appendChild(breakpointElement);
+ this._breakpoint.addEventListener("enable-changed", this._enableChanged, this);
+ this._breakpoint.addEventListener("removed", this._removed, this);
+}
+
+WebInspector.BreakpointItem.prototype = {
+ element: function()
+ {
+ return this._element;
},
- _breakpointRemoved: function(event)
+ remove: function()
{
- var breakpoint = event.data;
+ this._breakpoint.remove();
+ },
- breakpoint.removeEventListener("enabled", null, this);
- breakpoint.removeEventListener("disabled", null, this);
- breakpoint.removeEventListener("text-changed", null, this);
+ _checkboxClicked: function(event)
+ {
+ this._breakpoint.enabled = !this._breakpoint.enabled;
- var element = breakpoint._breakpointListElement;
- element.parentElement.removeChild(element);
+ // without this, we'd switch to the source of the clicked breakpoint
+ event.stopPropagation();
+ },
- if (!this.listElement.firstChild) {
- this.bodyElement.removeChild(this.listElement);
- this.bodyElement.appendChild(this.emptyElement);
- }
+ _enableChanged: function()
+ {
+ var checkbox = this._element.firstChild;
+ checkbox.checked = this._breakpoint.enabled;
},
- _breakpointEnableChanged: function(event)
+ _removed: function()
+ {
+ this.dispatchEventToListeners("removed");
+ }
+}
+
+WebInspector.BreakpointItem.prototype.__proto__ = WebInspector.Object.prototype;
+
+WebInspector.JSBreakpointItem = function(breakpoint)
+{
+ WebInspector.BreakpointItem.call(this, breakpoint);
+
+ this._element.addEventListener("click", this._breakpointClicked.bind(this), false);
+
+ var displayName = this._breakpoint.url ? WebInspector.displayNameForURL(this._breakpoint.url) : WebInspector.UIString("(program)");
+ var labelElement = document.createTextNode(displayName + ":" + this._breakpoint.line);
+ this._element.appendChild(labelElement);
+
+ var sourceTextElement = document.createElement("div");
+ sourceTextElement.textContent = this._breakpoint.sourceText;
+ sourceTextElement.className = "source-text monospace";
+ this._element.appendChild(sourceTextElement);
+
+ this._breakpoint.addEventListener("text-changed", this._textChanged, this);
+}
+
+WebInspector.JSBreakpointItem.prototype = {
+ compareTo: function(other)
{
- var breakpoint = event.target;
+ if (this._breakpoint.url != other._breakpoint.url)
+ return this._breakpoint.url < other._breakpoint.url ? -1 : 1;
+ if (this._breakpoint.line != other._breakpoint.line)
+ return this._breakpoint.line < other._breakpoint.line ? -1 : 1;
+ return 0;
+ },
- var checkbox = breakpoint._breakpointListElement.firstChild;
- checkbox.checked = breakpoint.enabled;
+ _breakpointClicked: function()
+ {
+ WebInspector.panels.scripts.showSourceLine(this._breakpoint.url, this._breakpoint.line);
},
- _breakpointTextChanged: function(event)
+ _textChanged: function()
{
- var breakpoint = event.target;
+ var sourceTextElement = this._element.firstChild.nextSibling.nextSibling;
+ sourceTextElement.textContent = this._breakpoint.sourceText;
+ }
+}
+
+WebInspector.JSBreakpointItem.prototype.__proto__ = WebInspector.BreakpointItem.prototype;
- var sourceTextElement = breakpoint._breakpointListElement.firstChild.nextSibling.nextSibling;
- sourceTextElement.textContent = breakpoint.sourceText;
+WebInspector.DOMBreakpointItem = function(breakpoint)
+{
+ WebInspector.BreakpointItem.call(this, breakpoint);
+
+ var link = WebInspector.panels.elements.linkifyNodeReference(this._breakpoint.node);
+ this._element.appendChild(link);
+
+ var type = WebInspector.DOMBreakpoint.Labels[this._breakpoint.type];
+ var typeElement = document.createTextNode(" - " + type);
+ this._element.appendChild(typeElement);
+}
+
+WebInspector.DOMBreakpointItem.prototype = {
+ compareTo: function(other)
+ {
+ if (this._breakpoint.type != other._breakpoint.type)
+ return this._breakpoint.type < other._breakpoint.type ? -1 : 1;
+ return 0;
}
}
-WebInspector.BreakpointsSidebarPane.prototype.__proto__ = WebInspector.SidebarPane.prototype;
+WebInspector.DOMBreakpointItem.prototype.__proto__ = WebInspector.BreakpointItem.prototype;
diff --git a/WebCore/inspector/front-end/CSSCompletions.js b/WebCore/inspector/front-end/CSSCompletions.js
index 5485464..9480467 100644
--- a/WebCore/inspector/front-end/CSSCompletions.js
+++ b/WebCore/inspector/front-end/CSSCompletions.js
@@ -1,27 +1,4 @@
-WebInspector.CSSCompletions = (function() {
- var used = {};
- var properties = [];
- var style = document.documentElement.style;
- var list = document.defaultView.getComputedStyle(document.documentElement, "");
- var length = list.length;
- for (var i = 0; i < length; ++i)
- used[properties[i] = list[i]] = true;
-
- for (var i = 0, end = length; i < length; ++i) {
- var propertyWords = properties[i].split("-");
- var j = propertyWords.length;
- while (--j) {
- propertyWords.pop();
- var shorthand = propertyWords.join("-");
- if (!(shorthand in used) && style[shorthand] !== undefined) {
- used[shorthand] = true;
- properties[end++] = shorthand;
- }
- }
- }
-
- return properties.sort();
-})();
+WebInspector.CSSCompletions = [];
WebInspector.CSSCompletions.startsWith = function(prefix)
{
@@ -45,6 +22,8 @@ WebInspector.CSSCompletions._firstIndexOfPrefix = function(prefix)
{
if (!prefix)
return -1;
+ if (!this.length)
+ return -1;
var maxIndex = this.length - 1;
var minIndex = 0;
@@ -100,3 +79,10 @@ WebInspector.CSSCompletions._closest = function(str, prefix, shift)
j = (j + propertiesWithPrefix.length + shift) % propertiesWithPrefix.length;
return propertiesWithPrefix[j];
}
+
+WebInspector.CSSCompletions._load = function(properties)
+{
+ for (var i = 0; i < properties.length; ++i)
+ WebInspector.CSSCompletions.push(properties[i]);
+ WebInspector.CSSCompletions.sort();
+}
diff --git a/WebCore/inspector/front-end/Callback.js b/WebCore/inspector/front-end/Callback.js
index d8163fe..0621fd1 100644
--- a/WebCore/inspector/front-end/Callback.js
+++ b/WebCore/inspector/front-end/Callback.js
@@ -42,9 +42,8 @@ WebInspector.Callback.prototype = {
return callbackId;
},
- processResponse: function(callbackId, opt_vararg)
+ processResponse: function(callbackId, args)
{
- var args = Array.prototype.slice.call(arguments, 1);
var callback = this._callbacks[callbackId];
callback.apply(null, args);
delete this._callbacks[callbackId];
diff --git a/WebCore/inspector/front-end/ConsoleView.js b/WebCore/inspector/front-end/ConsoleView.js
index 474c362..9785cd0 100644
--- a/WebCore/inspector/front-end/ConsoleView.js
+++ b/WebCore/inspector/front-end/ConsoleView.js
@@ -401,9 +401,9 @@ WebInspector.ConsoleView.prototype = {
var contextMenu = new WebInspector.ContextMenu();
if (!WebInspector.monitoringXHREnabled)
- contextMenu.appendItem(WebInspector.UIString("Enable XMLHttpRequest logging"), InspectorBackend.enableMonitoringXHR.bind(InspectorBackend));
+ contextMenu.appendCheckboxItem(WebInspector.UIString("XMLHttpRequest logging"), InspectorBackend.enableMonitoringXHR.bind(InspectorBackend), false);
else
- contextMenu.appendItem(WebInspector.UIString("Disable XMLHttpRequest logging"), InspectorBackend.disableMonitoringXHR.bind(InspectorBackend));
+ contextMenu.appendCheckboxItem(WebInspector.UIString("XMLHttpRequest logging"), InspectorBackend.disableMonitoringXHR.bind(InspectorBackend), true);
contextMenu.appendItem(WebInspector.UIString("Clear Console"), this.requestClearMessages.bind(this));
contextMenu.show(event);
},
diff --git a/WebCore/inspector/front-end/ContextMenu.js b/WebCore/inspector/front-end/ContextMenu.js
index 3cdb152..47045a2 100644
--- a/WebCore/inspector/front-end/ContextMenu.js
+++ b/WebCore/inspector/front-end/ContextMenu.js
@@ -46,10 +46,17 @@ WebInspector.ContextMenu.prototype = {
}
},
- appendItem: function(label, handler)
+ appendItem: function(label, handler, disabled)
{
var id = this._items.length;
- this._items.push({id: id, label: label});
+ this._items.push({type: "item", id: id, label: label, enabled: !disabled});
+ this._handlers[id] = handler;
+ },
+
+ appendCheckboxItem: function(label, handler, checked, disabled)
+ {
+ var id = this._items.length;
+ this._items.push({type: "checkbox", id: id, label: label, checked: !!checked, enabled: !disabled});
this._handlers[id] = handler;
},
@@ -60,7 +67,7 @@ WebInspector.ContextMenu.prototype = {
return;
if (!("id" in this._items[this._items.length - 1]))
return;
- this._items.push({});
+ this._items.push({type: "separator"});
},
_itemSelected: function(id)
diff --git a/WebCore/inspector/front-end/DOMAgent.js b/WebCore/inspector/front-end/DOMAgent.js
index 57422f6..0d79d51 100644
--- a/WebCore/inspector/front-end/DOMAgent.js
+++ b/WebCore/inspector/front-end/DOMAgent.js
@@ -677,3 +677,94 @@ WebInspector.childNodeRemoved = function()
this.domAgent._childNodeRemoved.apply(this.domAgent, arguments);
}
+WebInspector.DOMBreakpointManager = function()
+{
+ this._breakpoints = {};
+}
+
+WebInspector.DOMBreakpointManager.prototype = {
+ setBreakpoint: function(node, type)
+ {
+ if (!(node.id in this._breakpoints))
+ this._breakpoints[node.id] = {};
+ else if (type in this._breakpoints[node.id])
+ return;
+
+ var breakpoint = new WebInspector.DOMBreakpoint(node, type);
+ this._breakpoints[node.id][type] = breakpoint;
+ breakpoint.addEventListener("removed", this._breakpointRemoved, this);
+
+ this.dispatchEventToListeners("dom-breakpoint-added", breakpoint);
+ },
+
+ removeBreakpointsForNode: function(node)
+ {
+ var nodeBreakpoints = this._breakpoints[node.id];
+ for (var type in nodeBreakpoints)
+ nodeBreakpoints[type].remove();
+ },
+
+ _breakpointRemoved: function(event)
+ {
+ var breakpoint = event.target;
+
+ var nodeBreakpoints = this._breakpoints[breakpoint.node.id];
+ delete nodeBreakpoints[breakpoint.type];
+ for (var type in nodeBreakpoints)
+ return;
+ delete this._breakpoints[breakpoint.node.id];
+ }
+}
+
+WebInspector.DOMBreakpointManager.prototype.__proto__ = WebInspector.Object.prototype;
+
+WebInspector.DOMBreakpoint = function(node, type)
+{
+ this.node = node;
+ this.type = type;
+ this._enabled = true;
+
+ InspectorBackend.setDOMBreakpoint(this.node.id, this.type);
+}
+
+WebInspector.DOMBreakpoint.Types = {
+ SubtreeModified: 0,
+ AttributeModified: 1,
+ NodeRemoved: 2
+};
+
+WebInspector.DOMBreakpoint.Labels = {};
+WebInspector.DOMBreakpoint.Labels[WebInspector.DOMBreakpoint.Types.SubtreeModified] = WebInspector.UIString("Subtree Modified");
+WebInspector.DOMBreakpoint.Labels[WebInspector.DOMBreakpoint.Types.AttributeModified] = WebInspector.UIString("Attribute Modified");
+WebInspector.DOMBreakpoint.Labels[WebInspector.DOMBreakpoint.Types.NodeRemoved] = WebInspector.UIString("Node Removed");
+
+WebInspector.DOMBreakpoint.prototype = {
+ get enabled()
+ {
+ return this._enabled;
+ },
+
+ set enabled(enabled)
+ {
+ if (this._enabled === enabled)
+ return;
+
+ this._enabled = enabled;
+ if (this._enabled)
+ InspectorBackend.setDOMBreakpoint(this.node.id, this.type);
+ else
+ InspectorBackend.removeDOMBreakpoint(this.node.id, this.type);
+
+ this.dispatchEventToListeners("enable-changed");
+ },
+
+ remove: function()
+ {
+ if (this._enabled)
+ InspectorBackend.removeDOMBreakpoint(this.node.id, this.type);
+ this.dispatchEventToListeners("removed");
+ }
+}
+
+WebInspector.DOMBreakpoint.prototype.__proto__ = WebInspector.Object.prototype;
+
diff --git a/WebCore/inspector/front-end/ElementsPanel.js b/WebCore/inspector/front-end/ElementsPanel.js
index 0296737..f18299a 100644
--- a/WebCore/inspector/front-end/ElementsPanel.js
+++ b/WebCore/inspector/front-end/ElementsPanel.js
@@ -74,6 +74,8 @@ WebInspector.ElementsPanel = function()
this.sidebarPanes.styles = new WebInspector.StylesSidebarPane(this.sidebarPanes.computedStyle);
this.sidebarPanes.metrics = new WebInspector.MetricsSidebarPane();
this.sidebarPanes.properties = new WebInspector.PropertiesSidebarPane();
+ if (Preferences.domBreakpointsEnabled)
+ this.sidebarPanes.domBreakpoints = WebInspector.createDOMBreakpointsSidebarPane();
this.sidebarPanes.eventListeners = new WebInspector.EventListenersSidebarPane();
this.sidebarPanes.styles.onexpand = this.updateStyles.bind(this);
@@ -90,11 +92,8 @@ WebInspector.ElementsPanel = function()
this.sidebarElement = document.createElement("div");
this.sidebarElement.id = "elements-sidebar";
- this.sidebarElement.appendChild(this.sidebarPanes.computedStyle.element);
- this.sidebarElement.appendChild(this.sidebarPanes.styles.element);
- this.sidebarElement.appendChild(this.sidebarPanes.metrics.element);
- this.sidebarElement.appendChild(this.sidebarPanes.properties.element);
- this.sidebarElement.appendChild(this.sidebarPanes.eventListeners.element);
+ for (var pane in this.sidebarPanes)
+ this.sidebarElement.appendChild(this.sidebarPanes[pane].element);
this.sidebarResizeElement = document.createElement("div");
this.sidebarResizeElement.className = "sidebar-resizer-vertical";
@@ -179,6 +178,9 @@ WebInspector.ElementsPanel.prototype = {
this.recentlyModifiedNodes = [];
delete this.currentQuery;
+
+ if (Preferences.domBreakpointsEnabled)
+ this.sidebarPanes.domBreakpoints.reset();
},
setDocument: function(inspectedRootDocument)
diff --git a/WebCore/inspector/front-end/ElementsTreeOutline.js b/WebCore/inspector/front-end/ElementsTreeOutline.js
index c7d39f1..7f48161 100644
--- a/WebCore/inspector/front-end/ElementsTreeOutline.js
+++ b/WebCore/inspector/front-end/ElementsTreeOutline.js
@@ -402,7 +402,7 @@ WebInspector.ElementsTreeElement.prototype = {
var node = this.representedObject;
if (!node.nodeName || node.nodeName.toLowerCase() !== "img")
return;
-
+
function setTooltip(properties)
{
if (!properties)
@@ -761,6 +761,21 @@ WebInspector.ElementsTreeElement.prototype = {
contextMenu.appendItem(WebInspector.UIString("Edit as HTML"), this._editAsHTML.bind(this));
contextMenu.appendItem(WebInspector.UIString("Copy as HTML"), this._copyHTML.bind(this));
contextMenu.appendItem(WebInspector.UIString("Delete Node"), this.remove.bind(this));
+
+ if (Preferences.domBreakpointsEnabled) {
+ // Add debbuging-related actions
+ contextMenu.appendSeparator();
+
+ contextMenu.appendItem(WebInspector.UIString("Stop on Subtree Modifications"),
+ WebInspector.domBreakpointManager.setBreakpoint.bind(WebInspector.domBreakpointManager, this.representedObject, WebInspector.DOMBreakpoint.Types.SubtreeModified));
+ contextMenu.appendItem(WebInspector.UIString("Stop on Attributes Modifications"),
+ WebInspector.domBreakpointManager.setBreakpoint.bind(WebInspector.domBreakpointManager, this.representedObject, WebInspector.DOMBreakpoint.Types.AttributeModified));
+ contextMenu.appendItem(WebInspector.UIString("Stop on Node Removal"),
+ WebInspector.domBreakpointManager.setBreakpoint.bind(WebInspector.domBreakpointManager, this.representedObject, WebInspector.DOMBreakpoint.Types.NodeRemoved));
+
+ contextMenu.appendItem(WebInspector.UIString("Remove Breakpoints"),
+ WebInspector.domBreakpointManager.removeBreakpointsForNode.bind(WebInspector.domBreakpointManager, this.representedObject));
+ }
},
_populateTextContextMenu: function(contextMenu, textNode)
diff --git a/WebCore/inspector/front-end/ExtensionAPI.js b/WebCore/inspector/front-end/ExtensionAPI.js
index 476a463..a89dcf1 100644
--- a/WebCore/inspector/front-end/ExtensionAPI.js
+++ b/WebCore/inspector/front-end/ExtensionAPI.js
@@ -160,7 +160,6 @@ Panels.prototype = {
function PanelImpl(id)
{
this._id = id;
- this.onSelectionChanged = new EventSink("panel-objectSelected-" + id);
}
PanelImpl.prototype = {
@@ -182,6 +181,7 @@ function Panel(id)
{
var impl = new PanelImpl(id);
this.createSidebarPane = bind(impl.createSidebarPane, impl);
+ this.onSelectionChanged = new EventSink("panel-objectSelected-" + id);
}
function ExtensionPanel(id)
diff --git a/WebCore/inspector/front-end/Panel.js b/WebCore/inspector/front-end/Panel.js
index 2fa0d34..8cbdebb 100644
--- a/WebCore/inspector/front-end/Panel.js
+++ b/WebCore/inspector/front-end/Panel.js
@@ -116,7 +116,7 @@ WebInspector.Panel.prototype = {
document.getElementById("main-panels").appendChild(this.element);
},
- searchCanceled: function(startingNewSearch)
+ searchCanceled: function()
{
if (this._searchResults) {
for (var i = 0; i < this._searchResults.length; ++i) {
@@ -238,11 +238,9 @@ WebInspector.Panel.prototype = {
var currentView = this._searchResults[this._currentSearchResultIndex];
if (currentView.showingLastSearchResult()) {
- if (this.searchIteratesOverViews()) {
- if (++this._currentSearchResultIndex >= this._searchResults.length)
- this._currentSearchResultIndex = 0;
- currentView = this._searchResults[this._currentSearchResultIndex];
- }
+ if (++this._currentSearchResultIndex >= this._searchResults.length)
+ this._currentSearchResultIndex = 0;
+ currentView = this._searchResults[this._currentSearchResultIndex];
showFirstResult = true;
}
@@ -273,11 +271,9 @@ WebInspector.Panel.prototype = {
var currentView = this._searchResults[this._currentSearchResultIndex];
if (currentView.showingFirstSearchResult()) {
- if (this.searchIteratesOverViews()) {
- if (--this._currentSearchResultIndex < 0)
- this._currentSearchResultIndex = (this._searchResults.length - 1);
- currentView = this._searchResults[this._currentSearchResultIndex];
- }
+ if (--this._currentSearchResultIndex < 0)
+ this._currentSearchResultIndex = (this._searchResults.length - 1);
+ currentView = this._searchResults[this._currentSearchResultIndex];
showLastResult = true;
}
@@ -409,11 +405,6 @@ WebInspector.Panel.prototype = {
return false;
},
- searchIteratesOverViews: function()
- {
- return false;
- },
-
elementsToRestoreScrollPositionsFor: function()
{
return [];
diff --git a/WebCore/inspector/front-end/ProfilesPanel.js b/WebCore/inspector/front-end/ProfilesPanel.js
index e5877d9..e18274c 100644
--- a/WebCore/inspector/front-end/ProfilesPanel.js
+++ b/WebCore/inspector/front-end/ProfilesPanel.js
@@ -158,26 +158,20 @@ WebInspector.ProfilesPanel.prototype = {
show: function()
{
WebInspector.Panel.prototype.show.call(this);
- if (this._shouldPopulateProfiles)
+ if (!this._profilesWereRequested)
this._populateProfiles();
},
- populateInterface: function()
- {
- this._reset();
- if (this.visible)
- this._populateProfiles();
- else
- this._shouldPopulateProfiles = true;
- },
-
profilerWasEnabled: function()
{
if (this._profilerEnabled)
return;
this._profilerEnabled = true;
- this.populateInterface();
+
+ this._reset();
+ if (this.visible)
+ this._populateProfiles();
},
profilerWasDisabled: function()
@@ -207,6 +201,7 @@ WebInspector.ProfilesPanel.prototype = {
this._profilesIdMap = {};
this._profileGroups = {};
this._profileGroupsForLinks = {}
+ this._profilesWereRequested = false;
this.sidebarTreeElement.removeStyleClass("some-expandable");
@@ -532,7 +527,7 @@ WebInspector.ProfilesPanel.prototype = {
var callId = WebInspector.Callback.wrap(populateCallback);
InspectorBackend.getProfileHeaders(callId);
- delete this._shouldPopulateProfiles;
+ this._profilesWereRequested = true;
},
updateMainViewWidth: function(width)
diff --git a/WebCore/inspector/front-end/ResourcesPanel.js b/WebCore/inspector/front-end/ResourcesPanel.js
index 01eefc7..ff0d1ab 100644
--- a/WebCore/inspector/front-end/ResourcesPanel.js
+++ b/WebCore/inspector/front-end/ResourcesPanel.js
@@ -769,11 +769,6 @@ WebInspector.ResourcesPanel.prototype = {
return this.items;
},
- searchIteratesOverViews: function()
- {
- return true;
- },
-
elementsToRestoreScrollPositionsFor: function()
{
return [ this.containerElement ];
diff --git a/WebCore/inspector/front-end/ScriptView.js b/WebCore/inspector/front-end/ScriptView.js
index 5598577..74dc30a 100644
--- a/WebCore/inspector/front-end/ScriptView.js
+++ b/WebCore/inspector/front-end/ScriptView.js
@@ -34,7 +34,7 @@ WebInspector.ScriptView = function(script)
this._frameNeedsSetup = true;
this._sourceFrameSetup = false;
var canEditScripts = WebInspector.panels.scripts.canEditScripts();
- this.sourceFrame = new WebInspector.SourceFrame(this.element, this._addBreakpoint.bind(this), this._removeBreakpoint.bind(this), canEditScripts ? this._editLine.bind(this) : null, this._continueToLine.bind(this));
+ this.sourceFrame = new WebInspector.SourceFrame(this.element, this._addBreakpoint.bind(this), canEditScripts ? this._editLine.bind(this) : null, this._continueToLine.bind(this));
}
WebInspector.ScriptView.prototype = {
@@ -129,7 +129,6 @@ WebInspector.ScriptView.prototype = {
showingFirstSearchResult: WebInspector.SourceView.prototype.showingFirstSearchResult,
showingLastSearchResult: WebInspector.SourceView.prototype.showingLastSearchResult,
_jumpToSearchResult: WebInspector.SourceView.prototype._jumpToSearchResult,
- _removeBreakpoint: WebInspector.SourceView.prototype._removeBreakpoint,
_editLine: WebInspector.SourceView.prototype._editLine,
resize: WebInspector.SourceView.prototype.resize
}
diff --git a/WebCore/inspector/front-end/ScriptsPanel.js b/WebCore/inspector/front-end/ScriptsPanel.js
index 8675f79..7521ea9 100644
--- a/WebCore/inspector/front-end/ScriptsPanel.js
+++ b/WebCore/inspector/front-end/ScriptsPanel.js
@@ -132,7 +132,9 @@ WebInspector.ScriptsPanel = function()
this.sidebarPanes.watchExpressions = new WebInspector.WatchExpressionsSidebarPane();
this.sidebarPanes.callstack = new WebInspector.CallStackSidebarPane();
this.sidebarPanes.scopechain = new WebInspector.ScopeChainSidebarPane();
- this.sidebarPanes.breakpoints = new WebInspector.BreakpointsSidebarPane();
+ this.sidebarPanes.jsBreakpoints = WebInspector.createJSBreakpointsSidebarPane();
+ if (Preferences.domBreakpointsEnabled)
+ this.sidebarPanes.domBreakpoints = WebInspector.createDOMBreakpointsSidebarPane();
this.sidebarPanes.workers = new WebInspector.WorkersSidebarPane();
for (var pane in this.sidebarPanes)
@@ -142,7 +144,9 @@ WebInspector.ScriptsPanel = function()
this.sidebarPanes.callstack.addEventListener("call frame selected", this._callFrameSelected, this);
this.sidebarPanes.scopechain.expanded = true;
- this.sidebarPanes.breakpoints.expanded = true;
+ this.sidebarPanes.jsBreakpoints.expanded = true;
+ if (Preferences.domBreakpointsEnabled)
+ this.sidebarPanes.domBreakpoints.expanded = true;
var panelEnablerHeading = WebInspector.UIString("You need to enable debugging before you can use the Scripts panel.");
var panelEnablerDisclaimer = WebInspector.UIString("Enabling debugging will make scripts run slower.");
@@ -171,7 +175,6 @@ WebInspector.ScriptsPanel = function()
this._debuggerEnabled = Preferences.debuggerAlwaysEnabled;
WebInspector.breakpointManager.addEventListener("breakpoint-added", this._breakpointAdded, this);
- WebInspector.breakpointManager.addEventListener("breakpoint-removed", this._breakpointRemoved, this);
this.reset();
}
@@ -227,11 +230,6 @@ WebInspector.ScriptsPanel.prototype = {
WebInspector.Panel.prototype.hide.call(this);
},
- get searchableViews()
- {
- return [ this.visibleView ];
- },
-
get breakpointsActivated()
{
return this.toggleBreakpointsButton.toggled;
@@ -312,26 +310,6 @@ WebInspector.ScriptsPanel.prototype = {
sourceFrame.addBreakpoint(breakpoint);
},
- _breakpointRemoved: function(event)
- {
- var breakpoint = event.data;
-
- var sourceFrame;
- if (breakpoint.url) {
- var resource = WebInspector.resourceURLMap[breakpoint.url];
- if (resource && resource.finished)
- sourceFrame = this._sourceFrameForScriptOrResource(resource);
- }
-
- if (breakpoint.sourceID && !sourceFrame) {
- var object = this._sourceIDMap[breakpoint.sourceID]
- sourceFrame = this._sourceFrameForScriptOrResource(object);
- }
-
- if (sourceFrame)
- sourceFrame.removeBreakpoint(breakpoint);
- },
-
canEditScripts: function()
{
return Preferences.canEditScriptSource;
@@ -345,7 +323,7 @@ WebInspector.ScriptsPanel.prototype = {
// Need to clear breakpoints and re-create them later when editing source.
var breakpoints = WebInspector.breakpointManager.breakpointsForSourceID(sourceID);
for (var i = 0; i < breakpoints.length; ++i)
- WebInspector.breakpointManager.removeBreakpoint(breakpoints[i]);
+ breakpoints[i].remove();
function mycallback(success, newBodyOrErrorMessage, callFrames)
{
@@ -494,7 +472,9 @@ WebInspector.ScriptsPanel.prototype = {
this.sidebarPanes.watchExpressions.refreshExpressions();
if (!preserveItems) {
- this.sidebarPanes.breakpoints.reset();
+ this.sidebarPanes.jsBreakpoints.reset();
+ if (Preferences.domBreakpointsEnabled)
+ this.sidebarPanes.domBreakpoints.reset();
this.sidebarPanes.workers.reset();
}
},
@@ -1029,6 +1009,74 @@ WebInspector.ScriptsPanel.prototype = {
section.addAlternateKeys([ shortcut1.name, shortcut2.name ], WebInspector.UIString("Step out"));
this.sidebarPanes.callstack.registerShortcuts(section);
+ },
+
+ searchCanceled: function()
+ {
+ WebInspector.updateSearchMatchesCount(0, this);
+
+ if (this._searchView)
+ this._searchView.searchCanceled();
+
+ delete this._searchView;
+ delete this._searchQuery;
+ },
+
+ performSearch: function(query)
+ {
+ if (!this.visibleView)
+ return;
+
+ // Call searchCanceled since it will reset everything we need before doing a new search.
+ this.searchCanceled();
+
+ this._searchView = this.visibleView;
+ this._searchQuery = query;
+
+ function finishedCallback(view, searchMatches)
+ {
+ if (!searchMatches)
+ return;
+
+ WebInspector.updateSearchMatchesCount(searchMatches, this);
+ view.jumpToFirstSearchResult();
+ }
+
+ this._searchView.performSearch(query, finishedCallback.bind(this));
+ },
+
+ jumpToNextSearchResult: function()
+ {
+ if (!this._searchView)
+ return;
+
+ if (this._searchView !== this.visibleView) {
+ this.performSearch(this._searchQuery);
+ return;
+ }
+
+ if (this._searchView.showingLastSearchResult())
+ this._searchView.jumpToFirstSearchResult();
+ else
+ this._searchView.jumpToNextSearchResult();
+ },
+
+ jumpToPreviousSearchResult: function()
+ {
+ if (!this._searchView)
+ return;
+
+ if (this._searchView !== this.visibleView) {
+ this.performSearch(this._searchQuery);
+ if (this._searchView)
+ this._searchView.jumpToLastSearchResult();
+ return;
+ }
+
+ if (this._searchView.showingFirstSearchResult())
+ this._searchView.jumpToLastSearchResult();
+ else
+ this._searchView.jumpToPreviousSearchResult();
}
}
diff --git a/WebCore/inspector/front-end/Section.js b/WebCore/inspector/front-end/Section.js
index 913d495..a186d43 100644
--- a/WebCore/inspector/front-end/Section.js
+++ b/WebCore/inspector/front-end/Section.js
@@ -82,21 +82,18 @@ WebInspector.Section.prototype = {
if (this._subtitle === x)
return;
this._subtitle = x;
- this.subtitleElement.setAttribute("data-uncopyable", x);
+ this.subtitleElement.textContent = x;
},
- get subtitleAsText()
- {
- var result = "";
- var data = this.subtitleElement.getAttribute("data-uncopyable");
- if (data)
- result += data;
- var child = this.subtitleElement.querySelector("[data-uncopyable]");
- if (child) {
- var linkData = child.getAttribute("data-uncopyable");
- if (linkData)
- result += linkData;
- }
+ get subtitleAsTextForTest()
+ {
+ var result = this.subtitleElement.textContent;
+ var child = this.subtitleElement.querySelector("[data-uncopyable]");
+ if (child) {
+ var linkData = child.getAttribute("data-uncopyable");
+ if (linkData)
+ result += linkData;
+ }
return result;
},
diff --git a/WebCore/inspector/front-end/Settings.js b/WebCore/inspector/front-end/Settings.js
index c84ba79..33a1b91 100644
--- a/WebCore/inspector/front-end/Settings.js
+++ b/WebCore/inspector/front-end/Settings.js
@@ -43,36 +43,48 @@ var Preferences = {
debuggerAlwaysEnabled: false,
profilerAlwaysEnabled: false,
auditsPanelEnabled: true,
- onlineDetectionEnabled: true
+ onlineDetectionEnabled: true,
+ domBreakpointsEnabled: false
}
-WebInspector.populateApplicationSettings = function(settingsString)
+WebInspector.Settings = function(sessionScope)
{
- WebInspector.applicationSettings._load(settingsString);
- WebInspector.applicationSettings.installSetting("eventListenersFilter", "event-listeners-filter", "all");
- WebInspector.applicationSettings.installSetting("colorFormat", "color-format", "hex");
- WebInspector.applicationSettings.installSetting("resourcesLargeRows", "resources-large-rows", true);
- WebInspector.applicationSettings.installSetting("watchExpressions", "watch-expressions", []);
- WebInspector.applicationSettings.installSetting("lastViewedScriptFile", "last-viewed-script-file");
- WebInspector.applicationSettings.installSetting("showInheritedComputedStyleProperties", "show-inherited-computed-style-properties", false);
- WebInspector.applicationSettings.installSetting("showUserAgentStyles", "show-user-agent-styles", true);
- WebInspector.applicationSettings.installSetting("resourceViewTab", "resource-view-tab", "content");
- WebInspector.applicationSettings.installSetting("consoleHistory", "console-history", []);
- WebInspector.applicationSettings.installSetting("resourcesSortOptions", "resources-sort-options", {timeOption: "responseTime", sizeOption: "transferSize"});
-
- WebInspector.applicationSettings.dispatchEventToListeners("loaded");
+ this._sessionScope = sessionScope;
+ this._store = {};
}
-WebInspector.populateSessionSettings = function(settingsString)
+WebInspector.Settings.initialize = function()
{
- WebInspector.sessionSettings._load(settingsString);
- WebInspector.sessionSettings.dispatchEventToListeners("loaded");
-}
+ WebInspector.applicationSettings = new WebInspector.Settings(false);
+ WebInspector.sessionSettings = new WebInspector.Settings(true);
-WebInspector.Settings = function(sessionScope)
-{
- this._sessionScope = sessionScope;
- this._store = {};
+ function populateApplicationSettings(settingsString)
+ {
+ WebInspector.applicationSettings._load(settingsString);
+ WebInspector.applicationSettings.installSetting("eventListenersFilter", "event-listeners-filter", "all");
+ WebInspector.applicationSettings.installSetting("colorFormat", "color-format", "hex");
+ WebInspector.applicationSettings.installSetting("resourcesLargeRows", "resources-large-rows", true);
+ WebInspector.applicationSettings.installSetting("watchExpressions", "watch-expressions", []);
+ WebInspector.applicationSettings.installSetting("lastViewedScriptFile", "last-viewed-script-file");
+ WebInspector.applicationSettings.installSetting("showInheritedComputedStyleProperties", "show-inherited-computed-style-properties", false);
+ WebInspector.applicationSettings.installSetting("showUserAgentStyles", "show-user-agent-styles", true);
+ WebInspector.applicationSettings.installSetting("resourceViewTab", "resource-view-tab", "content");
+ WebInspector.applicationSettings.installSetting("consoleHistory", "console-history", []);
+ WebInspector.applicationSettings.installSetting("resourcesSortOptions", "resources-sort-options", {timeOption: "responseTime", sizeOption: "transferSize"});
+
+ WebInspector.applicationSettings.dispatchEventToListeners("loaded");
+ }
+
+ function populateSessionSettings(settingsString)
+ {
+ WebInspector.sessionSettings._load(settingsString);
+ WebInspector.sessionSettings.dispatchEventToListeners("loaded");
+ }
+
+ InspectorBackend.getSettings(WebInspector.Callback.wrap(function(settings) {
+ populateApplicationSettings(settings.application);
+ populateSessionSettings(settings.session);
+ }));
}
WebInspector.Settings.prototype = {
diff --git a/WebCore/inspector/front-end/SourceCSSTokenizer.js b/WebCore/inspector/front-end/SourceCSSTokenizer.js
index 2179982..82149e0 100644
--- a/WebCore/inspector/front-end/SourceCSSTokenizer.js
+++ b/WebCore/inspector/front-end/SourceCSSTokenizer.js
@@ -45,60 +45,8 @@ WebInspector.SourceCSSTokenizer = function()
{
WebInspector.SourceTokenizer.call(this);
- this._propertyKeywords = [
- "background", "background-attachment", "background-clip", "background-color", "background-image",
- "background-origin", "background-position", "background-position-x", "background-position-y",
- "background-repeat", "background-repeat-x", "background-repeat-y", "background-size", "border",
- "border-bottom", "border-bottom-color", "border-bottom-left-radius", "border-bottom-right-radius",
- "border-bottom-style", "border-bottom-width", "border-collapse", "border-color", "border-left",
- "border-left-color", "border-left-style", "border-left-width", "border-radius", "border-right",
- "border-right-color", "border-right-style", "border-right-width", "border-spacing", "border-style",
- "border-top", "border-top-color", "border-top-left-radius", "border-top-right-radius", "border-top-style",
- "border-top-width", "border-width", "bottom", "caption-side", "clear", "clip", "color", "content",
- "counter-increment", "counter-reset", "cursor", "direction", "display", "empty-cells", "float",
- "font", "font-family", "font-size", "font-stretch", "font-style", "font-variant", "font-weight",
- "height", "left", "letter-spacing", "line-height", "list-style", "list-style-image", "list-style-position",
- "list-style-type", "margin", "margin-bottom", "margin-left", "margin-right", "margin-top", "max-height",
- "max-width", "min-height", "min-width", "opacity", "orphans", "outline", "outline-color", "outline-offset",
- "outline-style", "outline-width", "overflow", "overflow-x", "overflow-y", "padding", "padding-bottom",
- "padding-left", "padding-right", "padding-top", "page", "page-break-after", "page-break-before",
- "page-break-inside", "pointer-events", "position", "quotes", "resize", "right", "size", "src",
- "table-layout", "text-align", "text-decoration", "text-indent", "text-line-through", "text-line-through-color",
- "text-line-through-mode", "text-line-through-style", "text-line-through-width", "text-overflow", "text-overline",
- "text-overline-color", "text-overline-mode", "text-overline-style", "text-overline-width", "text-rendering",
- "text-shadow", "text-transform", "text-underline", "text-underline-color", "text-underline-mode",
- "text-underline-style", "text-underline-width", "top", "unicode-bidi", "unicode-range", "vertical-align",
- "visibility", "white-space", "widows", "width", "word-break", "word-spacing", "word-wrap", "z-index", "zoom",
- "-webkit-animation", "-webkit-animation-delay", "-webkit-animation-direction", "-webkit-animation-duration",
- "-webkit-animation-iteration-count", "-webkit-animation-name", "-webkit-animation-play-state",
- "-webkit-animation-timing-function", "-webkit-appearance", "-webkit-backface-visibility",
- "-webkit-background-clip", "-webkit-background-composite", "-webkit-background-origin", "-webkit-background-size",
- "-webkit-binding", "-webkit-border-end", "-webkit-border-end-color", "-webkit-border-end-style", "-webkit-border-end-width",
- "-webkit-border-fit", "-webkit-border-horizontal-spacing", "-webkit-border-image",
- "-webkit-border-radius", "-webkit-border-start", "-webkit-border-start-color", "-webkit-border-start-style",
- "-webkit-border-start-width","-webkit-border-vertical-spacing", "-webkit-box-align", "-webkit-box-direction",
- "-webkit-box-flex", "-webkit-box-flex-group", "-webkit-box-lines", "-webkit-box-ordinal-group",
- "-webkit-box-orient", "-webkit-box-pack", "-webkit-box-reflect", "-webkit-box-shadow", "-webkit-box-sizing",
- "-webkit-column-break-after", "-webkit-column-break-before", "-webkit-column-break-inside", "-webkit-column-count",
- "-webkit-column-gap", "-webkit-column-rule", "-webkit-column-rule-color", "-webkit-column-rule-style",
- "-webkit-column-rule-width", "-webkit-column-width", "-webkit-columns", "-webkit-font-size-delta",
- "-webkit-font-smoothing", "-webkit-highlight", "-webkit-line-break", "-webkit-line-clamp",
- "-webkit-margin-bottom-collapse", "-webkit-margin-collapse", "-webkit-margin-end", "-webkit-margin-start", "-webkit-margin-top-collapse",
- "-webkit-marquee", "-webkit-marquee-direction", "-webkit-marquee-increment", "-webkit-marquee-repetition",
- "-webkit-marquee-speed", "-webkit-marquee-style", "-webkit-mask", "-webkit-mask-attachment",
- "-webkit-mask-box-image", "-webkit-mask-clip", "-webkit-mask-composite", "-webkit-mask-image",
- "-webkit-mask-origin", "-webkit-mask-position", "-webkit-mask-position-x", "-webkit-mask-position-y",
- "-webkit-mask-repeat", "-webkit-mask-repeat-x", "-webkit-mask-repeat-y", "-webkit-mask-size",
- "-webkit-match-nearest-mail-blockquote-color", "-webkit-nbsp-mode", "-webkit-padding-end", "-webkit-padding-start",
- "-webkit-perspective", "-webkit-perspective-origin", "-webkit-perspective-origin-x", "-webkit-perspective-origin-y",
- "-webkit-rtl-ordering", "-webkit-text-decorations-in-effect", "-webkit-text-fill-color", "-webkit-text-security",
- "-webkit-text-size-adjust", "-webkit-text-stroke", "-webkit-text-stroke-color", "-webkit-text-stroke-width",
- "-webkit-transform", "-webkit-transform-origin", "-webkit-transform-origin-x", "-webkit-transform-origin-y",
- "-webkit-transform-origin-z", "-webkit-transform-style", "-webkit-transition", "-webkit-transition-delay",
- "-webkit-transition-duration", "-webkit-transition-property", "-webkit-transition-timing-function",
- "-webkit-user-drag", "-webkit-user-modify", "-webkit-user-select", "-webkit-variable-declaration-block"
- ].keySet();
-
+ this._propertyKeywords = WebInspector.CSSCompletions.keySet();
+
this._valueKeywords = [
"above", "absolute", "activeborder", "activecaption", "afar", "after-white-space", "ahead", "alias", "all", "all-scroll",
"alternate", "always","amharic", "amharic-abegede", "antialiased", "appworkspace", "aqua", "arabic-indic", "armenian",
diff --git a/WebCore/inspector/front-end/SourceCSSTokenizer.re2js b/WebCore/inspector/front-end/SourceCSSTokenizer.re2js
index 6ba9f60..b4d3eef 100644
--- a/WebCore/inspector/front-end/SourceCSSTokenizer.re2js
+++ b/WebCore/inspector/front-end/SourceCSSTokenizer.re2js
@@ -44,58 +44,8 @@ WebInspector.SourceCSSTokenizer = function()
{
WebInspector.SourceTokenizer.call(this);
- this._propertyKeywords = [
- "background", "background-attachment", "background-clip", "background-color", "background-image",
- "background-origin", "background-position", "background-position-x", "background-position-y",
- "background-repeat", "background-repeat-x", "background-repeat-y", "background-size", "border",
- "border-bottom", "border-bottom-color", "border-bottom-left-radius", "border-bottom-right-radius",
- "border-bottom-style", "border-bottom-width", "border-collapse", "border-color", "border-left",
- "border-left-color", "border-left-style", "border-left-width", "border-radius", "border-right",
- "border-right-color", "border-right-style", "border-right-width", "border-spacing", "border-style",
- "border-top", "border-top-color", "border-top-left-radius", "border-top-right-radius", "border-top-style",
- "border-top-width", "border-width", "bottom", "caption-side", "clear", "clip", "color", "content",
- "counter-increment", "counter-reset", "cursor", "direction", "display", "empty-cells", "float",
- "font", "font-family", "font-size", "font-stretch", "font-style", "font-variant", "font-weight",
- "height", "left", "letter-spacing", "line-height", "list-style", "list-style-image", "list-style-position",
- "list-style-type", "margin", "margin-bottom", "margin-left", "margin-right", "margin-top", "max-height",
- "max-width", "min-height", "min-width", "opacity", "orphans", "outline", "outline-color", "outline-offset",
- "outline-style", "outline-width", "overflow", "overflow-x", "overflow-y", "padding", "padding-bottom",
- "padding-left", "padding-right", "padding-top", "page", "page-break-after", "page-break-before",
- "page-break-inside", "pointer-events", "position", "quotes", "resize", "right", "size", "src",
- "table-layout", "text-align", "text-decoration", "text-indent", "text-line-through", "text-line-through-color",
- "text-line-through-mode", "text-line-through-style", "text-line-through-width", "text-overflow", "text-overline",
- "text-overline-color", "text-overline-mode", "text-overline-style", "text-overline-width", "text-rendering",
- "text-shadow", "text-transform", "text-underline", "text-underline-color", "text-underline-mode",
- "text-underline-style", "text-underline-width", "top", "unicode-bidi", "unicode-range", "vertical-align",
- "visibility", "white-space", "widows", "width", "word-break", "word-spacing", "word-wrap", "z-index", "zoom",
- "-webkit-animation", "-webkit-animation-delay", "-webkit-animation-direction", "-webkit-animation-duration",
- "-webkit-animation-iteration-count", "-webkit-animation-name", "-webkit-animation-play-state",
- "-webkit-animation-timing-function", "-webkit-appearance", "-webkit-backface-visibility",
- "-webkit-background-clip", "-webkit-background-composite", "-webkit-background-origin", "-webkit-background-size",
- "-webkit-binding", "-webkit-border-fit", "-webkit-border-horizontal-spacing", "-webkit-border-image",
- "-webkit-border-radius", "-webkit-border-vertical-spacing", "-webkit-box-align", "-webkit-box-direction",
- "-webkit-box-flex", "-webkit-box-flex-group", "-webkit-box-lines", "-webkit-box-ordinal-group",
- "-webkit-box-orient", "-webkit-box-pack", "-webkit-box-reflect", "-webkit-box-shadow", "-webkit-box-sizing",
- "-webkit-column-break-after", "-webkit-column-break-before", "-webkit-column-break-inside", "-webkit-column-count",
- "-webkit-column-gap", "-webkit-column-rule", "-webkit-column-rule-color", "-webkit-column-rule-style",
- "-webkit-column-rule-width", "-webkit-column-width", "-webkit-columns", "-webkit-font-size-delta",
- "-webkit-font-smoothing", "-webkit-highlight", "-webkit-line-break", "-webkit-line-clamp",
- "-webkit-margin-bottom-collapse", "-webkit-margin-collapse", "-webkit-margin-start", "-webkit-margin-top-collapse",
- "-webkit-marquee", "-webkit-marquee-direction", "-webkit-marquee-increment", "-webkit-marquee-repetition",
- "-webkit-marquee-speed", "-webkit-marquee-style", "-webkit-mask", "-webkit-mask-attachment",
- "-webkit-mask-box-image", "-webkit-mask-clip", "-webkit-mask-composite", "-webkit-mask-image",
- "-webkit-mask-origin", "-webkit-mask-position", "-webkit-mask-position-x", "-webkit-mask-position-y",
- "-webkit-mask-repeat", "-webkit-mask-repeat-x", "-webkit-mask-repeat-y", "-webkit-mask-size",
- "-webkit-match-nearest-mail-blockquote-color", "-webkit-nbsp-mode", "-webkit-padding-start",
- "-webkit-perspective", "-webkit-perspective-origin", "-webkit-perspective-origin-x", "-webkit-perspective-origin-y",
- "-webkit-rtl-ordering", "-webkit-text-decorations-in-effect", "-webkit-text-fill-color", "-webkit-text-security",
- "-webkit-text-size-adjust", "-webkit-text-stroke", "-webkit-text-stroke-color", "-webkit-text-stroke-width",
- "-webkit-transform", "-webkit-transform-origin", "-webkit-transform-origin-x", "-webkit-transform-origin-y",
- "-webkit-transform-origin-z", "-webkit-transform-style", "-webkit-transition", "-webkit-transition-delay",
- "-webkit-transition-duration", "-webkit-transition-property", "-webkit-transition-timing-function",
- "-webkit-user-drag", "-webkit-user-modify", "-webkit-user-select", "-webkit-variable-declaration-block"
- ].keySet();
-
+ this._propertyKeywords = WebInspector.CSSCompletions.keySet();
+
this._valueKeywords = [
"above", "absolute", "activeborder", "activecaption", "afar", "after-white-space", "ahead", "alias", "all", "all-scroll",
"alternate", "always","amharic", "amharic-abegede", "antialiased", "appworkspace", "aqua", "arabic-indic", "armenian",
diff --git a/WebCore/inspector/front-end/SourceFrame.js b/WebCore/inspector/front-end/SourceFrame.js
index 01a8ec2..16b8e8d 100644
--- a/WebCore/inspector/front-end/SourceFrame.js
+++ b/WebCore/inspector/front-end/SourceFrame.js
@@ -28,7 +28,7 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-WebInspector.SourceFrame = function(parentElement, addBreakpointDelegate, removeBreakpointDelegate, editDelegate, continueToHereDelegate)
+WebInspector.SourceFrame = function(parentElement, addBreakpointDelegate, editDelegate, continueToHereDelegate)
{
this._parentElement = parentElement;
@@ -44,7 +44,6 @@ WebInspector.SourceFrame = function(parentElement, addBreakpointDelegate, remove
this._continueToHereDelegate = continueToHereDelegate;
this._addBreakpointDelegate = addBreakpointDelegate;
- this._removeBreakpointDelegate = removeBreakpointDelegate;
this._editDelegate = editDelegate;
this._popoverObjectGroup = "popover";
}
@@ -55,7 +54,7 @@ WebInspector.SourceFrame.prototype = {
{
this._visible = visible;
this._createViewerIfNeeded();
-
+
if (visible) {
if (this._textViewer && this._scrollTop)
this._textViewer.element.scrollTop = this._scrollTop;
@@ -99,19 +98,16 @@ WebInspector.SourceFrame.prototype = {
addBreakpoint: function(breakpoint)
{
this.breakpoints.push(breakpoint);
- breakpoint.addEventListener("enabled", this._breakpointChanged, this);
- breakpoint.addEventListener("disabled", this._breakpointChanged, this);
- breakpoint.addEventListener("condition-changed", this._breakpointChanged, this);
+ breakpoint.addEventListener("removed", this._breakpointRemoved, this);
if (this._textViewer)
this._addBreakpointToSource(breakpoint);
},
- removeBreakpoint: function(breakpoint)
+ _breakpointRemoved: function(event)
{
+ var breakpoint = event.target;
+
this.breakpoints.remove(breakpoint);
- breakpoint.removeEventListener("enabled", null, this);
- breakpoint.removeEventListener("disabled", null, this);
- breakpoint.removeEventListener("condition-changed", null, this);
if (this._textViewer)
this._removeBreakpointFromSource(breakpoint);
},
@@ -384,6 +380,9 @@ WebInspector.SourceFrame.prototype = {
_addBreakpointToSource: function(breakpoint)
{
+ breakpoint.addEventListener("enable-changed", this._breakpointChanged, this);
+ breakpoint.addEventListener("condition-changed", this._breakpointChanged, this);
+
var lineNumber = breakpoint.line - 1;
if (lineNumber >= this._textModel.linesCount)
return;
@@ -402,6 +401,9 @@ WebInspector.SourceFrame.prototype = {
_removeBreakpointFromSource: function(breakpoint)
{
+ breakpoint.removeEventListener("enable-changed", null, this);
+ breakpoint.removeEventListener("condition-changed", null, this);
+
var lineNumber = breakpoint.line - 1;
this._textViewer.beginUpdates();
this._textModel.removeAttribute(lineNumber, "breakpoint");
@@ -431,7 +433,7 @@ WebInspector.SourceFrame.prototype = {
// This row doesn't have a breakpoint: We want to show Add Breakpoint and Add and Edit Breakpoint.
contextMenu.appendItem(WebInspector.UIString("Add Breakpoint"), this._addBreakpointDelegate.bind(this, lineNumber + 1));
- function addConditionalBreakpoint()
+ function addConditionalBreakpoint()
{
this._addBreakpointDelegate(lineNumber + 1);
var breakpoint = this._textModel.getAttribute(lineNumber, "breakpoint");
@@ -442,7 +444,7 @@ WebInspector.SourceFrame.prototype = {
contextMenu.appendItem(WebInspector.UIString("Add Conditional Breakpoint…"), addConditionalBreakpoint.bind(this));
} else {
// This row has a breakpoint, we want to show edit and remove breakpoint, and either disable or enable.
- contextMenu.appendItem(WebInspector.UIString("Remove Breakpoint"), this._removeBreakpointDelegate.bind(this, breakpoint));
+ contextMenu.appendItem(WebInspector.UIString("Remove Breakpoint"), breakpoint.remove.bind(breakpoint));
contextMenu.appendItem(WebInspector.UIString("Edit Breakpoint…"), this._editBreakpointCondition.bind(this, breakpoint));
if (breakpoint.enabled)
contextMenu.appendItem(WebInspector.UIString("Disable Breakpoint"), function() { breakpoint.enabled = false; });
@@ -475,7 +477,7 @@ WebInspector.SourceFrame.prototype = {
if (event.shiftKey)
breakpoint.enabled = !breakpoint.enabled;
else
- this._removeBreakpointDelegate(breakpoint);
+ breakpoint.remove();
} else
this._addBreakpointDelegate(lineNumber + 1);
event.preventDefault();
diff --git a/WebCore/inspector/front-end/SourceView.js b/WebCore/inspector/front-end/SourceView.js
index 4d03ecd..240dca1 100644
--- a/WebCore/inspector/front-end/SourceView.js
+++ b/WebCore/inspector/front-end/SourceView.js
@@ -33,7 +33,7 @@ WebInspector.SourceView = function(resource)
this.element.addStyleClass("source");
var canEditScripts = WebInspector.panels.scripts && WebInspector.panels.scripts.canEditScripts() && resource.type === WebInspector.Resource.Type.Script;
- this.sourceFrame = new WebInspector.SourceFrame(this.contentElement, this._addBreakpoint.bind(this), this._removeBreakpoint.bind(this), canEditScripts ? this._editLine.bind(this) : null, this._continueToLine.bind(this));
+ this.sourceFrame = new WebInspector.SourceFrame(this.contentElement, this._addBreakpoint.bind(this), canEditScripts ? this._editLine.bind(this) : null, this._continueToLine.bind(this));
resource.addEventListener("finished", this._resourceLoadingFinished, this);
this._frameNeedsSetup = true;
}
@@ -132,11 +132,6 @@ WebInspector.SourceView.prototype = {
WebInspector.panels.scripts.toggleBreakpointsClicked();
},
- _removeBreakpoint: function(breakpoint)
- {
- WebInspector.breakpointManager.removeBreakpoint(breakpoint);
- },
-
_editLine: function(line, newContent, cancelEditingCallback)
{
var lines = [];
@@ -213,7 +208,7 @@ WebInspector.SourceView.prototype = {
this.localContentElement = document.createElement("div");
this.localContentElement.className = "resource-view-content";
this.tabbedPane.appendTab("local", WebInspector.UIString("Local"), this.localContentElement, this.selectLocalContentTab.bind(this));
- this.localSourceFrame = new WebInspector.SourceFrame(this.localContentElement, this._addBreakpoint.bind(this), this._removeBreakpoint.bind(this), null, this._continueToLine.bind(this));
+ this.localSourceFrame = new WebInspector.SourceFrame(this.localContentElement, this._addBreakpoint.bind(this), null, this._continueToLine.bind(this));
}
this.localSourceFrame.setContent(mimeType, content, "");
},
diff --git a/WebCore/inspector/front-end/StylesSidebarPane.js b/WebCore/inspector/front-end/StylesSidebarPane.js
index 5f5a5ad..1dddde7 100644
--- a/WebCore/inspector/front-end/StylesSidebarPane.js
+++ b/WebCore/inspector/front-end/StylesSidebarPane.js
@@ -143,7 +143,7 @@ WebInspector.StylesSidebarPane.prototype = {
{
if (computedStyle)
this._refreshUpdate(node, computedStyle, editedSection);
- };
+ }
if (refresh)
WebInspector.cssModel.getComputedStyleAsync(node.id, computedStyleCallback.bind(this));
@@ -160,17 +160,23 @@ WebInspector.StylesSidebarPane.prototype = {
this._markUsedProperties(styleRules, usedProperties, disabledComputedProperties);
this._refreshSectionsForStyleRules(styleRules, usedProperties, disabledComputedProperties, editedSection);
}
+ // Trace the computed style.
+ this.sections[0][0].rebuildComputedTrace(this.sections[0]);
},
_rebuildUpdate: function(node, styles)
{
this.bodyElement.removeChildren();
this._computedStylePane.bodyElement.removeChildren();
+
var styleRules = this._rebuildStyleRules(node, styles);
var usedProperties = {};
var disabledComputedProperties = {};
this._markUsedProperties(styleRules, usedProperties, disabledComputedProperties);
this.sections[0] = this._rebuildSectionsForStyleRules(styleRules, usedProperties, disabledComputedProperties, 0);
+ var anchorElement = this.sections[0].inheritedPropertiesSeparatorElement;
+ // Trace the computed style.
+ this.sections[0][0].rebuildComputedTrace(this.sections[0]);
for (var i = 0; i < styles.pseudoElements.length; ++i) {
var pseudoElementCSSRules = styles.pseudoElements[i];
@@ -189,7 +195,7 @@ WebInspector.StylesSidebarPane.prototype = {
usedProperties = {};
disabledComputedProperties = {};
this._markUsedProperties(styleRules, usedProperties, disabledComputedProperties);
- this.sections[pseudoId] = this._rebuildSectionsForStyleRules(styleRules, usedProperties, disabledComputedProperties, pseudoId);
+ this.sections[pseudoId] = this._rebuildSectionsForStyleRules(styleRules, usedProperties, disabledComputedProperties, pseudoId, anchorElement);
}
},
@@ -221,7 +227,6 @@ WebInspector.StylesSidebarPane.prototype = {
var styleAttributes = {};
for (var name in styles.styleAttributes) {
var attrStyle = { style: new WebInspector.CSSStyleDeclaration(styles.styleAttributes[name]), editable: false };
- attrStyle.subtitle = WebInspector.UIString("element’s “%s” attribute", name);
attrStyle.selectorText = WebInspector.panels.elements.treeOutline.nodeNameToCorrectCase(node.nodeName) + "[" + name;
if (node.getAttribute(name))
attrStyle.selectorText += "=" + node.getAttribute(name);
@@ -232,7 +237,6 @@ WebInspector.StylesSidebarPane.prototype = {
// Show element's Style Attributes
if (styles.inlineStyle && node.nodeType === Node.ELEMENT_NODE) {
var inlineStyle = { selectorText: "element.style", style: new WebInspector.CSSStyleDeclaration(styles.inlineStyle), isAttribute: true };
- inlineStyle.subtitle = WebInspector.UIString("element’s “%s” attribute", "style");
styleRules.push(inlineStyle);
}
@@ -244,17 +248,6 @@ WebInspector.StylesSidebarPane.prototype = {
styleRules.push({ style: rule.style, selectorText: rule.selectorText, parentStyleSheet: rule.parentStyleSheet, rule: rule });
}
- // Collect used properties first in order to identify inherited ones.
- var userPropertyNames = {};
- for (var i = 0; i < styleRules.length; ++i) {
- var styleRule = styleRules[i];
- if (styleRule.computedStyle || styleRule.isStyleSeparator)
- continue;
- var style = styleRule.style;
- for (var j = 0; j < style.length; ++j)
- userPropertyNames[style[j]] = true;
- }
-
// Walk the node structure and identify styles with inherited properties.
var parentStyles = styles.parent;
var parentNode = node.parentNode;
@@ -271,7 +264,6 @@ WebInspector.StylesSidebarPane.prototype = {
if (parentStyles.inlineStyle) {
if (this._containsInherited(parentStyles.inlineStyle)) {
var inlineStyle = { selectorText: WebInspector.UIString("Style Attribute"), style: new WebInspector.CSSStyleDeclaration(parentStyles.inlineStyle), isAttribute: true, isInherited: true };
- inlineStyle.subtitle = WebInspector.UIString("element’s “%s” attribute", "style");
if (!separatorInserted) {
insertInheritedNodeSeparator(parentNode);
separatorInserted = true;
@@ -395,14 +387,18 @@ WebInspector.StylesSidebarPane.prototype = {
for (var i = 0; i < styleRules.length; ++i) {
var styleRule = styleRules[i];
var section = styleRule.section;
- if (styleRule.computedStyle)
- section.disabledComputedProperties = disabledComputedProperties;
- section._usedProperties = (styleRule.usedProperties || usedProperties);
- section.update((section === editedSection) || styleRule.computedStyle);
+ if (styleRule.computedStyle) {
+ section._disabledComputedProperties = disabledComputedProperties;
+ section._usedProperties = usedProperties;
+ section.update();
+ } else {
+ section._usedProperties = styleRule.usedProperties;
+ section.update(section === editedSection);
+ }
}
},
- _rebuildSectionsForStyleRules: function(styleRules, usedProperties, disabledComputedProperties, pseudoId)
+ _rebuildSectionsForStyleRules: function(styleRules, usedProperties, disabledComputedProperties, pseudoId, anchorElement)
{
// Make a property section for each style rule.
var sections = [];
@@ -416,6 +412,8 @@ WebInspector.StylesSidebarPane.prototype = {
var link = WebInspector.panels.elements.linkifyNodeReference(styleRule.node);
separatorElement.appendChild(document.createTextNode(WebInspector.UIString("Inherited from") + " "));
separatorElement.appendChild(link);
+ if (!sections.inheritedPropertiesSeparatorElement)
+ sections.inheritedPropertiesSeparatorElement = separatorElement;
} else if ("pseudoId" in styleRule) {
var pseudoName = WebInspector.StylesSidebarPane.PseudoIdNames[styleRule.pseudoId];
if (pseudoName)
@@ -424,7 +422,7 @@ WebInspector.StylesSidebarPane.prototype = {
separatorElement.textContent = WebInspector.UIString("Pseudo element");
} else
separatorElement.textContent = styleRule.text;
- this.bodyElement.appendChild(separatorElement);
+ this.bodyElement.insertBefore(separatorElement, anchorElement);
lastWasSeparator = true;
continue;
}
@@ -435,9 +433,10 @@ WebInspector.StylesSidebarPane.prototype = {
if (typeof editable === "undefined")
editable = true;
- var section = new WebInspector.StylePropertiesSection(styleRule, styleRule.subtitle, styleRule.computedStyle, (styleRule.usedProperties || usedProperties), editable, styleRule.isInherited, lastWasSeparator);
if (computedStyle)
- section.disabledComputedProperties = disabledComputedProperties;
+ var section = new WebInspector.ComputedStylePropertiesSection(styleRule, usedProperties, disabledComputedProperties, styleRules);
+ else
+ var section = new WebInspector.StylePropertiesSection(styleRule, editable, styleRule.isInherited, lastWasSeparator);
section.pane = this;
section.expanded = true;
@@ -445,7 +444,7 @@ WebInspector.StylesSidebarPane.prototype = {
this._computedStylePane.bodyElement.appendChild(section.element);
lastWasSeparator = true;
} else {
- this.bodyElement.appendChild(section.element);
+ this.bodyElement.insertBefore(section.element, anchorElement);
lastWasSeparator = false;
}
sections.push(section);
@@ -603,7 +602,7 @@ WebInspector.ComputedStyleSidebarPane = function()
WebInspector.ComputedStyleSidebarPane.prototype.__proto__ = WebInspector.SidebarPane.prototype;
-WebInspector.StylePropertiesSection = function(styleRule, subtitle, computedStyle, usedProperties, editable, isInherited, isFirstSection)
+WebInspector.StylePropertiesSection = function(styleRule, editable, isInherited, isFirstSection)
{
WebInspector.PropertiesSection.call(this, "");
this.element.className = "styles-section monospace" + (isFirstSection ? " first-styles-section" : "");
@@ -612,23 +611,20 @@ WebInspector.StylePropertiesSection = function(styleRule, subtitle, computedStyl
this._selectorElement.textContent = styleRule.selectorText;
this.titleElement.appendChild(this._selectorElement);
- if (!computedStyle) {
- var openBrace = document.createElement("span");
- openBrace.textContent = " {";
- this.titleElement.appendChild(openBrace);
+ var openBrace = document.createElement("span");
+ openBrace.textContent = " {";
+ this.titleElement.appendChild(openBrace);
- var closeBrace = document.createElement("div");
- closeBrace.textContent = "}";
- this.element.appendChild(closeBrace);
- }
+ var closeBrace = document.createElement("div");
+ closeBrace.textContent = "}";
+ this.element.appendChild(closeBrace);
this._selectorElement.addEventListener("dblclick", this._handleSelectorDoubleClick.bind(this), false);
this.element.addEventListener("dblclick", this._handleEmptySpaceDoubleClick.bind(this), false);
this.styleRule = styleRule;
this.rule = this.styleRule.rule;
- this.computedStyle = computedStyle;
- this.editable = (editable && !computedStyle);
+ this.editable = editable;
this.isInherited = isInherited;
// Prevent editing the user agent and user rules.
@@ -639,58 +635,45 @@ WebInspector.StylePropertiesSection = function(styleRule, subtitle, computedStyl
if (isUserAgent || isUser)
this.editable = false;
- this._usedProperties = usedProperties;
+ this._usedProperties = styleRule.usedProperties;
if (this.rule)
this.titleElement.addStyleClass("styles-selector");
- if (computedStyle) {
- this.element.addStyleClass("computed-style");
- this.headerElement.addStyleClass("hidden");
- } else {
- if (!subtitle) {
- function linkifyUncopyable(url, line)
- {
- var link = WebInspector.linkifyResourceAsNode(url, "resources", line + 1);
- link.setAttribute("data-uncopyable", link.textContent);
- link.textContent = "";
- return link;
- }
-
- if (this.styleRule.parentStyleSheet && this.styleRule.parentStyleSheet.href)
- this.subtitleElement.appendChild(linkifyUncopyable(this.styleRule.parentStyleSheet.href, this.rule.sourceLine));
- else if (isUserAgent)
- subtitle = WebInspector.UIString("user agent stylesheet");
- else if (isUser)
- subtitle = WebInspector.UIString("user stylesheet");
- else if (isViaInspector)
- subtitle = WebInspector.UIString("via inspector");
- else
- this.subtitleElement.appendChild(linkifyUncopyable(this.rule.documentURL, this.rule.sourceLine));
- }
- if (isInherited)
- this.element.addStyleClass("show-inherited"); // This one is related to inherited rules, not compted style.
- if (subtitle)
- this.subtitle = subtitle;
+ function linkifyUncopyable(url, line)
+ {
+ var link = WebInspector.linkifyResourceAsNode(url, "resources", line + 1);
+ link.setAttribute("data-uncopyable", link.textContent);
+ link.textContent = "";
+ return link;
}
+ var subtitle = "";
+ if (this.styleRule.parentStyleSheet && this.styleRule.parentStyleSheet.href)
+ this.subtitleElement.appendChild(linkifyUncopyable(this.styleRule.parentStyleSheet.href, this.rule.sourceLine));
+ else if (isUserAgent)
+ subtitle = WebInspector.UIString("user agent stylesheet");
+ else if (isUser)
+ subtitle = WebInspector.UIString("user stylesheet");
+ else if (isViaInspector)
+ subtitle = WebInspector.UIString("via inspector");
+ else if (this.rule && this.rule.documentURL)
+ this.subtitleElement.appendChild(linkifyUncopyable(this.rule.documentURL, this.rule.sourceLine));
+
+ if (isInherited)
+ this.element.addStyleClass("show-inherited"); // This one is related to inherited rules, not compted style.
+ if (subtitle)
+ this.subtitle = subtitle;
+
this.identifier = styleRule.selectorText;
if (this.subtitle)
this.identifier += ":" + this.subtitle;
+
+ if (!this.editable)
+ this.element.addStyleClass("read-only");
}
WebInspector.StylePropertiesSection.prototype = {
- get usedProperties()
- {
- return this._usedProperties || {};
- },
-
- set usedProperties(x)
- {
- this._usedProperties = x;
- this.update();
- },
-
collapse: function(dontRememberState)
{
// Overriding with empty body.
@@ -703,17 +686,12 @@ WebInspector.StylePropertiesSection.prototype = {
// Render truly inherited properties with black, i.e. return them as non-inherited.
return !(property in WebInspector.StylesSidebarPane.InheritedProperties);
}
-
- if (!this.computedStyle || !this._usedProperties || this.noAffect)
- return false;
- // These properties should always show for Computed Style.
- var alwaysShowComputedProperties = { "display": true, "height": true, "width": true };
- return !(property in this.usedProperties) && !(property in alwaysShowComputedProperties) && !(property in this.disabledComputedProperties);
+ return false;
},
isPropertyOverloaded: function(property, shorthand)
{
- if (this.computedStyle || !this._usedProperties || this.noAffect)
+ if (!this._usedProperties || this.noAffect)
return false;
if (this.isInherited && !(property in WebInspector.StylesSidebarPane.InheritedProperties)) {
@@ -721,7 +699,7 @@ WebInspector.StylePropertiesSection.prototype = {
return false;
}
- var used = (property in this.usedProperties);
+ var used = (property in this._usedProperties);
if (used || !shorthand)
return !used;
@@ -730,16 +708,23 @@ WebInspector.StylePropertiesSection.prototype = {
var longhandProperties = this.styleRule.style.getLonghandProperties(property);
for (var j = 0; j < longhandProperties.length; ++j) {
var individualProperty = longhandProperties[j];
- if (individualProperty in this.usedProperties)
+ if (individualProperty in this._usedProperties)
return false;
}
return true;
},
+ isPropertyDisabled: function(property)
+ {
+ if (!this.styleRule.style.__disabledPropertyValues)
+ return false;
+ return property in this.styleRule.style.__disabledPropertyValues;
+ },
+
update: function(full)
{
- if (full || this.computedStyle) {
+ if (full) {
this.propertiesTreeOutline.removeChildren();
this.populated = false;
} else {
@@ -749,7 +734,6 @@ WebInspector.StylePropertiesSection.prototype = {
child = child.traverseNextTreeElement(false, null, true);
}
}
-
this.afterUpdate();
},
@@ -768,21 +752,18 @@ WebInspector.StylePropertiesSection.prototype = {
var foundShorthands = {};
var disabledProperties = style.__disabledPropertyValues || {};
- var uniqueProperties = [];
+ this.uniqueProperties = [];
for (var i = 0; i < style.length; ++i)
- uniqueProperties.push(style[i]);
+ this.uniqueProperties.push(style[i]);
for (var name in disabledProperties)
- uniqueProperties.push(name);
+ this.uniqueProperties.push(name);
- uniqueProperties.sort();
+ this.uniqueProperties.sort();
- for (var i = 0; i < uniqueProperties.length; ++i) {
- var name = uniqueProperties[i];
+ for (var i = 0; i < this.uniqueProperties.length; ++i) {
+ var name = this.uniqueProperties[i];
var disabled = name in disabledProperties;
- if (!disabled && this.disabledComputedProperties && !(name in this.usedProperties) && name in this.disabledComputedProperties)
- disabled = true;
-
var shorthand = !disabled ? style.getPropertyShorthand(name) : null;
if (shorthand && shorthand in foundShorthands)
@@ -924,10 +905,102 @@ WebInspector.StylePropertiesSection.prototype = {
WebInspector.StylePropertiesSection.prototype.__proto__ = WebInspector.PropertiesSection.prototype;
-WebInspector.BlankStylePropertiesSection = function(defaultSelectorText)
+WebInspector.ComputedStylePropertiesSection = function(styleRule, usedProperties, disabledComputedProperties)
{
- WebInspector.StylePropertiesSection.call(this, {selectorText: defaultSelectorText, rule: {isViaInspector: true}}, "", false, {}, false);
+ WebInspector.PropertiesSection.call(this, "");
+ this.headerElement.addStyleClass("hidden");
+ this.element.className = "styles-section monospace first-styles-section read-only computed-style";
+ this.styleRule = styleRule;
+ this._usedProperties = usedProperties;
+ this._disabledComputedProperties = disabledComputedProperties;
+ this._alwaysShowComputedProperties = { "display": true, "height": true, "width": true };
+ this.computedStyle = true;
+ this._propertyTreeElements = {};
+ this._expandedPropertyNames = {};
+}
+
+WebInspector.ComputedStylePropertiesSection.prototype = {
+ collapse: function(dontRememberState)
+ {
+ // Overriding with empty body.
+ },
+
+ _isPropertyInherited: function(property)
+ {
+ return !(property in this._usedProperties) && !(property in this._alwaysShowComputedProperties) && !(property in this._disabledComputedProperties);
+ },
+
+ update: function()
+ {
+ this._expandedPropertyNames = {};
+ for (var name in this._propertyTreeElements) {
+ if (this._propertyTreeElements[name].expanded)
+ this._expandedPropertyNames[name] = true;
+ }
+ this._propertyTreeElements = {};
+ this.propertiesTreeOutline.removeChildren();
+ this.populated = false;
+ },
+
+ onpopulate: function()
+ {
+ var style = this.styleRule.style;
+ var uniqueProperties = [];
+ for (var i = 0; i < style.length; ++i)
+ uniqueProperties.push(style[i]);
+ uniqueProperties.sort();
+ this._propertyTreeElements = {};
+ for (var i = 0; i < uniqueProperties.length; ++i) {
+ var name = uniqueProperties[i];
+ var inherited = this._isPropertyInherited(name);
+ var item = new WebInspector.StylePropertyTreeElement(this.styleRule, style, name, false, inherited, false, false);
+ this.propertiesTreeOutline.appendChild(item);
+ this._propertyTreeElements[name] = item;
+ }
+ },
+
+ rebuildComputedTrace: function(sections)
+ {
+ for (var i = 0; i < sections.length; ++i) {
+ var section = sections[i];
+ if (section.computedStyle || section instanceof WebInspector.BlankStylePropertiesSection)
+ continue;
+
+ for (var j = 0; j < section.uniqueProperties.length; ++j) {
+ var name = section.uniqueProperties[j];
+ if (section.isPropertyDisabled(name))
+ continue;
+ if (section.isInherited && !(name in WebInspector.StylesSidebarPane.InheritedProperties))
+ continue;
+
+ var treeElement = this._propertyTreeElements[name];
+ if (treeElement) {
+ var selectorText = section.styleRule.selectorText;
+ var value = section.styleRule.style.getPropertyValue(name);
+ var title = "<span style='color: gray'>" + selectorText + "</span> - " + value;
+ var subtitle = " <span style='float:right'>" + section.subtitleElement.innerHTML + "</span>";
+ var childElement = new TreeElement(title + subtitle, null, false);
+ treeElement.appendChild(childElement);
+ if (section.isPropertyOverloaded(name))
+ childElement.listItemElement.addStyleClass("overloaded");
+ }
+ }
+ }
+
+ // Restore expanded state after update.
+ for (var name in this._expandedPropertyNames) {
+ if (name in this._propertyTreeElements)
+ this._propertyTreeElements[name].expand();
+ }
+ }
+}
+
+WebInspector.ComputedStylePropertiesSection.prototype.__proto__ = WebInspector.PropertiesSection.prototype;
+
+WebInspector.BlankStylePropertiesSection = function(defaultSelectorText)
+{
+ WebInspector.StylePropertiesSection.call(this, {selectorText: defaultSelectorText, rule: {isViaInspector: true}}, true, false, false);
this.element.addStyleClass("blank-section");
}
@@ -966,13 +1039,9 @@ WebInspector.BlankStylePropertiesSection.prototype = {
makeNormal: function(styleRule)
{
this.element.removeStyleClass("blank-section");
-
this.styleRule = styleRule;
this.rule = styleRule.rule;
- this.computedStyle = false;
- this.editable = true;
this.identifier = styleRule.selectorText + ":via inspector";
-
this.__proto__ = WebInspector.StylePropertiesSection.prototype;
}
}
diff --git a/WebCore/inspector/front-end/inspector.css b/WebCore/inspector/front-end/inspector.css
index 8c4a2ea..4319816 100644
--- a/WebCore/inspector/front-end/inspector.css
+++ b/WebCore/inspector/front-end/inspector.css
@@ -4079,6 +4079,10 @@ a.worker-item {
border-top: 1px solid rgb(191, 191, 191);
}
+.styles-section.read-only {
+ background-color: rgb(240, 240, 240);
+}
+
.styles-section .header {
white-space: nowrap;
-webkit-background-origin: padding;
@@ -4103,7 +4107,7 @@ a.worker-item {
color: inherit;
}
-.styles-section .subtitle::before, .styles-section .subtitle a::before {
+.styles-section a::before {
content: attr(data-uncopyable);
}
diff --git a/WebCore/inspector/front-end/inspector.js b/WebCore/inspector/front-end/inspector.js
index fa57916..db89e20 100644
--- a/WebCore/inspector/front-end/inspector.js
+++ b/WebCore/inspector/front-end/inspector.js
@@ -197,6 +197,28 @@ var WebInspector = {
}
},
+ createJSBreakpointsSidebarPane: function()
+ {
+ var pane = new WebInspector.BreakpointsSidebarPane(WebInspector.UIString("Breakpoints"));
+ function breakpointAdded(event)
+ {
+ pane.addBreakpoint(new WebInspector.JSBreakpointItem(event.data));
+ }
+ WebInspector.breakpointManager.addEventListener("breakpoint-added", breakpointAdded);
+ return pane;
+ },
+
+ createDOMBreakpointsSidebarPane: function()
+ {
+ var pane = new WebInspector.BreakpointsSidebarPane(WebInspector.UIString("DOM Breakpoints"));
+ function breakpointAdded(event)
+ {
+ pane.addBreakpoint(new WebInspector.DOMBreakpointItem(event.data));
+ }
+ WebInspector.domBreakpointManager.addEventListener("dom-breakpoint-added", breakpointAdded);
+ return pane;
+ },
+
_createPanels: function()
{
var hiddenPanels = (InspectorFrontendHost.hiddenPanels() || "").split(',');
@@ -469,8 +491,9 @@ WebInspector.doLoadedDone = function()
var port = WebInspector.port;
document.body.addStyleClass("port-" + port);
- this.applicationSettings = new WebInspector.Settings(false);
- this.sessionSettings = new WebInspector.Settings(true);
+ InspectorFrontendHost.loaded();
+ WebInspector.Settings.initialize();
+
this._registerShortcuts();
// set order of some sections explicitly
@@ -496,6 +519,7 @@ WebInspector.doLoadedDone = function()
};
this.breakpointManager = new WebInspector.BreakpointManager();
+ this.domBreakpointManager = new WebInspector.DOMBreakpointManager();
this.cssModel = new WebInspector.CSSStyleModel();
this.panels = {};
@@ -556,7 +580,10 @@ WebInspector.doLoadedDone = function()
this.extensionServer.initExtensions();
- InspectorFrontendHost.loaded();
+ InspectorBackend.populateScriptObjects();
+
+ // As a DOMAgent method, this needs to happen after the frontend has loaded and the agent is available.
+ InspectorBackend.getSupportedCSSProperties(WebInspector.Callback.wrap(WebInspector.CSSCompletions._load));
}
WebInspector.addPanelToolbarIcon = function(toolbarElement, panel, previousToolbarItem)
@@ -589,20 +616,12 @@ var windowLoaded = function()
window.addEventListener("load", windowLoaded, false);
-WebInspector.dispatch = function() {
- var methodName = arguments[0];
- var parameters = Array.prototype.slice.call(arguments, 1);
-
+WebInspector.dispatch = function(message) {
// We'd like to enforce asynchronous interaction between the inspector controller and the frontend.
// This is important to LayoutTests.
function delayDispatch()
{
- if (!(methodName in WebInspector)) {
- console.error("Attempted to dispatch unimplemented WebInspector method: %s", methodName);
- return;
- }
-
- WebInspector[methodName].apply(WebInspector, parameters);
+ WebInspector_syncDispatch(message);
WebInspector.pendingDispatches--;
}
WebInspector.pendingDispatches++;
@@ -612,21 +631,41 @@ WebInspector.dispatch = function() {
// This function is purposely put into the global scope for easy access.
WebInspector_syncDispatch = function(message)
{
- var args = JSON.parse(message);
- var methodName = args[0];
- var parameters = args.slice(1);
- WebInspector[methodName].apply(WebInspector, parameters);
+ var messageObject = (typeof message === "string") ? JSON.parse(message) : message;
+ if (messageObject.type === "response" && !messageObject.success) {
+ WebInspector.removeResponseCallbackEntry(messageObject.seq)
+ WebInspector.reportProtocolError(messageObject);
+ return;
+ }
+
+ var arguments = [];
+ if (messageObject.data)
+ for (var key in messageObject.data)
+ arguments.push(messageObject.data[key]);
+
+ if (messageObject.type === "event") {
+ if (!messageObject.event in WebInspector) {
+ console.error("Attempted to dispatch unimplemented WebInspector method: %s", messageObject.event);
+ return;
+ }
+ WebInspector[messageObject.event].apply(WebInspector, arguments);
+ }
+
+ if (messageObject.type === "response")
+ WebInspector.processResponse(messageObject.seq, arguments);
}
-WebInspector.dispatchMessageFromBackend = function(arguments)
+WebInspector.dispatchMessageFromBackend = function(messageObject)
{
- WebInspector.dispatch.apply(this, arguments);
+ WebInspector.dispatch(messageObject);
}
-WebInspector.reportProtocolError = function(callId, methodName, errorText)
+WebInspector.reportProtocolError = function(messageObject)
{
- WebInspector.log("InspectorBackend." + methodName + " failed with error text: '" + errorText + "'");
- WebInspector.removeResponseCallbackEntry(callId);
+ console.error("Error: InspectorBackend." + messageObject.command + " failed.");
+ for (var error in messageObject.errors)
+ console.error(" " + error);
+ WebInspector.removeResponseCallbackEntry(messageObject.seq);
}
WebInspector.windowResize = function(event)
@@ -702,13 +741,13 @@ WebInspector.documentClick = function(event)
function followLink()
{
// FIXME: support webkit-html-external-link links here.
- if (WebInspector.canShowSourceLine(anchor.href, anchor.lineNumber, anchor.preferredPanel)) {
+ if (WebInspector.canShowSourceLine(anchor.href, anchor.getAttribute("line_number"), anchor.getAttribute("preferred_panel"))) {
if (anchor.hasStyleClass("webkit-html-external-link")) {
anchor.removeStyleClass("webkit-html-external-link");
anchor.addStyleClass("webkit-html-resource-link");
}
- WebInspector.showSourceLine(anchor.href, anchor.lineNumber, anchor.preferredPanel);
+ WebInspector.showSourceLine(anchor.href, anchor.getAttribute("line_number"), anchor.getAttribute("preferred_panel"));
return;
}
@@ -1412,15 +1451,6 @@ WebInspector.resumedScript = function()
this.panels.scripts.debuggerResumed();
}
-WebInspector.populateInterface = function()
-{
- for (var panelName in this.panels) {
- var panel = this.panels[panelName];
- if ("populateInterface" in panel)
- panel.populateInterface();
- }
-}
-
WebInspector.reset = function()
{
for (var panelName in this.panels) {
@@ -1788,8 +1818,8 @@ WebInspector.linkifyResourceAsNode = function(url, preferredPanel, lineNumber, c
if (lineNumber)
linkText += ":" + lineNumber;
var node = WebInspector.linkifyURLAsNode(url, linkText, classes, false, tooltipText);
- node.lineNumber = lineNumber;
- node.preferredPanel = preferredPanel;
+ node.setAttribute("line_number", lineNumber);
+ node.setAttribute("preferred_panel", preferredPanel);
return node;
}
diff --git a/WebCore/loader/Cache.cpp b/WebCore/loader/Cache.cpp
index 521d075..cb536e2 100644
--- a/WebCore/loader/Cache.cpp
+++ b/WebCore/loader/Cache.cpp
@@ -82,10 +82,6 @@ static CachedResource* createResource(CachedResource::Type type, const KURL& url
case CachedResource::XSLStyleSheet:
return new CachedXSLStyleSheet(url.string());
#endif
-#if ENABLE(XBL)
- case CachedResource::XBLStyleSheet:
- return new CachedXBLDocument(url.string());
-#endif
#if ENABLE(LINK_PREFETCH)
case CachedResource::LinkPrefetch:
return new CachedResource(url.string(), CachedResource::LinkPrefetch);
@@ -691,11 +687,6 @@ Cache::Statistics Cache::getStatistics()
case CachedResource::FontResource:
stats.fonts.addResource(resource);
break;
-#if ENABLE(XBL)
- case CachedResource::XBL:
- stats.xblDocs.addResource(resource)
- break;
-#endif
default:
break;
}
diff --git a/WebCore/loader/Cache.h b/WebCore/loader/Cache.h
index 23aad1e..ce8cde4 100644
--- a/WebCore/loader/Cache.h
+++ b/WebCore/loader/Cache.h
@@ -85,9 +85,6 @@ public:
#if ENABLE(XSLT)
TypeStatistic xslStyleSheets;
#endif
-#if ENABLE(XBL)
- TypeStatistic xblDocs;
-#endif
TypeStatistic fonts;
};
diff --git a/WebCore/loader/CachedMetadata.h b/WebCore/loader/CachedMetadata.h
index d26539e..120e4c0 100644
--- a/WebCore/loader/CachedMetadata.h
+++ b/WebCore/loader/CachedMetadata.h
@@ -84,7 +84,7 @@ private:
{
if (m_serializedData.size() < position + sizeof(unsigned))
return 0;
- return *reinterpret_cast<unsigned*>(const_cast<char*>(m_serializedData.data() + position));
+ return *reinterpret_cast_ptr<unsigned*>(const_cast<char*>(m_serializedData.data() + position));
}
// Appends an unsigned value to the end of the serialized data.
diff --git a/WebCore/loader/CachedResource.h b/WebCore/loader/CachedResource.h
index 4b83a8e..f6eb730 100644
--- a/WebCore/loader/CachedResource.h
+++ b/WebCore/loader/CachedResource.h
@@ -61,9 +61,6 @@ public:
#if ENABLE(XSLT)
, XSLStyleSheet
#endif
-#if ENABLE(XBL)
- , XBL
-#endif
#if ENABLE(LINK_PREFETCH)
, LinkPrefetch
#endif
diff --git a/WebCore/loader/CachedResourceClient.h b/WebCore/loader/CachedResourceClient.h
index 40a6a06..275d331 100644
--- a/WebCore/loader/CachedResourceClient.h
+++ b/WebCore/loader/CachedResourceClient.h
@@ -28,12 +28,6 @@
#include <wtf/FastAllocBase.h>
#include <wtf/Forward.h>
-#if ENABLE(XBL)
-namespace XBL {
- class XBLDocument;
-}
-#endif
-
namespace WebCore {
class CachedCSSStyleSheet;
@@ -68,13 +62,7 @@ namespace WebCore {
virtual void setCSSStyleSheet(const String& /* href */, const KURL& /* baseURL */, const String& /* charset */, const CachedCSSStyleSheet*) { }
virtual void setXSLStyleSheet(const String& /* href */, const KURL& /* baseURL */, const String& /* sheet */) { }
-
virtual void fontLoaded(CachedFont*) {};
-
-#if ENABLE(XBL)
- virtual void setXBLDocument(const String& /*URL*/, XBL::XBLDocument*) { }
-#endif
-
virtual void notifyFinished(CachedResource*) { }
};
diff --git a/WebCore/loader/CachedXBLDocument.cpp b/WebCore/loader/CachedXBLDocument.cpp
deleted file mode 100644
index 0ff17f2..0000000
--- a/WebCore/loader/CachedXBLDocument.cpp
+++ /dev/null
@@ -1,110 +0,0 @@
-/*
- Copyright (C) 1998 Lars Knoll (knoll@mpi-hd.mpg.de)
- Copyright (C) 2001 Dirk Mueller (mueller@kde.org)
- Copyright (C) 2002 Waldo Bastian (bastian@kde.org)
- Copyright (C) 2006 Samuel Weinig (sam.weinig@gmail.com)
- Copyright (C) 2004, 2005, 2006, 2007, 2008 Apple 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.
-
- This class provides all functionality needed for loading images, style sheets and html
- pages from the web. It has a memory cache for these objects.
-*/
-
-#include "config.h"
-
-#if ENABLE(XBL)
-
-#include "CachedXBLDocument.h"
-
-#include "CachedResourceClientWalker.h"
-#include "TextResourceDecoder.h"
-#include <wtf/Vector.h>
-
-namespace WebCore {
-
-CachedXBLDocument::CachedXBLDocument(const String &url)
-: CachedResource(url, XBL), m_document(0)
-{
- // It's XML we want.
- setAccept("text/xml, application/xml, application/xhtml+xml, text/xsl, application/rss+xml, application/atom+xml");
-
- m_decoder = new TextResourceDecoder("application/xml");
-}
-
-CachedXBLDocument::~CachedXBLDocument()
-{
- if (m_document)
- m_document->deref();
-}
-
-void CachedXBLDocument::ref(CachedResourceClient *c)
-{
- CachedResource::ref(c);
- if (!m_loading)
- c->setXBLDocument(m_url, m_document);
-}
-
-void CachedXBLDocument::setEncoding(const String& chs)
-{
- m_decoder->setEncoding(chs, TextResourceDecoder::EncodingFromHTTPHeader);
-}
-
-String CachedXBLDocument::encoding() const
-{
- return m_decoder->encoding().name();
-}
-
-void CachedXBLDocument::data(Vector<char>& data, bool )
-{
- if (!allDataReceived)
- return;
-
- ASSERT(!m_document);
-
- m_document = new XBL::XBLDocument();
- m_document->ref();
- m_document->open();
-
- m_document->write(m_decoder->decode(data.data(), data.size()));
- setSize(data.size());
-
- m_document->finishParsing();
- m_document->close();
- m_loading = false;
- checkNotify();
-}
-
-void CachedXBLDocument::checkNotify()
-{
- if (m_loading)
- return;
-
- CachedResourceClientWalker w(m_clients);
- while (CachedResourceClient *c = w.next())
- c->setXBLDocument(m_url, m_document);
-}
-
-void CachedXBLDocument::error()
-{
- m_loading = false;
- m_errorOccurred = true;
- checkNotify();
-}
-
-}
-
-#endif
diff --git a/WebCore/loader/CachedXBLDocument.h b/WebCore/loader/CachedXBLDocument.h
deleted file mode 100644
index 9a8d366..0000000
--- a/WebCore/loader/CachedXBLDocument.h
+++ /dev/null
@@ -1,65 +0,0 @@
-/*
- Copyright (C) 1998 Lars Knoll (knoll@mpi-hd.mpg.de)
- Copyright (C) 2001 Dirk Mueller <mueller@kde.org>
- Copyright (C) 2006 Samuel Weinig (sam.weinig@gmail.com)
- Copyright (C) 2004, 2005, 2006, 2007, 2008 Apple 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.
-
- This class provides all functionality needed for loading images, style sheets and html
- pages from the web. It has a memory cache for these objects.
-*/
-
-#ifndef CachedXBLDocument_h
-#define CachedXBLDocument_h
-
-#include "CachedResource.h"
-#include <wtf/Vector.h>
-
-namespace WebCore {
- class CachedResource;
- class Request;
- class DocLoader;
- class TextResourceDecoder;
- class CachedResourceClient;
-
-#if ENABLE(XBL)
- class CachedXBLDocument : public CachedResource {
- public:
- CachedXBLDocument(const String& url);
- virtual ~CachedXBLDocument();
-
- XBL::XBLDocument* document() const { return m_document; }
-
- virtual void addClient(CachedResourceClient*);
-
- virtual void setEncoding(const String&);
- virtual String encoding() const;
- virtual void data(Vector<char>&, bool allDataReceived);
- virtual void error();
-
- void checkNotify();
-
- protected:
- XBL::XBLDocument* m_document;
- RefPtr<TextResourceDecoder> m_decoder;
- };
-
-#endif
-
-}
-
-#endif
diff --git a/WebCore/loader/DocLoader.cpp b/WebCore/loader/DocLoader.cpp
index f6588c7..d63123e 100644
--- a/WebCore/loader/DocLoader.cpp
+++ b/WebCore/loader/DocLoader.cpp
@@ -27,6 +27,7 @@
#include "config.h"
#include "DocLoader.h"
+#include "loader.h"
#include "Cache.h"
#include "CachedCSSStyleSheet.h"
#include "CachedFont.h"
@@ -40,7 +41,7 @@
#include "Frame.h"
#include "FrameLoader.h"
#include "FrameLoaderClient.h"
-#include "loader.h"
+#include "PingLoader.h"
#include "SecurityOrigin.h"
#include "Settings.h"
#include <wtf/text/CString.h>
@@ -128,6 +129,13 @@ CachedImage* DocLoader::requestImage(const String& url)
Settings* settings = f->settings();
if (!f->loader()->client()->allowImages(!settings || settings->areImagesEnabled()))
return 0;
+
+ if (f->loader()->pageDismissalEventBeingDispatched()) {
+ KURL completeURL = m_doc->completeURL(url);
+ if (completeURL.isValid() && canRequest(CachedResource::ImageResource, completeURL))
+ PingLoader::loadImage(f, completeURL);
+ return 0;
+ }
}
CachedImage* resource = static_cast<CachedImage*>(requestResource(CachedResource::ImageResource, url, String()));
if (autoLoadImages() && resource && resource->stillNeedsLoad()) {
@@ -169,13 +177,6 @@ CachedXSLStyleSheet* DocLoader::requestXSLStyleSheet(const String& url)
}
#endif
-#if ENABLE(XBL)
-CachedXBLDocument* DocLoader::requestXBLDocument(const String& url)
-{
- return static_cast<CachedXSLStyleSheet*>(requestResource(CachedResource::XBL, url, String()));
-}
-#endif
-
#if ENABLE(LINK_PREFETCH)
CachedResource* DocLoader::requestLinkPrefetch(const String& url)
{
@@ -201,11 +202,6 @@ bool DocLoader::canRequest(CachedResource::Type type, const KURL& url)
break;
#if ENABLE(XSLT)
case CachedResource::XSLStyleSheet:
-#endif
-#if ENABLE(XBL)
- case CachedResource::XBL:
-#endif
-#if ENABLE(XSLT) || ENABLE(XBL)
if (!m_doc->securityOrigin()->canRequest(url)) {
printAccessDeniedMessage(url);
return false;
@@ -229,9 +225,6 @@ bool DocLoader::canRequest(CachedResource::Type type, const KURL& url)
#if ENABLE(XSLT)
case CachedResource::XSLStyleSheet:
#endif
-#if ENABLE(XBL)
- case CachedResource::XBL:
-#endif
// These resource can inject script into the current document.
if (Frame* f = frame())
f->loader()->checkIfRunInsecureContent(m_doc->securityOrigin(), url);
diff --git a/WebCore/loader/DocLoader.h b/WebCore/loader/DocLoader.h
index 06b02c9..d77bce5 100644
--- a/WebCore/loader/DocLoader.h
+++ b/WebCore/loader/DocLoader.h
@@ -64,9 +64,6 @@ public:
#if ENABLE(XSLT)
CachedXSLStyleSheet* requestXSLStyleSheet(const String& url);
#endif
-#if ENABLE(XBL)
- CachedXBLDocument* requestXBLDocument(const String &url);
-#endif
#if ENABLE(LINK_PREFETCH)
CachedResource* requestLinkPrefetch(const String &url);
#endif
diff --git a/WebCore/loader/FTPDirectoryDocument.cpp b/WebCore/loader/FTPDirectoryDocument.cpp
index 5c7102c..6475ea9 100644
--- a/WebCore/loader/FTPDirectoryDocument.cpp
+++ b/WebCore/loader/FTPDirectoryDocument.cpp
@@ -50,7 +50,10 @@ using namespace HTMLNames;
class FTPDirectoryDocumentParser : public HTMLDocumentParser {
public:
- FTPDirectoryDocumentParser(HTMLDocument*);
+ static PassRefPtr<FTPDirectoryDocumentParser> create(HTMLDocument* document)
+ {
+ return adoptRef(new FTPDirectoryDocumentParser(document));
+ }
virtual void append(const SegmentedString&);
virtual void finish();
@@ -70,6 +73,8 @@ public:
}
private:
+ FTPDirectoryDocumentParser(HTMLDocument*);
+
// The parser will attempt to load the document template specified via the preference
// Failing that, it will fall back and create the basic document which will have a minimal
// table for presenting the FTP directory in a useful manner
@@ -436,9 +441,9 @@ FTPDirectoryDocument::FTPDirectoryDocument(Frame* frame, const KURL& url)
#endif
}
-DocumentParser* FTPDirectoryDocument::createParser()
+PassRefPtr<DocumentParser> FTPDirectoryDocument::createParser()
{
- return new FTPDirectoryDocumentParser(this);
+ return FTPDirectoryDocumentParser::create(this);
}
}
diff --git a/WebCore/loader/FTPDirectoryDocument.h b/WebCore/loader/FTPDirectoryDocument.h
index 920f870..e7e52f7 100644
--- a/WebCore/loader/FTPDirectoryDocument.h
+++ b/WebCore/loader/FTPDirectoryDocument.h
@@ -40,7 +40,7 @@ public:
private:
FTPDirectoryDocument(Frame*, const KURL&);
- virtual DocumentParser* createParser();
+ virtual PassRefPtr<DocumentParser> createParser();
};
} // namespace WebCore
diff --git a/WebCore/loader/FrameLoader.h b/WebCore/loader/FrameLoader.h
index 639b6cc..754c151 100644
--- a/WebCore/loader/FrameLoader.h
+++ b/WebCore/loader/FrameLoader.h
@@ -333,6 +333,8 @@ public:
void started();
+ bool pageDismissalEventBeingDispatched() const { return m_pageDismissalEventBeingDispatched; }
+
private:
bool canCachePageContainingThisFrame();
#ifndef NDEBUG
diff --git a/WebCore/loader/ImageDocument.cpp b/WebCore/loader/ImageDocument.cpp
index b1e33f4..a1a9f80 100644
--- a/WebCore/loader/ImageDocument.cpp
+++ b/WebCore/loader/ImageDocument.cpp
@@ -73,17 +73,22 @@ private:
class ImageDocumentParser : public RawDataDocumentParser {
public:
- ImageDocumentParser(ImageDocument* document)
- : RawDataDocumentParser(document)
+ static PassRefPtr<ImageDocumentParser> create(ImageDocument* document)
{
+ return adoptRef(new ImageDocumentParser(document));
}
ImageDocument* document() const
{
- return static_cast<ImageDocument*>(m_document);
+ return static_cast<ImageDocument*>(RawDataDocumentParser::document());
}
-
+
private:
+ ImageDocumentParser(ImageDocument* document)
+ : RawDataDocumentParser(document)
+ {
+ }
+
virtual void appendBytes(DocumentWriter*, const char*, int, bool);
virtual void finish();
};
@@ -175,9 +180,9 @@ ImageDocument::ImageDocument(Frame* frame, const KURL& url)
setParseMode(Compat);
}
-DocumentParser* ImageDocument::createParser()
+PassRefPtr<DocumentParser> ImageDocument::createParser()
{
- return new ImageDocumentParser(this);
+ return ImageDocumentParser::create(this);
}
void ImageDocument::createDocumentStructure()
diff --git a/WebCore/loader/ImageDocument.h b/WebCore/loader/ImageDocument.h
index e85b3ab..5d00bd6 100644
--- a/WebCore/loader/ImageDocument.h
+++ b/WebCore/loader/ImageDocument.h
@@ -49,7 +49,7 @@ public:
private:
ImageDocument(Frame*, const KURL&);
- virtual DocumentParser* createParser();
+ virtual PassRefPtr<DocumentParser> createParser();
virtual bool isImageDocument() const { return true; }
void createDocumentStructure();
diff --git a/WebCore/loader/MediaDocument.cpp b/WebCore/loader/MediaDocument.cpp
index 97e1775..7e28d02 100644
--- a/WebCore/loader/MediaDocument.cpp
+++ b/WebCore/loader/MediaDocument.cpp
@@ -47,13 +47,18 @@ using namespace HTMLNames;
// FIXME: Share more code with PluginDocumentParser.
class MediaDocumentParser : public RawDataDocumentParser {
public:
+ static PassRefPtr<MediaDocumentParser> create(MediaDocument* document)
+ {
+ return adoptRef(new MediaDocumentParser(document));
+ }
+
+private:
MediaDocumentParser(Document* document)
: RawDataDocumentParser(document)
, m_mediaElement(0)
{
}
-private:
virtual void appendBytes(DocumentWriter*, const char*, int, bool);
void createDocumentStructure();
@@ -113,9 +118,9 @@ MediaDocument::~MediaDocument()
ASSERT(!m_replaceMediaElementTimer.isActive());
}
-DocumentParser* MediaDocument::createParser()
+PassRefPtr<DocumentParser> MediaDocument::createParser()
{
- return new MediaDocumentParser(this);
+ return MediaDocumentParser::create(this);
}
void MediaDocument::defaultEventHandler(Event* event)
diff --git a/WebCore/loader/MediaDocument.h b/WebCore/loader/MediaDocument.h
index 5a8ec52..2d81296 100644
--- a/WebCore/loader/MediaDocument.h
+++ b/WebCore/loader/MediaDocument.h
@@ -46,7 +46,7 @@ private:
MediaDocument(Frame*, const KURL&);
virtual bool isMediaDocument() const { return true; }
- virtual DocumentParser* createParser();
+ virtual PassRefPtr<DocumentParser> createParser();
virtual void defaultEventHandler(Event*);
diff --git a/WebCore/loader/PingLoader.cpp b/WebCore/loader/PingLoader.cpp
new file mode 100644
index 0000000..d2c6410
--- /dev/null
+++ b/WebCore/loader/PingLoader.cpp
@@ -0,0 +1,73 @@
+/*
+ * Copyright (C) 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 "PingLoader.h"
+
+#include "Frame.h"
+#include "ResourceHandle.h"
+#include "SecurityOrigin.h"
+#include <wtf/OwnPtr.h>
+#include <wtf/UnusedParam.h>
+
+namespace WebCore {
+
+void PingLoader::loadImage(Frame* frame, const KURL& url)
+{
+ if (SecurityOrigin::restrictAccessToLocal() && !SecurityOrigin::canLoad(url, String(), frame->document())) {
+ FrameLoader::reportLocalLoadFailed(frame, url);
+ return;
+ }
+
+ ResourceRequest request(url);
+ request.setTargetType(ResourceRequest::TargetIsImage);
+ request.setHTTPHeaderField("Cache-Control", "max-age=0");
+ if (!SecurityOrigin::shouldHideReferrer(request.url(), frame->loader()->outgoingReferrer()))
+ request.setHTTPReferrer(frame->loader()->outgoingReferrer());
+ frame->loader()->addExtraFieldsToSubresourceRequest(request);
+ OwnPtr<PingLoader> pingLoader(new PingLoader(frame, request));
+
+ // Leak the ping loader, since it will kill itself as soon as it receives a response.
+ PingLoader* leakedPingLoader = pingLoader.leakPtr();
+ UNUSED_PARAM(leakedPingLoader);
+}
+
+PingLoader::PingLoader(Frame* frame, const ResourceRequest& request)
+{
+ m_handle = ResourceHandle::create(request, this, frame, false, false);
+}
+
+PingLoader::~PingLoader()
+{
+ m_handle->cancel();
+}
+
+}
diff --git a/WebCore/loader/PingLoader.h b/WebCore/loader/PingLoader.h
new file mode 100644
index 0000000..1d8a2d8
--- /dev/null
+++ b/WebCore/loader/PingLoader.h
@@ -0,0 +1,71 @@
+/*
+ * Copyright (C) 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 PingLoader_h
+#define PingLoader_h
+
+#include "ResourceHandleClient.h"
+#include <wtf/Noncopyable.h>
+#include <wtf/RefPtr.h>
+
+namespace WebCore {
+
+class Frame;
+class KURL;
+class ResourceError;
+class ResourceHandle;
+class ResourceResponse;
+
+// This class triggers asynchronous loads independent of Frame staying alive (i.e., auditing pingbacks).
+// Since nothing depends on resources loaded through this class, we just want
+// to allow the load to live long enough to ensure the message was actually sent.
+// Therefore, as soon as a callback is received from the ResourceHandle, this class
+// will cancel the load and delete itself.
+class PingLoader : private ResourceHandleClient, public Noncopyable {
+public:
+ static void loadImage(Frame*, const KURL& url);
+
+ ~PingLoader();
+
+private:
+ PingLoader(Frame*, const ResourceRequest&);
+
+ void didReceiveResponse(ResourceHandle*, const ResourceResponse&) { delete this; }
+ void didReceiveData(ResourceHandle*, const char*, int) { delete this; }
+ void didFinishLoading(ResourceHandle*) { delete this; }
+ void didFail(ResourceHandle*, const ResourceError&) { delete this; }
+
+ RefPtr<ResourceHandle> m_handle;
+};
+
+}
+
+#endif
diff --git a/WebCore/loader/PluginDocument.cpp b/WebCore/loader/PluginDocument.cpp
index cca6894..54e686c 100644
--- a/WebCore/loader/PluginDocument.cpp
+++ b/WebCore/loader/PluginDocument.cpp
@@ -43,15 +43,20 @@ using namespace HTMLNames;
// FIXME: Share more code with MediaDocumentParser.
class PluginDocumentParser : public RawDataDocumentParser {
public:
+ static PassRefPtr<PluginDocumentParser> create(PluginDocument* document)
+ {
+ return adoptRef(new PluginDocumentParser(document));
+ }
+
+ static Widget* pluginWidgetFromDocument(Document*);
+
+private:
PluginDocumentParser(Document* document)
: RawDataDocumentParser(document)
, m_embedElement(0)
{
}
- static Widget* pluginWidgetFromDocument(Document*);
-
-private:
virtual void appendBytes(DocumentWriter*, const char*, int, bool);
void createDocumentStructure();
@@ -130,9 +135,9 @@ PluginDocument::PluginDocument(Frame* frame, const KURL& url)
setParseMode(Compat);
}
-DocumentParser* PluginDocument::createParser()
+PassRefPtr<DocumentParser> PluginDocument::createParser()
{
- return new PluginDocumentParser(this);
+ return PluginDocumentParser::create(this);
}
Widget* PluginDocument::pluginWidget()
diff --git a/WebCore/loader/PluginDocument.h b/WebCore/loader/PluginDocument.h
index 53dde65..3bb5d99 100644
--- a/WebCore/loader/PluginDocument.h
+++ b/WebCore/loader/PluginDocument.h
@@ -46,7 +46,7 @@ public:
private:
PluginDocument(Frame*, const KURL&);
- virtual DocumentParser* createParser();
+ virtual PassRefPtr<DocumentParser> createParser();
};
}
diff --git a/WebCore/loader/RedirectScheduler.cpp b/WebCore/loader/RedirectScheduler.cpp
index d969f30..26d7787 100644
--- a/WebCore/loader/RedirectScheduler.cpp
+++ b/WebCore/loader/RedirectScheduler.cpp
@@ -342,10 +342,10 @@ void RedirectScheduler::scheduleHistoryNavigation(int steps)
}
#if !ENABLE(HISTORY_ALWAYS_ASYNC)
- // If the specified entry and the current entry have the same document, this is either a state object traversal or a fragment
- // traversal (or both) and should be performed synchronously.
+ // If the specified entry and the current entry have the same document (or documents, in there are frames), this is either a
+ // state object traversal or a fragment traversal (or both) and should be performed synchronously.
HistoryItem* currentEntry = m_frame->loader()->history()->currentItem();
- if (currentEntry != specifiedEntry && currentEntry->documentSequenceNumber() == specifiedEntry->documentSequenceNumber()) {
+ if (currentEntry != specifiedEntry && currentEntry->hasSameDocuments(specifiedEntry)) {
m_frame->loader()->history()->goToItem(specifiedEntry, FrameLoadTypeIndexedBackForward);
return;
}
diff --git a/WebCore/loader/ResourceLoader.cpp b/WebCore/loader/ResourceLoader.cpp
index b700fcf..b679795 100644
--- a/WebCore/loader/ResourceLoader.cpp
+++ b/WebCore/loader/ResourceLoader.cpp
@@ -32,6 +32,7 @@
#include "ApplicationCacheHost.h"
#include "DocumentLoader.h"
+#include "FileStreamProxy.h"
#include "Frame.h"
#include "FrameLoader.h"
#include "InspectorTimelineAgent.h"
@@ -522,4 +523,12 @@ void ResourceLoader::willCacheResponse(ResourceHandle*, CacheStoragePolicy& poli
policy = StorageAllowedInMemoryOnly;
}
+#if ENABLE(BLOB)
+AsyncFileStream* ResourceLoader::createAsyncFileStream(FileStreamClient* client)
+{
+ // It is OK to simply return a pointer since FileStreamProxy::create adds an extra ref.
+ return FileStreamProxy::create(m_frame->document()->scriptExecutionContext(), client).get();
+}
+#endif
+
}
diff --git a/WebCore/loader/ResourceLoader.h b/WebCore/loader/ResourceLoader.h
index e7643bf..f2a3161 100644
--- a/WebCore/loader/ResourceLoader.h
+++ b/WebCore/loader/ResourceLoader.h
@@ -122,6 +122,9 @@ namespace WebCore {
#if USE(CFNETWORK)
virtual bool shouldCacheResponse(ResourceHandle*, CFCachedURLResponseRef);
#endif
+#if ENABLE(BLOB)
+ virtual AsyncFileStream* createAsyncFileStream(FileStreamClient*);
+#endif
ResourceHandle* handle() const { return m_handle.get(); }
bool sendResourceLoadCallbacks() const { return m_sendResourceLoadCallbacks; }
diff --git a/WebCore/loader/SinkDocument.cpp b/WebCore/loader/SinkDocument.cpp
index fb0ab94..262d318 100644
--- a/WebCore/loader/SinkDocument.cpp
+++ b/WebCore/loader/SinkDocument.cpp
@@ -32,12 +32,17 @@ namespace WebCore {
class SinkDocumentParser : public RawDataDocumentParser {
public:
+ static PassRefPtr<SinkDocumentParser> create(SinkDocument* document)
+ {
+ return adoptRef(new SinkDocumentParser(document));
+ }
+
+private:
SinkDocumentParser(SinkDocument* document)
: RawDataDocumentParser(document)
{
}
-private:
// Ignore all data.
virtual void appendBytes(DocumentWriter*, const char*, int, bool) { }
};
@@ -48,9 +53,9 @@ SinkDocument::SinkDocument(Frame* frame, const KURL& url)
setParseMode(Compat);
}
-DocumentParser* SinkDocument::createParser()
+PassRefPtr<DocumentParser> SinkDocument::createParser()
{
- return new SinkDocumentParser(this);
+ return SinkDocumentParser::create(this);
}
} // namespace WebCore
diff --git a/WebCore/loader/SinkDocument.h b/WebCore/loader/SinkDocument.h
index 61930d4..50152ff 100644
--- a/WebCore/loader/SinkDocument.h
+++ b/WebCore/loader/SinkDocument.h
@@ -40,7 +40,7 @@ public:
private:
SinkDocument(Frame*, const KURL&);
- virtual DocumentParser* createParser();
+ virtual PassRefPtr<DocumentParser> createParser();
};
diff --git a/WebCore/loader/SubframeLoader.cpp b/WebCore/loader/SubframeLoader.cpp
index e7dafa1..f56ebf1 100644
--- a/WebCore/loader/SubframeLoader.cpp
+++ b/WebCore/loader/SubframeLoader.cpp
@@ -37,9 +37,6 @@
#include "FrameLoaderClient.h"
#include "HTMLAppletElement.h"
#include "HTMLFrameElementBase.h"
-#if ENABLE(PLUGIN_PROXY_FOR_VIDEO)
-#include "HTMLMediaElement.h"
-#endif
#include "HTMLNames.h"
#include "HTMLPlugInElement.h"
#include "MIMETypeRegistry.h"
@@ -47,13 +44,15 @@
#include "Page.h"
#include "PluginData.h"
#include "RenderEmbeddedObject.h"
-#if ENABLE(PLUGIN_PROXY_FOR_VIDEO)
-#include "RenderVideo.h"
-#endif
#include "RenderView.h"
#include "Settings.h"
#include "XSSAuditor.h"
+#if ENABLE(PLUGIN_PROXY_FOR_VIDEO)
+#include "HTMLMediaElement.h"
+#include "RenderVideo.h"
+#endif
+
namespace WebCore {
using namespace HTMLNames;
@@ -90,12 +89,7 @@ bool SubframeLoader::requestFrame(HTMLFrameOwnerElement* ownerElement, const Str
} else
url = completeURL(urlString);
- Frame* frame = ownerElement->contentFrame();
- if (frame)
- frame->redirectScheduler()->scheduleLocationChange(url.string(), m_frame->loader()->outgoingReferrer(), lockHistory, lockBackForwardList, m_frame->loader()->isProcessingUserGesture());
- else
- frame = loadSubframe(ownerElement, url, frameName, m_frame->loader()->outgoingReferrer());
-
+ Frame* frame = loadOrRedirectSubframe(ownerElement, url, frameName, lockHistory, lockBackForwardList);
if (!frame)
return false;
@@ -138,10 +132,10 @@ bool SubframeLoader::requestObject(RenderEmbeddedObject* renderer, const String&
ASSERT(renderer->node()->hasTagName(objectTag) || renderer->node()->hasTagName(embedTag));
HTMLPlugInElement* element = static_cast<HTMLPlugInElement*>(renderer->node());
- // If the plug-in element already contains a subframe, requestFrame will re-use it. Otherwise,
+ // If the plug-in element already contains a subframe, loadOrRedirectSubframe will re-use it. Otherwise,
// it will create a new frame and set it as the RenderPart's widget, causing what was previously
// in the widget to be torn down.
- return requestFrame(element, completedURL, frameName);
+ return loadOrRedirectSubframe(element, completedURL, frameName, true, true);
}
@@ -236,6 +230,16 @@ PassRefPtr<Widget> SubframeLoader::createJavaAppletWidget(const IntSize& size, H
return widget;
}
+Frame* SubframeLoader::loadOrRedirectSubframe(HTMLFrameOwnerElement* ownerElement, const KURL& url, const AtomicString& frameName, bool lockHistory, bool lockBackForwardList)
+{
+ Frame* frame = ownerElement->contentFrame();
+ if (frame)
+ frame->redirectScheduler()->scheduleLocationChange(url.string(), m_frame->loader()->outgoingReferrer(), lockHistory, lockBackForwardList, m_frame->loader()->isProcessingUserGesture());
+ else
+ frame = loadSubframe(ownerElement, url, frameName, m_frame->loader()->outgoingReferrer());
+ return frame;
+}
+
Frame* SubframeLoader::loadSubframe(HTMLFrameOwnerElement* ownerElement, const KURL& url, const String& name, const String& referrer)
{
bool allowsScrolling = true;
diff --git a/WebCore/loader/SubframeLoader.h b/WebCore/loader/SubframeLoader.h
index df08870..d42ef2c 100644
--- a/WebCore/loader/SubframeLoader.h
+++ b/WebCore/loader/SubframeLoader.h
@@ -74,6 +74,7 @@ public:
bool containsPlugins() const { return m_containsPlugins; }
private:
+ Frame* loadOrRedirectSubframe(HTMLFrameOwnerElement*, const KURL&, const AtomicString& frameName, bool lockHistory, bool lockBackForwardList);
Frame* loadSubframe(HTMLFrameOwnerElement*, const KURL&, const String& name, const String& referrer);
bool loadPlugin(RenderEmbeddedObject*, const KURL&, const String& mimeType,
const Vector<String>& paramNames, const Vector<String>& paramValues, bool useFallback);
diff --git a/WebCore/loader/TextDocument.cpp b/WebCore/loader/TextDocument.cpp
index 6b53084..5e2b774 100644
--- a/WebCore/loader/TextDocument.cpp
+++ b/WebCore/loader/TextDocument.cpp
@@ -42,11 +42,22 @@ using namespace HTMLNames;
// which started the Tokenizer in the PlainText state.
class TextDocumentParser : public DecodedDataDocumentParser {
public:
- TextDocumentParser(Document*);
+ static PassRefPtr<TextDocumentParser> create(Document* document)
+ {
+ return adoptRef(new TextDocumentParser(document));
+ }
+
+ static PassRefPtr<TextDocumentParser> create(HTMLViewSourceDocument* document)
+ {
+ return adoptRef(new TextDocumentParser(document));
+ }
+
virtual ~TextDocumentParser();
+
+private:
+ TextDocumentParser(Document*);
TextDocumentParser(HTMLViewSourceDocument*);
-private:
virtual void insert(const SegmentedString&);
virtual void append(const SegmentedString&);
virtual void finish();
@@ -193,14 +204,14 @@ TextDocument::TextDocument(Frame* frame, const KURL& url)
{
}
-DocumentParser* TextDocument::createParser()
+PassRefPtr<DocumentParser> TextDocument::createParser()
{
- return new TextDocumentParser(this);
+ return TextDocumentParser::create(this);
}
-DocumentParser* createTextDocumentParser(HTMLViewSourceDocument* document)
+PassRefPtr<DocumentParser> createTextDocumentParser(HTMLViewSourceDocument* document)
{
- return new TextDocumentParser(document);
+ return TextDocumentParser::create(document);
}
}
diff --git a/WebCore/loader/TextDocument.h b/WebCore/loader/TextDocument.h
index 8f58b69..d5bf153 100644
--- a/WebCore/loader/TextDocument.h
+++ b/WebCore/loader/TextDocument.h
@@ -41,10 +41,10 @@ public:
private:
TextDocument(Frame*, const KURL&);
- virtual DocumentParser* createParser();
+ virtual PassRefPtr<DocumentParser> createParser();
};
-DocumentParser* createTextDocumentParser(HTMLViewSourceDocument*);
+PassRefPtr<DocumentParser> createTextDocumentParser(HTMLViewSourceDocument*);
}
diff --git a/WebCore/loader/icon/IconDatabase.cpp b/WebCore/loader/icon/IconDatabase.cpp
index 63b9c64..f708622 100644
--- a/WebCore/loader/icon/IconDatabase.cpp
+++ b/WebCore/loader/icon/IconDatabase.cpp
@@ -768,6 +768,7 @@ IconDatabase::IconDatabase()
, m_threadTerminationRequested(false)
, m_removeIconsRequested(false)
, m_iconURLImportComplete(false)
+ , m_disabledSuddenTerminationForSyncThread(false)
, m_initialPruningComplete(false)
, m_client(defaultClient())
, m_imported(false)
@@ -806,13 +807,17 @@ void IconDatabase::notifyPendingLoadDecisions()
void IconDatabase::wakeSyncThread()
{
- // The following is balanced by the call to enableSuddenTermination in the
- // syncThreadMainLoop function.
- // FIXME: It would be better to only disable sudden termination if we have
- // something to write, not just if we have something to read.
- disableSuddenTermination();
-
MutexLocker locker(m_syncLock);
+
+ if (!m_disabledSuddenTerminationForSyncThread) {
+ m_disabledSuddenTerminationForSyncThread = true;
+ // The following is balanced by the call to enableSuddenTermination in the
+ // syncThreadMainLoop function.
+ // FIXME: It would be better to only disable sudden termination if we have
+ // something to write, not just if we have something to read.
+ disableSuddenTermination();
+ }
+
m_syncCondition.signal();
}
@@ -1411,7 +1416,9 @@ void* IconDatabase::syncThreadMainLoop()
// The following is balanced by the call to disableSuddenTermination in the
// wakeSyncThread function. Any time we wait on the condition, we also have
// to enableSuddenTermation, after doing the next batch of work.
+ ASSERT(m_disabledSuddenTerminationForSyncThread);
enableSuddenTermination();
+ m_disabledSuddenTerminationForSyncThread = false;
}
m_syncCondition.wait(m_syncLock);
@@ -1428,7 +1435,9 @@ void* IconDatabase::syncThreadMainLoop()
// The following is balanced by the call to disableSuddenTermination in the
// wakeSyncThread function. Any time we wait on the condition, we also have
// to enableSuddenTermation, after doing the next batch of work.
+ ASSERT(m_disabledSuddenTerminationForSyncThread);
enableSuddenTermination();
+ m_disabledSuddenTerminationForSyncThread = false;
}
return 0;
diff --git a/WebCore/loader/icon/IconDatabase.h b/WebCore/loader/icon/IconDatabase.h
index 9793d21..6146aa6 100644
--- a/WebCore/loader/icon/IconDatabase.h
+++ b/WebCore/loader/icon/IconDatabase.h
@@ -144,11 +144,12 @@ private:
String m_databaseDirectory;
// Holding m_syncLock is required when accessing m_completeDatabasePath
String m_completeDatabasePath;
-
+
bool m_threadTerminationRequested;
bool m_removeIconsRequested;
bool m_iconURLImportComplete;
-
+ bool m_disabledSuddenTerminationForSyncThread;
+
Mutex m_urlAndIconLock;
// Holding m_urlAndIconLock is required when accessing any of the following data structures or the objects they contain
HashMap<String, IconRecord*> m_iconURLToRecordMap;
diff --git a/WebCore/loader/loader.cpp b/WebCore/loader/loader.cpp
index 230d6ea..345d881 100644
--- a/WebCore/loader/loader.cpp
+++ b/WebCore/loader/loader.cpp
@@ -79,9 +79,6 @@ static ResourceRequest::TargetType cachedResourceTypeToTargetType(CachedResource
#if ENABLE(XSLT)
case CachedResource::XSLStyleSheet:
#endif
-#if ENABLE(XBL)
- case CachedResource::XBL:
-#endif
return ResourceRequest::TargetIsStyleSheet;
case CachedResource::Script:
return ResourceRequest::TargetIsScript;
@@ -106,9 +103,6 @@ Loader::Priority Loader::determinePriority(const CachedResource* resource) const
#if ENABLE(XSLT)
case CachedResource::XSLStyleSheet:
#endif
-#if ENABLE(XBL)
- case CachedResource::XBL:
-#endif
return High;
case CachedResource::Script:
case CachedResource::FontResource:
@@ -551,9 +545,7 @@ void Loader::Host::didReceiveData(SubresourceLoader* loader, const char* data, i
if (resource->errorOccurred())
return;
- if (resource->response().httpStatusCode() / 100 == 4) {
- // Treat a 4xx response like a network error for all resources but images (which will ignore the error and continue to load for
- // legacy compatibility).
+ if (resource->response().httpStatusCode() >= 400) {
resource->httpStatusCodeError();
return;
}
diff --git a/WebCore/manual-tests/indexed-database.html b/WebCore/manual-tests/indexed-database.html
index d0fb381..da2a1e1 100644
--- a/WebCore/manual-tests/indexed-database.html
+++ b/WebCore/manual-tests/indexed-database.html
@@ -2,65 +2,47 @@
<body>
<p>This is a test that only applies to IndexedDB. <span id=enabled>Our test for whether you have it enabled seems to have failed.</span></p>
-<p>This page opens up a database with the name "name" and a description of "description". Result of open: <span id=result>Pending...</span></p>
+<p>Please follow these steps in order:</p>
-<p>The first time you open this page up, the message should be a success. Now, lets make it fail. Find where the associated .indexeddb file is
- for this page, replace it with something that's not a sqlite database, and make it read only to your user. Now close and re-open the browser.
- When you re-open it, you should get an internal error from the page.</p>
+<p>First, click <a href="javascript: doOpen(true)">here</a> to open an indexedDB database. Look in the proper place in your file system (the place being specific to each port) and verify a file was created. You should be able to open the file up with sqlite and examine it that way as well.</p>
-<p>Now delete all IndexedDB files (including the one you just made), restart the browser, and come back to this page. It should start up fine again.</p>
+<p>Next, close the browser, delete the file, replace it with some garbage, and make it read only to the user the browser is running as. Now click <a href="javascript: doOpen(false)">here</a>. You should get some sort of error.</p>
-<p>Now click <a href="javascript:updateDescription()">here</a>, close the browser, come back, and click <a href="javascript:readDescription()">here</a>. If everything worked well, this should be a success here: <span id=description>...</span></p>
+<p>Close the browser, delete the file you made, and click <a href="javascript: doOpen(true)">here</a>. All should be well again.</p>
-<p>That's it!</p>
+<p>Status: <span id=status>...</span></p>
<script>
- if (!('indexedDB' in window))
- document.getElementById("enabled").innerHTML = "<font color=red>Your build does NOT seem to have it enabled. So all code on this page is disabled.</font>";
- else {
- document.getElementById("enabled").innerHTML = "<font color=green>Your build seems to have it enabled.</font>";
-
- request = indexedDB.open("name");
- request.onsuccess = function() {
- document.getElementById("result").innerHTML = "<font color=green>Success!</font>";
- window.nameDB = event.result;
- };
- request.onerror = function() {
- document.getElementById("result").innerHTML = "<font color=red>Error: " + event.message + ".</font>";
- };
-
- request = indexedDB.open("another", "test of the description attribute");
- request.onsuccess = function() {
- window.anotherDB = event.result;
- };
- }
-
- function updateDescription()
- {
- indexedDB.open("name", "test of the description attribute");
- indexedDB.open("another", "xyz");
- }
-
- function readDescription()
- {
- if (window.nameDB.description != "test of the description attribute") {
- // Since we passed in nothing, the description should not be reset.
- document.getElementById("description").innerHTML = "<font color=red>Failure: (Database 'name' was this: " + window.nameDB.description + ").</font>";
- } else if (window.anotherDB.description != "test of the description attribute") {
- // But in this case we did pass something in, so it should have been reset.
- document.getElementById("description").innerHTML = "<font color=red>Failure: (Database 'another' was this: " + window.anotherDB.description + ").</font>";
- } else {
- request = indexedDB.open("another", "123");
- request.onsuccess = function() {
- // And here it should have been reset again.
- if (event.result.description != "123")
- document.getElementById("description").innerHTML = "<font color=red>Failure: (Database 'another' was this: " + event.result.description + ").</font>";
- else
- document.getElementById("description").innerHTML = "<font color=green>Success!</font>";
- };
- }
- }
+if (!('indexedDB' in window))
+ document.getElementById("enabled").innerHTML = "<font color=red>Your build does NOT seem to have it enabled. So all code on this page is disabled.</font>";
+else
+ document.getElementById("enabled").innerHTML = "<font color=green>Your build seems to have it enabled.</font>";
+
+function status(str, color)
+{
+ if (color)
+ str = "<font color='" + color + "'>" + str + "</font>";
+ document.getElementById("status").innerHTML = str;
+}
+
+function doOpen(expectSuccess)
+{
+ status("Calling open");
+ request = indexedDB.open("xyz");
+ request.onsuccess = function() {
+ if (expectSuccess)
+ status("Open successful", "green");
+ else
+ status("Open was successful...but shouldn't have been", "red");
+ };
+ request.onerror = function() {
+ if (expectSuccess)
+ status("Unexpected error: " + event.message, "red");
+ else
+ status("Expected error: " + event.message, "green");
+ };
+}
</script>
</body>
diff --git a/WebCore/mathml/RenderMathMLFraction.cpp b/WebCore/mathml/RenderMathMLFraction.cpp
index 72f7298..914f6fe 100644
--- a/WebCore/mathml/RenderMathMLFraction.cpp
+++ b/WebCore/mathml/RenderMathMLFraction.cpp
@@ -176,7 +176,7 @@ void RenderMathMLFraction::paint(PaintInfo& info, int tx, int ty)
int RenderMathMLFraction::baselinePosition(bool firstLine, bool isRootLineBox) const
{
- if (firstChild()->isRenderMathMLBlock()) {
+ if (firstChild() && firstChild()->isRenderMathMLBlock()) {
RenderMathMLBlock* numerator = toRenderMathMLBlock(firstChild());
// FIXME: the baseline should adjust so the fraction line aligns
// relative certain operators (e.g. aligns with the horizontal
diff --git a/WebCore/mathml/RenderMathMLUnderOver.cpp b/WebCore/mathml/RenderMathMLUnderOver.cpp
index ad32d59..f015054 100644
--- a/WebCore/mathml/RenderMathMLUnderOver.cpp
+++ b/WebCore/mathml/RenderMathMLUnderOver.cpp
@@ -236,35 +236,35 @@ void RenderMathMLUnderOver::layout()
int RenderMathMLUnderOver::baselinePosition(bool firstLine, bool isRootLineBox) const
{
+ RenderObject* current = firstChild();
+ if (!current)
+ return RenderBlock::baselinePosition(firstLine, isRootLineBox);
+
int baseline = 0;
- RenderObject* current = 0;
switch (m_kind) {
case UnderOver:
case Over:
- current = firstChild();
baseline += getOffsetHeight(current);
current = current->nextSibling();
if (current) {
// actual base
RenderObject* base = current->firstChild();
+ if (!base)
+ break;
baseline += base->baselinePosition(firstLine, isRootLineBox);
// added the negative top margin
baseline += current->style()->marginTop().value();
- // FIXME: Where is the extra 2-3px adjusted for zoom coming from?
- float zoomFactor = style()->effectiveZoom();
- baseline += static_cast<int>((zoomFactor > 1.25 ? 2 : 3) * zoomFactor);
}
break;
case Under:
- current = firstChild();
- if (current) {
- RenderObject* base = current->firstChild();
+ RenderObject* base = current->firstChild();
+ if (base)
baseline += base->baselinePosition(true);
- // FIXME: Where is the extra 2-3px adjusted for zoom coming from?
- float zoomFactor = style()->effectiveZoom();
- baseline += static_cast<int>((zoomFactor > 1.25 ? 2 : 3) * zoomFactor);
- }
}
+
+ // FIXME: Where is the extra 2-3px adjusted for zoom coming from?
+ float zoomFactor = style()->effectiveZoom();
+ baseline += static_cast<int>((zoomFactor > 1.25 ? 2 : 3) * zoomFactor);
return baseline;
}
diff --git a/WebCore/notifications/Notification.cpp b/WebCore/notifications/Notification.cpp
index c1edab4..4cb2f85 100644
--- a/WebCore/notifications/Notification.cpp
+++ b/WebCore/notifications/Notification.cpp
@@ -34,6 +34,7 @@
#if ENABLE(NOTIFICATIONS)
#include "Notification.h"
+#include "NotificationCenter.h"
#include "NotificationContents.h"
#include "Document.h"
@@ -45,14 +46,14 @@
namespace WebCore {
-Notification::Notification(const KURL& url, ScriptExecutionContext* context, ExceptionCode& ec, NotificationPresenter* provider)
+Notification::Notification(const KURL& url, ScriptExecutionContext* context, ExceptionCode& ec, PassRefPtr<NotificationCenter> provider)
: ActiveDOMObject(context, this)
, m_isHTML(true)
, m_state(Idle)
- , m_presenter(provider)
+ , m_notificationCenter(provider)
{
- ASSERT(m_presenter);
- if (m_presenter->checkPermission(context) != NotificationPresenter::PermissionAllowed) {
+ ASSERT(m_notificationCenter->presenter());
+ if (m_notificationCenter->presenter()->checkPermission(context) != NotificationPresenter::PermissionAllowed) {
ec = SECURITY_ERR;
return;
}
@@ -65,15 +66,15 @@ Notification::Notification(const KURL& url, ScriptExecutionContext* context, Exc
m_notificationURL = url;
}
-Notification::Notification(const NotificationContents& contents, ScriptExecutionContext* context, ExceptionCode& ec, NotificationPresenter* provider)
+Notification::Notification(const NotificationContents& contents, ScriptExecutionContext* context, ExceptionCode& ec, PassRefPtr<NotificationCenter> provider)
: ActiveDOMObject(context, this)
, m_isHTML(false)
, m_contents(contents)
, m_state(Idle)
- , m_presenter(provider)
+ , m_notificationCenter(provider)
{
- ASSERT(m_presenter);
- if (m_presenter->checkPermission(context) != NotificationPresenter::PermissionAllowed) {
+ ASSERT(m_notificationCenter->presenter());
+ if (m_notificationCenter->presenter()->checkPermission(context) != NotificationPresenter::PermissionAllowed) {
ec = SECURITY_ERR;
return;
}
@@ -92,6 +93,16 @@ Notification::~Notification()
}
}
+PassRefPtr<Notification> Notification::create(const KURL& url, ScriptExecutionContext* context, ExceptionCode& ec, PassRefPtr<NotificationCenter> provider)
+{
+ return adoptRef(new Notification(url, context, ec, provider));
+}
+
+PassRefPtr<Notification> Notification::create(const NotificationContents& contents, ScriptExecutionContext* context, ExceptionCode& ec, PassRefPtr<NotificationCenter> provider)
+{
+ return adoptRef(new Notification(contents, context, ec, provider));
+}
+
void Notification::show()
{
#if PLATFORM(QT)
@@ -100,13 +111,14 @@ void Notification::show()
// handling of ondisplay may rely on that.
if (m_state == Idle) {
m_state = Showing;
- m_presenter->show(this);
+ if (m_notificationCenter->presenter())
+ m_notificationCenter->presenter()->show(this);
}
} else
startLoading();
#else
// prevent double-showing
- if (m_state == Idle && m_presenter->show(this))
+ if (m_state == Idle && m_notificationCenter->presenter() && m_notificationCenter->presenter()->show(this))
m_state = Showing;
#endif
}
@@ -121,7 +133,8 @@ void Notification::cancel()
stopLoading();
break;
case Showing:
- m_presenter->cancel(this);
+ if (m_notificationCenter->presenter())
+ m_notificationCenter->presenter()->cancel(this);
break;
case Cancelled:
break;
@@ -141,8 +154,8 @@ EventTargetData* Notification::ensureEventTargetData()
void Notification::contextDestroyed()
{
ActiveDOMObject::contextDestroyed();
- if (m_presenter)
- m_presenter->notificationObjectDestroyed(this);
+ if (m_notificationCenter->presenter())
+ m_notificationCenter->presenter()->notificationObjectDestroyed(this);
}
void Notification::startLoading()
@@ -205,7 +218,7 @@ void Notification::didReceiveAuthenticationCancellation(const ResourceResponse&)
void Notification::finishLoading()
{
if (m_state == Loading) {
- if (m_presenter->show(this))
+ if (m_notificationCenter->presenter() && m_notificationCenter->presenter()->show(this))
m_state = Showing;
}
unsetPendingActivity(this);
diff --git a/WebCore/notifications/Notification.h b/WebCore/notifications/Notification.h
index e8e29f4..35f9cb8 100644
--- a/WebCore/notifications/Notification.h
+++ b/WebCore/notifications/Notification.h
@@ -55,12 +55,13 @@
#if ENABLE(NOTIFICATIONS)
namespace WebCore {
+ class NotificationCenter;
class WorkerContext;
class Notification : public RefCounted<Notification>, public ActiveDOMObject, public ThreadableLoaderClient, public EventTarget {
public:
- static PassRefPtr<Notification> create(const KURL& url, ScriptExecutionContext* context, ExceptionCode& ec, NotificationPresenter* provider) { return adoptRef(new Notification(url, context, ec, provider)); }
- static PassRefPtr<Notification> create(const NotificationContents& contents, ScriptExecutionContext* context, ExceptionCode& ec, NotificationPresenter* provider) { return adoptRef(new Notification(contents, context, ec, provider)); }
+ static PassRefPtr<Notification> create(const KURL& url, ScriptExecutionContext* context, ExceptionCode& ec, PassRefPtr<NotificationCenter> provider);
+ static PassRefPtr<Notification> create(const NotificationContents& contents, ScriptExecutionContext* context, ExceptionCode& ec, PassRefPtr<NotificationCenter> provider);
virtual ~Notification();
@@ -98,8 +99,8 @@ namespace WebCore {
SharedBuffer* iconData() { return m_iconData.get(); }
void releaseIconData() { m_iconData = 0; }
- // Called if the presenter is deleted before the notification is GC'd
- void detachPresenter() { m_presenter = 0; }
+ // Deprecated. Use functions from NotificationCenter.
+ void detachPresenter() { }
virtual void didReceiveResponse(const ResourceResponse&);
virtual void didReceiveData(const char* data, int lengthReceived);
@@ -109,8 +110,8 @@ namespace WebCore {
virtual void didReceiveAuthenticationCancellation(const ResourceResponse&);
private:
- Notification(const KURL&, ScriptExecutionContext*, ExceptionCode&, NotificationPresenter*);
- Notification(const NotificationContents&, ScriptExecutionContext*, ExceptionCode&, NotificationPresenter*);
+ Notification(const KURL&, ScriptExecutionContext*, ExceptionCode&, PassRefPtr<NotificationCenter>);
+ Notification(const NotificationContents&, ScriptExecutionContext*, ExceptionCode&, PassRefPtr<NotificationCenter>);
// EventTarget interface
virtual void refEventTarget() { ref(); }
@@ -137,7 +138,7 @@ namespace WebCore {
NotificationState m_state;
- NotificationPresenter* m_presenter;
+ RefPtr<NotificationCenter> m_notificationCenter;
EventTargetData m_eventTargetData;
diff --git a/WebCore/notifications/NotificationCenter.h b/WebCore/notifications/NotificationCenter.h
index 349e8a4..adad59d 100644
--- a/WebCore/notifications/NotificationCenter.h
+++ b/WebCore/notifications/NotificationCenter.h
@@ -58,7 +58,7 @@ namespace WebCore {
ec = SYNTAX_ERR;
return 0;
}
- return Notification::create(m_scriptExecutionContext->completeURL(URI), context(), ec, presenter());
+ return Notification::create(m_scriptExecutionContext->completeURL(URI), context(), ec, this);
}
PassRefPtr<Notification> createNotification(const String& iconURI, const String& title, const String& body, ExceptionCode& ec)
@@ -68,7 +68,7 @@ namespace WebCore {
return 0;
}
NotificationContents contents(iconURI.isEmpty() ? KURL() : m_scriptExecutionContext->completeURL(iconURI), title, body);
- return Notification::create(contents, context(), ec, presenter());
+ return Notification::create(contents, context(), ec, this);
}
ScriptExecutionContext* context() const { return m_scriptExecutionContext; }
diff --git a/WebCore/page/FocusController.cpp b/WebCore/page/FocusController.cpp
index 388aa09..2c2c447 100644
--- a/WebCore/page/FocusController.cpp
+++ b/WebCore/page/FocusController.cpp
@@ -620,11 +620,14 @@ bool FocusController::setFocusedNode(Node* node, PassRefPtr<Frame> newFocusedFra
oldDocument->setFocusedNode(0);
setFocusedFrame(newFocusedFrame);
-
+
+ // Setting the focused node can result in losing our last reft to node when JS event handlers fire.
+ RefPtr<Node> protect = node;
if (newDocument)
newDocument->setFocusedNode(node);
-
- m_page->editorClient()->setInputMethodState(node->shouldUseInputMethod());
+
+ if (newDocument->focusedNode() == node)
+ m_page->editorClient()->setInputMethodState(node->shouldUseInputMethod());
return true;
}
diff --git a/WebCore/page/Frame.cpp b/WebCore/page/Frame.cpp
index 17652d9..c23368a 100644
--- a/WebCore/page/Frame.cpp
+++ b/WebCore/page/Frame.cpp
@@ -241,9 +241,11 @@ void Frame::setView(PassRefPtr<FrameView> view)
if (!view && m_doc && m_doc->attached() && !m_doc->inPageCache()) {
// FIXME: We don't call willRemove here. Why is that OK?
m_doc->detach();
- if (m_view)
- m_view->unscheduleRelayout();
}
+
+ if (m_view)
+ m_view->unscheduleRelayout();
+
eventHandler()->clear();
m_view = view;
@@ -1086,8 +1088,10 @@ void Frame::revealSelection(const ScrollAlignment& alignment, bool revealExtent)
// FIXME: This code only handles scrolling the startContainer's layer, but
// the selection rect could intersect more than just that.
// See <rdar://problem/4799899>.
- if (RenderLayer* layer = start.node()->renderer()->enclosingLayer())
+ if (RenderLayer* layer = start.node()->renderer()->enclosingLayer()) {
layer->scrollRectToVisible(rect, false, alignment, alignment);
+ selection()->updateAppearance();
+ }
}
}
@@ -1281,7 +1285,7 @@ unsigned Frame::markAllMatchesForText(const String& target, bool caseFlag, unsig
// Only treat the result as a match if it is visible
if (editor()->insideVisibleArea(resultRange.get())) {
++matchCount;
- document()->addMarker(resultRange.get(), DocumentMarker::TextMatch);
+ document()->markers()->addMarker(resultRange.get(), DocumentMarker::TextMatch);
}
// Stop looking if we hit the specified limit. A limit of 0 means no limit.
@@ -1321,7 +1325,7 @@ void Frame::setMarkedTextMatchesAreHighlighted(bool flag)
return;
m_highlightTextMatches = flag;
- document()->repaintMarkers(DocumentMarker::TextMatch);
+ document()->markers()->repaintMarkers(DocumentMarker::TextMatch);
}
void Frame::setDOMWindow(DOMWindow* domWindow)
@@ -1467,16 +1471,16 @@ void Frame::respondToChangedSelection(const VisibleSelection& oldSelection, bool
// This only erases markers that are in the first unit (word or sentence) of the selection.
// Perhaps peculiar, but it matches AppKit.
if (RefPtr<Range> wordRange = newAdjacentWords.toNormalizedRange())
- document()->removeMarkers(wordRange.get(), DocumentMarker::Spelling);
+ document()->markers()->removeMarkers(wordRange.get(), DocumentMarker::Spelling);
if (RefPtr<Range> sentenceRange = newSelectedSentence.toNormalizedRange())
- document()->removeMarkers(sentenceRange.get(), DocumentMarker::Grammar);
+ document()->markers()->removeMarkers(sentenceRange.get(), DocumentMarker::Grammar);
}
// When continuous spell checking is off, existing markers disappear after the selection changes.
if (!isContinuousSpellCheckingEnabled)
- document()->removeMarkers(DocumentMarker::Spelling);
+ document()->markers()->removeMarkers(DocumentMarker::Spelling);
if (!isContinuousGrammarCheckingEnabled)
- document()->removeMarkers(DocumentMarker::Grammar);
+ document()->markers()->removeMarkers(DocumentMarker::Grammar);
editor()->respondToChangedSelection(oldSelection);
}
@@ -1612,7 +1616,11 @@ String Frame::layerTreeAsText() const
if (!contentRenderer())
return String();
- GraphicsLayer* rootLayer = contentRenderer()->compositor()->rootPlatformLayer();
+ RenderLayerCompositor* compositor = contentRenderer()->compositor();
+ if (compositor->compositingLayerUpdatePending())
+ compositor->updateCompositingLayers();
+
+ GraphicsLayer* rootLayer = compositor->rootPlatformLayer();
if (!rootLayer)
return String();
diff --git a/WebCore/page/Frame.h b/WebCore/page/Frame.h
index 4e522c4..36803f8 100644
--- a/WebCore/page/Frame.h
+++ b/WebCore/page/Frame.h
@@ -221,6 +221,7 @@ namespace WebCore {
void textWillBeDeletedInTextField(Element* input);
void textDidChangeInTextArea(Element*);
+ DragImageRef nodeImage(Node*);
DragImageRef dragImageForSelection();
// === to be moved into SelectionController
@@ -285,7 +286,6 @@ namespace WebCore {
NSImage* selectionImage(bool forceBlackText = false) const;
NSImage* snapshotDragImage(Node*, NSRect* imageRect, NSRect* elementRect) const;
- NSImage* nodeImage(Node*) const;
private:
NSImage* imageFromRect(NSRect) const;
@@ -298,14 +298,6 @@ namespace WebCore {
#endif
-#if PLATFORM(WIN)
-
- public:
- // FIXME - We should have a single version of nodeImage instead of using platform types.
- HBITMAP nodeImage(Node*) const;
-
-#endif
-
private:
Page* m_page;
mutable FrameTree m_treeNode;
diff --git a/WebCore/page/FrameView.cpp b/WebCore/page/FrameView.cpp
index 441e543..831ea86 100644
--- a/WebCore/page/FrameView.cpp
+++ b/WebCore/page/FrameView.cpp
@@ -212,7 +212,7 @@ void FrameView::reset()
m_delayedLayout = false;
m_doFullRepaint = true;
m_layoutSchedulingEnabled = true;
- m_midLayout = false;
+ m_inLayout = false;
m_layoutCount = 0;
m_nestedLayoutCount = 0;
m_postLayoutTasksTimer.stop();
@@ -609,7 +609,7 @@ RenderObject* FrameView::layoutRoot(bool onlyDuringLayout) const
void FrameView::layout(bool allowSubtree)
{
- if (m_midLayout)
+ if (m_inLayout)
return;
m_layoutTimer.stop();
@@ -642,11 +642,6 @@ void FrameView::layout(bool allowSubtree)
}
ASSERT(m_frame->view() == this);
- // This early return should be removed when rdar://5598072 is resolved. In the meantime, there is a
- // gigantic CrashTracer because of this issue, and the early return will hopefully cause graceful
- // failure instead.
- if (m_frame->view() != this)
- return;
Document* document = m_frame->document();
@@ -788,11 +783,11 @@ void FrameView::layout(bool allowSubtree)
view->disableLayoutState();
}
- m_midLayout = true;
+ m_inLayout = true;
beginDeferredRepaints();
root->layout();
endDeferredRepaints();
- m_midLayout = false;
+ m_inLayout = false;
if (subtree) {
RenderView* view = root->view();
@@ -802,7 +797,7 @@ void FrameView::layout(bool allowSubtree)
}
m_layoutRoot = 0;
- m_frame->selection()->setNeedsLayout();
+ m_frame->selection()->setCaretRectNeedsUpdate();
m_frame->selection()->updateAppearance();
m_layoutSchedulingEnabled = true;
@@ -1016,6 +1011,7 @@ bool FrameView::scrollContentsFastPath(const IntSize& scrollDelta, const IntRect
return false;
}
+// Note that this gets called at painting time.
void FrameView::setIsOverlapped(bool isOverlapped)
{
if (isOverlapped == m_isOverlapped)
@@ -1026,10 +1022,15 @@ void FrameView::setIsOverlapped(bool isOverlapped)
#if USE(ACCELERATED_COMPOSITING)
// Overlap can affect compositing tests, so if it changes, we need to trigger
- // a recalcStyle in the parent document.
+ // a layer update in the parent document.
if (hasCompositedContent()) {
- if (Element* ownerElement = m_frame->document()->ownerElement())
- ownerElement->setNeedsStyleRecalc(SyntheticStyleChange);
+ if (Frame* parentFrame = m_frame->tree()->parent()) {
+ if (RenderView* parentView = parentFrame->contentRenderer()) {
+ RenderLayerCompositor* compositor = parentView->compositor();
+ compositor->setCompositingLayersNeedRebuild();
+ compositor->scheduleCompositingLayerUpdate();
+ }
+ }
}
#endif
}
@@ -1781,7 +1782,7 @@ void FrameView::invalidateScrollbarRect(Scrollbar* scrollbar, const IntRect& rec
void FrameView::getTickmarks(Vector<IntRect>& tickmarks) const
{
- tickmarks = frame()->document()->renderedRectsForMarkers(DocumentMarker::TextMatch);
+ tickmarks = frame()->document()->markers()->renderedRectsForMarkers(DocumentMarker::TextMatch);
}
IntRect FrameView::windowResizerRect() const
@@ -1988,7 +1989,7 @@ void FrameView::paintContents(GraphicsContext* p, const IntRect& rect)
PaintBehavior oldPaintBehavior = m_paintBehavior;
if (m_paintBehavior == PaintBehaviorNormal)
- document->invalidateRenderedRectsForMarkersInRect(rect);
+ document->markers()->invalidateRenderedRectsForMarkersInRect(rect);
if (document->printing())
m_paintBehavior |= PaintBehaviorFlattenCompositingLayers;
diff --git a/WebCore/page/FrameView.h b/WebCore/page/FrameView.h
index cc32404..47dff43 100644
--- a/WebCore/page/FrameView.h
+++ b/WebCore/page/FrameView.h
@@ -88,6 +88,7 @@ public:
void scheduleRelayoutOfSubtree(RenderObject*);
void unscheduleRelayout();
bool layoutPending() const;
+ bool isInLayout() const { return m_inLayout; }
RenderObject* layoutRoot(bool onlyDuringLayout = false) const;
int layoutCount() const { return m_layoutCount; }
@@ -317,7 +318,7 @@ private:
RenderObject* m_layoutRoot;
bool m_layoutSchedulingEnabled;
- bool m_midLayout;
+ bool m_inLayout;
int m_layoutCount;
unsigned m_nestedLayoutCount;
Timer<FrameView> m_postLayoutTasksTimer;
diff --git a/WebCore/page/Geolocation.cpp b/WebCore/page/Geolocation.cpp
index 9a5e40b..19eff4a 100644
--- a/WebCore/page/Geolocation.cpp
+++ b/WebCore/page/Geolocation.cpp
@@ -693,14 +693,6 @@ void Geolocation::stopUpdating()
#if USE(PREEMPT_GEOLOCATION_PERMISSION)
void Geolocation::handlePendingPermissionNotifiers()
{
-#if ENABLE(CLIENT_BASED_GEOLOCATION)
- if (!m_frame)
- return;
- Page* page = m_frame->page();
- if (!page)
- return;
-#endif
-
// While we iterate through the list, we need not worry about list being modified as the permission
// is already set to Yes/No and no new listeners will be added to the pending list
GeoNotifierSet::const_iterator end = m_pendingForPermissionNotifiers.end();
@@ -710,12 +702,10 @@ void Geolocation::handlePendingPermissionNotifiers()
if (isAllowed()) {
// start all pending notification requests as permission granted.
// The notifier is always ref'ed by m_oneShots or m_watchers.
-#if ENABLE(CLIENT_BASED_GEOLOCATION)
- notifier->startTimerIfNeeded();
- page->geolocationController()->addObserver(this, notifier->m_options->enableHighAccuracy());
-#else
- // TODO: Handle startUpdate() for non-client based implementations using pre-emptive policy
-#endif
+ if (startUpdating(notifier))
+ notifier->startTimerIfNeeded();
+ else
+ notifier->setFatalError(PositionError::create(PositionError::POSITION_UNAVAILABLE, failedToStartServiceErrorMessage));
} else
notifier->setFatalError(PositionError::create(PositionError::PERMISSION_DENIED, permissionDeniedErrorMessage));
}
diff --git a/WebCore/page/Page.cpp b/WebCore/page/Page.cpp
index 63decd7..b8abb54 100644
--- a/WebCore/page/Page.cpp
+++ b/WebCore/page/Page.cpp
@@ -558,7 +558,7 @@ void Page::unmarkAllTextMatches()
Frame* frame = mainFrame();
do {
- frame->document()->removeMarkers(DocumentMarker::TextMatch);
+ frame->document()->markers()->removeMarkers(DocumentMarker::TextMatch);
frame = incrementFrame(frame, true, false);
} while (frame);
}
diff --git a/WebCore/page/PageGroup.h b/WebCore/page/PageGroup.h
index 6a3518e..fcad773 100644
--- a/WebCore/page/PageGroup.h
+++ b/WebCore/page/PageGroup.h
@@ -74,6 +74,7 @@ namespace WebCore {
#endif
#if ENABLE(INDEXED_DATABASE)
IDBFactoryBackendInterface* idbFactory();
+ bool hasIDBFactory() { return m_factoryBackend; }
#endif
void addUserScriptToWorld(DOMWrapperWorld*, const String& source, const KURL&,
diff --git a/WebCore/page/SecurityOrigin.cpp b/WebCore/page/SecurityOrigin.cpp
index f759402..5b51501 100644
--- a/WebCore/page/SecurityOrigin.cpp
+++ b/WebCore/page/SecurityOrigin.cpp
@@ -29,6 +29,7 @@
#include "config.h"
#include "SecurityOrigin.h"
+#include "BlobURL.h"
#include "Document.h"
#include "FileSystem.h"
#include "KURL.h"
@@ -123,6 +124,10 @@ PassRefPtr<SecurityOrigin> SecurityOrigin::create(const KURL& url, SandboxFlags
{
if (!url.isValid())
return adoptRef(new SecurityOrigin(KURL(), sandboxFlags));
+#if ENABLE(BLOB)
+ if (url.protocolIs("blob"))
+ return adoptRef(new SecurityOrigin(BlobURL::getOrigin(url), sandboxFlags));
+#endif
return adoptRef(new SecurityOrigin(url, sandboxFlags));
}
@@ -275,6 +280,14 @@ bool SecurityOrigin::isAccessWhiteListed(const SecurityOrigin* targetOrigin) con
bool SecurityOrigin::canLoad(const KURL& url, const String& referrer, Document* document)
{
+#if ENABLE(BLOB)
+ if (url.protocolIs("blob") && document) {
+ SecurityOrigin* documentOrigin = document->securityOrigin();
+ RefPtr<SecurityOrigin> targetOrigin = SecurityOrigin::create(url);
+ return documentOrigin->isSameSchemeHostPort(targetOrigin.get());
+ }
+#endif
+
if (!SchemeRegistry::shouldTreatURLAsLocal(url.string()))
return true;
diff --git a/WebCore/page/Settings.cpp b/WebCore/page/Settings.cpp
index 06dcd49..a7ca533 100644
--- a/WebCore/page/Settings.cpp
+++ b/WebCore/page/Settings.cpp
@@ -144,8 +144,6 @@ Settings::Settings(Page* page)
, m_acceleratedCanvas2dEnabled(false)
, m_loadDeferringEnabled(true)
, m_tiledBackingStoreEnabled(false)
- , m_html5ParserEnabled(true)
- , m_html5TreeBuilderEnabled(false) // Will be deleted soon, do not use.
, m_paginateDuringLayoutEnabled(false)
, m_dnsPrefetchingEnabled(true)
, m_memoryInfoEnabled(false)
diff --git a/WebCore/page/Settings.h b/WebCore/page/Settings.h
index d048c34..0048598 100644
--- a/WebCore/page/Settings.h
+++ b/WebCore/page/Settings.h
@@ -376,16 +376,6 @@ namespace WebCore {
void setTiledBackingStoreEnabled(bool);
bool tiledBackingStoreEnabled() const { return m_tiledBackingStoreEnabled; }
- void setHTML5ParserEnabled(bool flag) { m_html5ParserEnabled = flag; }
- bool html5ParserEnabled() const { return m_html5ParserEnabled; }
-
- // NOTE: This code will be deleted once the HTML5TreeBuilder is ready
- // to replace LegacyHTMLTreeBuilder. Using the HTML5DocumentParser
- // with LegacyHTMLTreeBuilder will not be supported long-term.
- // Setting is only for testing the new tree builder in DumpRenderTree.
- void setHTML5TreeBuilderEnabled_DO_NOT_USE(bool flag) { m_html5TreeBuilderEnabled = flag; }
- bool html5TreeBuilderEnabled() const { return m_html5TreeBuilderEnabled; }
-
void setPaginateDuringLayoutEnabled(bool flag) { m_paginateDuringLayoutEnabled = flag; }
bool paginateDuringLayoutEnabled() const { return m_paginateDuringLayoutEnabled; }
@@ -516,8 +506,6 @@ namespace WebCore {
bool m_acceleratedCanvas2dEnabled : 1;
bool m_loadDeferringEnabled : 1;
bool m_tiledBackingStoreEnabled : 1;
- bool m_html5ParserEnabled: 1;
- bool m_html5TreeBuilderEnabled: 1; // Will be deleted soon, do not use.
bool m_paginateDuringLayoutEnabled : 1;
bool m_dnsPrefetchingEnabled : 1;
bool m_memoryInfoEnabled: 1;
diff --git a/WebCore/page/SpeechInput.cpp b/WebCore/page/SpeechInput.cpp
index 24b52d2..234791b 100644
--- a/WebCore/page/SpeechInput.cpp
+++ b/WebCore/page/SpeechInput.cpp
@@ -93,10 +93,10 @@ void SpeechInput::setRecognitionResult(int listenerId, const String& result)
m_listeners.get(listenerId)->setRecognitionResult(listenerId, result);
}
-bool SpeechInput::startRecognition(int listenerId)
+bool SpeechInput::startRecognition(int listenerId, const IntRect& elementRect)
{
ASSERT(m_listeners.contains(listenerId));
- return m_client->startRecognition(listenerId);
+ return m_client->startRecognition(listenerId, elementRect);
}
void SpeechInput::stopRecording(int listenerId)
diff --git a/WebCore/page/SpeechInput.h b/WebCore/page/SpeechInput.h
index f36194c..d10b789 100644
--- a/WebCore/page/SpeechInput.h
+++ b/WebCore/page/SpeechInput.h
@@ -40,6 +40,7 @@
namespace WebCore {
+class IntRect;
class SpeechInputClient;
class SpeechInputListener;
@@ -60,7 +61,7 @@ public:
void unregisterListener(int);
// Methods invoked by the input elements.
- bool startRecognition(int);
+ bool startRecognition(int, const IntRect&);
void stopRecording(int);
void cancelRecognition(int);
diff --git a/WebCore/page/SpeechInputClient.h b/WebCore/page/SpeechInputClient.h
index 87ff7b9..d5fda17 100644
--- a/WebCore/page/SpeechInputClient.h
+++ b/WebCore/page/SpeechInputClient.h
@@ -35,6 +35,7 @@
namespace WebCore {
+class IntRect;
class SpeechInputListener;
// Provides an interface for SpeechInput to call into the embedder.
@@ -47,7 +48,7 @@ public:
virtual void setListener(SpeechInputListener*) = 0;
// Starts speech recognition and audio recording.
- virtual bool startRecognition(int requestId) = 0;
+ virtual bool startRecognition(int requestId, const IntRect& elementRect) = 0;
// Stops audio recording and performs recognition with the audio recorded until now
// (does not discard audio).
diff --git a/WebCore/page/brew/FrameBrew.cpp b/WebCore/page/brew/FrameBrew.cpp
index a590544..7825dbd 100644
--- a/WebCore/page/brew/FrameBrew.cpp
+++ b/WebCore/page/brew/FrameBrew.cpp
@@ -29,6 +29,12 @@
namespace WebCore {
+DragImageRef Frame::nodeImage(Node*)
+{
+ notImplemented();
+ return 0;
+}
+
DragImageRef Frame::dragImageForSelection()
{
notImplemented();
diff --git a/WebCore/page/chromium/FrameChromium.cpp b/WebCore/page/chromium/FrameChromium.cpp
index 548e0fa..4146b39 100644
--- a/WebCore/page/chromium/FrameChromium.cpp
+++ b/WebCore/page/chromium/FrameChromium.cpp
@@ -28,19 +28,91 @@
#include "Document.h"
#include "FloatRect.h"
+#include "ImageBuffer.h"
#include "RenderView.h"
#include "Settings.h"
-using std::min;
-
namespace WebCore {
+namespace {
+
+struct ScopedState {
+ ScopedState(Frame* theFrame, RenderObject* theRenderer)
+ : frame(theFrame)
+ , renderer(theRenderer)
+ , paintBehavior(frame->view()->paintBehavior())
+ , backgroundColor(frame->view()->baseBackgroundColor())
+ {
+ }
+
+ ~ScopedState()
+ {
+ if (renderer)
+ renderer->updateDragState(false);
+ frame->view()->setPaintBehavior(paintBehavior);
+ frame->view()->setBaseBackgroundColor(backgroundColor);
+ frame->view()->setNodeToDraw(0);
+ }
+
+ Frame* frame;
+ RenderObject* renderer;
+ PaintBehavior paintBehavior;
+ Color backgroundColor;
+};
+
+} // namespace
+
+DragImageRef Frame::nodeImage(Node* node)
+{
+ RenderObject* renderer = node->renderer();
+ if (!renderer)
+ return 0;
+
+ const ScopedState state(this, renderer);
+
+ renderer->updateDragState(true);
+ m_view->setPaintBehavior(state.paintBehavior | PaintBehaviorFlattenCompositingLayers);
+ // When generating the drag image for an element, ignore the document background.
+ m_view->setBaseBackgroundColor(colorWithOverrideAlpha(Color::white, 1.0));
+ m_doc->updateLayout();
+ m_view->setNodeToDraw(node); // Enable special sub-tree drawing mode.
+
+ IntRect topLevelRect;
+ IntRect paintingRect = renderer->paintingRootRect(topLevelRect);
+
+ OwnPtr<ImageBuffer> buffer(ImageBuffer::create(paintingRect.size()));
+ if (!buffer)
+ return 0;
+ buffer->context()->translate(-paintingRect.x(), -paintingRect.y());
+ buffer->context()->clip(FloatRect(0, 0, paintingRect.right(), paintingRect.bottom()));
+
+ m_view->paint(buffer->context(), paintingRect);
+
+ RefPtr<Image> image = buffer->copyImage();
+ return createDragImageFromImage(image.get());
+}
+
DragImageRef Frame::dragImageForSelection()
-{
- if (selection()->isRange())
- return 0; // FIXME: implement me!
+{
+ if (!selection()->isRange())
+ return 0;
+
+ const ScopedState state(this, 0);
+ m_view->setPaintBehavior(PaintBehaviorSelectionOnly);
+ m_doc->updateLayout();
+
+ IntRect paintingRect = enclosingIntRect(selectionBounds());
+
+ OwnPtr<ImageBuffer> buffer(ImageBuffer::create(paintingRect.size()));
+ if (!buffer)
+ return 0;
+ buffer->context()->translate(-paintingRect.x(), -paintingRect.y());
+ buffer->context()->clip(FloatRect(0, 0, paintingRect.right(), paintingRect.bottom()));
+
+ m_view->paint(buffer->context(), paintingRect);
- return 0;
+ RefPtr<Image> image = buffer->copyImage();
+ return createDragImageFromImage(image.get());
}
} // namespace WebCore
diff --git a/WebCore/page/efl/FrameEfl.cpp b/WebCore/page/efl/FrameEfl.cpp
index 783df7e..b1be9ca 100644
--- a/WebCore/page/efl/FrameEfl.cpp
+++ b/WebCore/page/efl/FrameEfl.cpp
@@ -32,6 +32,12 @@
namespace WebCore {
+DragImageRef Frame::nodeImage(Node* node)
+{
+ notImplemented();
+ return 0;
+}
+
DragImageRef Frame::dragImageForSelection()
{
notImplemented();
diff --git a/WebCore/page/gtk/FrameGtk.cpp b/WebCore/page/gtk/FrameGtk.cpp
index 3cab5a0..14a0f8b 100644
--- a/WebCore/page/gtk/FrameGtk.cpp
+++ b/WebCore/page/gtk/FrameGtk.cpp
@@ -28,6 +28,12 @@
namespace WebCore {
+DragImageRef Frame::nodeImage(Node*)
+{
+ notImplemented();
+ return 0;
+}
+
DragImageRef Frame::dragImageForSelection()
{
notImplemented();
diff --git a/WebCore/page/haiku/FrameHaiku.cpp b/WebCore/page/haiku/FrameHaiku.cpp
index 50168dd..5ff6950 100644
--- a/WebCore/page/haiku/FrameHaiku.cpp
+++ b/WebCore/page/haiku/FrameHaiku.cpp
@@ -33,6 +33,12 @@
namespace WebCore {
+DragImageRef Frame::nodeImage(Node*)
+{
+ notImplemented();
+ return 0;
+}
+
DragImageRef Frame::dragImageForSelection()
{
notImplemented();
@@ -40,4 +46,3 @@ DragImageRef Frame::dragImageForSelection()
}
} // namespace WebCore
-
diff --git a/WebCore/page/mac/FrameMac.mm b/WebCore/page/mac/FrameMac.mm
index bb11ac9..0365784 100644
--- a/WebCore/page/mac/FrameMac.mm
+++ b/WebCore/page/mac/FrameMac.mm
@@ -380,7 +380,7 @@ NSImage* Frame::snapshotDragImage(Node* node, NSRect* imageRect, NSRect* element
return result;
}
-NSImage* Frame::nodeImage(Node* node) const
+DragImageRef Frame::nodeImage(Node* node)
{
RenderObject* renderer = node->renderer();
if (!renderer)
@@ -535,7 +535,7 @@ NSMutableDictionary* Frame::dashboardRegionsDictionary()
}
#endif
-DragImageRef Frame::dragImageForSelection()
+DragImageRef Frame::dragImageForSelection()
{
if (!selection()->isRange())
return nil;
diff --git a/WebCore/page/qt/FrameQt.cpp b/WebCore/page/qt/FrameQt.cpp
index 493e60d..ed75eb8 100644
--- a/WebCore/page/qt/FrameQt.cpp
+++ b/WebCore/page/qt/FrameQt.cpp
@@ -24,10 +24,19 @@
#include "config.h"
#include "Frame.h"
+#include "NotImplemented.h"
+
namespace WebCore {
-DragImageRef Frame::dragImageForSelection()
+DragImageRef Frame::nodeImage(Node*)
+{
+ notImplemented();
+ return 0;
+}
+
+DragImageRef Frame::dragImageForSelection()
{
+ notImplemented();
return 0;
}
diff --git a/WebCore/page/win/FrameCGWin.cpp b/WebCore/page/win/FrameCGWin.cpp
index cce5004..b61deef 100644
--- a/WebCore/page/win/FrameCGWin.cpp
+++ b/WebCore/page/win/FrameCGWin.cpp
@@ -95,7 +95,7 @@ HBITMAP imageFromSelection(Frame* frame, bool forceBlackText)
return image;
}
-HBITMAP Frame::nodeImage(Node* node) const
+DragImageRef Frame::nodeImage(Node* node)
{
RenderObject* renderer = node->renderer();
if (!renderer)
diff --git a/WebCore/page/win/FrameCairoWin.cpp b/WebCore/page/win/FrameCairoWin.cpp
index 3e1fe28..f843ba1 100644
--- a/WebCore/page/win/FrameCairoWin.cpp
+++ b/WebCore/page/win/FrameCairoWin.cpp
@@ -40,7 +40,7 @@ HBITMAP imageFromSelection(Frame* frame, bool forceBlackText)
return 0;
}
-HBITMAP Frame::nodeImage(Node*) const
+DragImageRef Frame::nodeImage(Node*)
{
notImplemented();
return 0;
diff --git a/WebCore/page/wince/FrameWince.cpp b/WebCore/page/wince/FrameWince.cpp
index c806b98..7cfbae0 100644
--- a/WebCore/page/wince/FrameWince.cpp
+++ b/WebCore/page/wince/FrameWince.cpp
@@ -35,6 +35,7 @@
#include "HTMLNames.h"
#include "HTMLTableCellElement.h"
#include "KeyboardEvent.h"
+#include "NotImplemented.h"
#include "Page.h"
#include "RenderFrame.h"
#include "RenderLayer.h"
@@ -147,6 +148,12 @@ HBITMAP imageFromSelection(Frame* frame, bool forceBlackText)
return hBmp;
}
+DragImageRef Frame::nodeImage(Node*)
+{
+ notImplemented();
+ return 0;
+}
+
DragImageRef Frame::dragImageForSelection()
{
if (selection()->isRange())
diff --git a/WebCore/page/wx/FrameWx.cpp b/WebCore/page/wx/FrameWx.cpp
index b220694..6c16adc 100644
--- a/WebCore/page/wx/FrameWx.cpp
+++ b/WebCore/page/wx/FrameWx.cpp
@@ -29,6 +29,12 @@
namespace WebCore {
+DragImageRef Frame::nodeImage(Node*)
+{
+ notImplemented();
+ return 0;
+}
+
DragImageRef Frame::dragImageForSelection()
{
notImplemented();
diff --git a/WebCore/platform/AsyncFileStream.h b/WebCore/platform/AsyncFileStream.h
new file mode 100644
index 0000000..3abda01
--- /dev/null
+++ b/WebCore/platform/AsyncFileStream.h
@@ -0,0 +1,74 @@
+/*
+ * Copyright (C) 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 AsyncFileStream_h
+#define AsyncFileStream_h
+
+#if ENABLE(BLOB) || ENABLE(FILE_WRITER)
+
+#include "FileStreamClient.h"
+#include <wtf/Forward.h>
+#include <wtf/RefCounted.h>
+
+namespace WebCore {
+
+class KURL;
+
+class AsyncFileStream : public RefCounted<AsyncFileStream> {
+public:
+ virtual ~AsyncFileStream() { }
+
+ virtual void getSize(const String& path, double expectedModificationTime) = 0;
+ virtual void openForRead(const String& path, long long offset, long long length) = 0;
+ virtual void openForWrite(const String& path) = 0;
+ virtual void close() = 0;
+ virtual void read(char* buffer, int length) = 0;
+ virtual void write(const KURL& blobURL, long long position, int length) = 0;
+ virtual void truncate(long long position) = 0;
+ virtual void stop() = 0;
+
+ FileStreamClient* client() const { return m_client; }
+ void setClient(FileStreamClient* client) { m_client = client; }
+
+protected:
+ AsyncFileStream(FileStreamClient* client)
+ : m_client(client)
+ {
+ }
+
+private:
+ FileStreamClient* m_client;
+};
+
+} // namespace WebCore
+
+#endif // ENABLE(BLOB) || ENABLE(FILE_WRITER)
+
+#endif // AsyncFileStream_h
diff --git a/WebCore/platform/ContextMenu.cpp b/WebCore/platform/ContextMenu.cpp
index 84a2ffc..37d4c2b 100644
--- a/WebCore/platform/ContextMenu.cpp
+++ b/WebCore/platform/ContextMenu.cpp
@@ -584,6 +584,10 @@ void ContextMenu::checkOrEnableIfNeeded(ContextMenuItem& item) const
if (!frame)
return;
+ // Custom items already have proper checked and enabled values.
+ if (ContextMenuItemBaseCustomTag <= item.action() && item.action() <= ContextMenuItemLastCustomTag)
+ return;
+
bool shouldEnable = true;
bool shouldCheck = false;
diff --git a/WebCore/platform/Cursor.h b/WebCore/platform/Cursor.h
index 5e547ef..92d3596 100644
--- a/WebCore/platform/Cursor.h
+++ b/WebCore/platform/Cursor.h
@@ -62,7 +62,7 @@ typedef struct HICON__ *HICON;
typedef HICON HCURSOR;
#endif
-#if PLATFORM(WIN) || PLATFORM(MAC) || PLATFORM(GTK)
+#if PLATFORM(WIN) || PLATFORM(MAC) || PLATFORM(GTK) || PLATFORM(QT)
#define WTF_USE_LAZY_NATIVE_CURSOR 1
#endif
@@ -84,11 +84,12 @@ namespace WebCore {
#elif PLATFORM(MAC)
typedef NSCursor* PlatformCursor;
#elif PLATFORM(GTK)
- typedef GRefPtr<GdkCursor> PlatformCursor;
+ typedef PlatformRefPtr<GdkCursor> PlatformCursor;
#elif PLATFORM(EFL)
typedef const char* PlatformCursor;
#elif PLATFORM(QT) && !defined(QT_NO_CURSOR)
- typedef QCursor PlatformCursor;
+ // Do not need to be shared but need to be created dynamically via ensurePlatformCursor.
+ typedef QCursor* PlatformCursor;
#elif PLATFORM(WX)
typedef wxCursor* PlatformCursor;
#elif PLATFORM(CHROMIUM)
@@ -151,7 +152,7 @@ namespace WebCore {
static const Cursor& fromType(Cursor::Type);
Cursor()
-#if !PLATFORM(QT) && !PLATFORM(EFL)
+#if !PLATFORM(EFL)
: m_platformCursor(0)
#endif
{
diff --git a/WebCore/html/FileStream.cpp b/WebCore/platform/FileStream.cpp
index a89c67a..45f435e 100644
--- a/WebCore/html/FileStream.cpp
+++ b/WebCore/platform/FileStream.cpp
@@ -34,7 +34,6 @@
#include "FileStream.h"
-#include "Blob.h"
#include "PlatformString.h"
namespace WebCore {
@@ -80,32 +79,32 @@ long long FileStream::getSize(const String& path, double expectedModificationTim
return length;
}
-ExceptionCode FileStream::openForRead(const String& path, long long offset, long long length)
+bool FileStream::openForRead(const String& path, long long offset, long long length)
{
if (isHandleValid(m_handle))
- return 0;
+ return true;
// Open the file.
m_handle = openFile(path, OpenForRead);
if (!isHandleValid(m_handle))
- return NOT_READABLE_ERR;
+ return false;
// Jump to the beginning position if the file has been sliced.
if (offset > 0) {
if (seekFile(m_handle, offset, SeekFromBeginning) < 0)
- return NOT_READABLE_ERR;
+ return false;
}
m_totalBytesToRead = length;
m_bytesProcessed = 0;
- return 0;
+ return true;
}
-ExceptionCode FileStream::openForWrite(const String&)
+bool FileStream::openForWrite(const String&)
{
// FIXME: to be implemented.
- return NOT_SUPPORTED_ERR;
+ return false;
}
void FileStream::close()
@@ -134,16 +133,16 @@ int FileStream::read(char* buffer, int bufferSize)
return bytesRead;
}
-int FileStream::write(Blob*, long long, int)
+int FileStream::write(const KURL&, long long, int)
{
// FIXME: to be implemented.
return -1;
}
-ExceptionCode FileStream::truncate(long long)
+bool FileStream::truncate(long long)
{
// FIXME: to be implemented.
- return NOT_SUPPORTED_ERR;
+ return false;
}
} // namespace WebCore
diff --git a/WebCore/html/FileStream.h b/WebCore/platform/FileStream.h
index e299fe4..6c3a221 100644
--- a/WebCore/html/FileStream.h
+++ b/WebCore/platform/FileStream.h
@@ -33,7 +33,6 @@
#if ENABLE(BLOB) || ENABLE(FILE_WRITER)
-#include "ExceptionCode.h"
#include "FileSystem.h"
#include <wtf/Forward.h>
#include <wtf/PassRefPtr.h>
@@ -41,7 +40,7 @@
namespace WebCore {
-class Blob;
+class KURL;
// All methods are synchronous.
class FileStream : public RefCounted<FileStream> {
@@ -50,7 +49,7 @@ public:
{
return adoptRef(new FileStream());
}
- virtual ~FileStream();
+ ~FileStream();
// FIXME: To be removed when we switch to using BlobData.
void start();
@@ -63,12 +62,12 @@ public:
long long getSize(const String& path, double expectedModificationTime);
// Opens a file for reading. The reading starts at the specified offset and lasts till the specified length.
- // Returns 0 on success. Exception code otherwise.
- ExceptionCode openForRead(const String& path, long long offset, long long length);
+ // Returns true on success. False otherwise.
+ bool openForRead(const String& path, long long offset, long long length);
// Opens a file for writing.
- // Returns 0 on success. Exception code otherwise.
- ExceptionCode openForWrite(const String& path);
+ // Returns true on success. False otherwise.
+ bool openForWrite(const String& path);
// Closes the file.
void close();
@@ -80,11 +79,11 @@ public:
// Writes a blob to the file.
// Returns number of bytes being written on success. -1 otherwise.
- int write(Blob*, long long position, int length);
+ int write(const KURL& blobURL, long long position, int length);
// Truncates the file to the specified position.
- // Returns 0 on success. Exception code otherwise.
- ExceptionCode truncate(long long position);
+ // Returns true on success. False otherwise.
+ bool truncate(long long position);
private:
FileStream();
diff --git a/WebCore/html/FileStreamClient.h b/WebCore/platform/FileStreamClient.h
index 440d2fb..b3d1fff 100644
--- a/WebCore/html/FileStreamClient.h
+++ b/WebCore/platform/FileStreamClient.h
@@ -33,8 +33,6 @@
#if ENABLE(BLOB) || ENABLE(FILE_WRITER)
-#include "ExceptionCode.h"
-
namespace WebCore {
class FileStreamClient {
@@ -44,13 +42,13 @@ public:
// For writing.
virtual void didWrite(int) { }
- virtual void didTruncate(ExceptionCode) { }
+ virtual void didTruncate(bool) { }
// FIXME: To be removed when we switch to using BlobData.
virtual void didStart() { }
// For both reading and writing.
- virtual void didOpen(ExceptionCode) { }
+ virtual void didOpen(bool) { }
virtual void didStop() { }
virtual void didGetSize(long long) { }
diff --git a/WebCore/platform/PlatformTouchPoint.h b/WebCore/platform/PlatformTouchPoint.h
index 4a667a0..3a25736 100644
--- a/WebCore/platform/PlatformTouchPoint.h
+++ b/WebCore/platform/PlatformTouchPoint.h
@@ -45,6 +45,7 @@ public:
#if PLATFORM(QT)
PlatformTouchPoint(const QTouchEvent::TouchPoint&);
+ PlatformTouchPoint() {};
#elif PLATFORM(ANDROID)
PlatformTouchPoint(const IntPoint& windowPos, State);
#endif
diff --git a/WebCore/platform/chromium/ChromiumBridge.h b/WebCore/platform/chromium/ChromiumBridge.h
index fc1345e..35ace89 100644
--- a/WebCore/platform/chromium/ChromiumBridge.h
+++ b/WebCore/platform/chromium/ChromiumBridge.h
@@ -72,8 +72,10 @@ namespace WebCore {
class GraphicsContext;
class Image;
class IDBFactoryBackendInterface;
+ class IDBKey;
class IntRect;
class KURL;
+ class SerializedScriptValue;
class Widget;
struct Cookie;
@@ -167,6 +169,8 @@ namespace WebCore {
// IndexedDB ----------------------------------------------------------
static PassRefPtr<IDBFactoryBackendInterface> idbFactory();
+ // Extracts keyPath from values and returns the corresponding keys.
+ static void createIDBKeysFromSerializedValuesAndKeyPath(const Vector<RefPtr<SerializedScriptValue> >& values, const String& keyPath, Vector<RefPtr<IDBKey> >& keys);
// JavaScript ---------------------------------------------------------
static void notifyJSOutOfMemory(Frame*);
diff --git a/WebCore/platform/chromium/ClipboardChromium.cpp b/WebCore/platform/chromium/ClipboardChromium.cpp
index 06244a2..23508a6 100644
--- a/WebCore/platform/chromium/ClipboardChromium.cpp
+++ b/WebCore/platform/chromium/ClipboardChromium.cpp
@@ -400,7 +400,12 @@ void ClipboardChromium::setDragImageElement(Node* node, const IntPoint& loc)
DragImageRef ClipboardChromium::createDragImage(IntPoint& loc) const
{
DragImageRef result = 0;
- if (m_dragImage) {
+ if (m_dragImageElement) {
+ if (m_frame) {
+ result = m_frame->nodeImage(m_dragImageElement.get());
+ loc = m_dragLoc;
+ }
+ } else if (m_dragImage) {
result = createDragImageFromImage(m_dragImage->image());
loc = m_dragLoc;
}
diff --git a/WebCore/platform/efl/PopupMenuEfl.cpp b/WebCore/platform/efl/PopupMenuEfl.cpp
index 401f24f..a6f7a53 100644
--- a/WebCore/platform/efl/PopupMenuEfl.cpp
+++ b/WebCore/platform/efl/PopupMenuEfl.cpp
@@ -43,7 +43,8 @@ PopupMenuEfl::~PopupMenuEfl()
{
// Tell client to destroy data related to this popup since this object is
// going away.
- hide();
+ if (m_view)
+ hide();
}
void PopupMenuEfl::show(const IntRect& rect, FrameView* view, int index)
diff --git a/WebCore/platform/efl/RenderThemeEfl.cpp b/WebCore/platform/efl/RenderThemeEfl.cpp
index 36600a9..102f754 100644
--- a/WebCore/platform/efl/RenderThemeEfl.cpp
+++ b/WebCore/platform/efl/RenderThemeEfl.cpp
@@ -26,6 +26,7 @@
#include "config.h"
#include "RenderThemeEfl.h"
+#include "CSSValueKeywords.h"
#include "FileSystem.h"
#include "Frame.h"
#include "FrameView.h"
@@ -631,6 +632,8 @@ void RenderThemeEfl::themeChanged()
applyPartDescriptions();
}
+float RenderThemeEfl::defaultFontSize = 16.0f;
+
RenderThemeEfl::RenderThemeEfl(Page* page)
: RenderTheme()
, m_page(page)
@@ -985,10 +988,24 @@ bool RenderThemeEfl::paintSearchField(RenderObject* o, const PaintInfo& i, const
return paintThemePart(o, SearchField, i, rect);
}
-void RenderThemeEfl::systemFont(int, FontDescription&) const
+void RenderThemeEfl::setDefaultFontSize(int size)
{
- // If you remove this notImplemented(), replace it with an comment that explains why.
- notImplemented();
+ defaultFontSize = size;
+}
+
+void RenderThemeEfl::systemFont(int propId, FontDescription& fontDescription) const
+{
+ // It was called by RenderEmbeddedObject::paintReplaced to render alternative string.
+ // To avoid cairo_error while rendering, fontDescription should be passed.
+ DEFINE_STATIC_LOCAL(String, fontFace, ("Sans"));
+ float fontSize = defaultFontSize;
+
+ fontDescription.firstFamily().setFamily(fontFace);
+ fontDescription.setSpecifiedSize(fontSize);
+ fontDescription.setIsAbsoluteSize(true);
+ fontDescription.setGenericFamily(FontDescription::NoFamily);
+ fontDescription.setWeight(FontWeightNormal);
+ fontDescription.setItalic(false);
}
}
diff --git a/WebCore/platform/efl/RenderThemeEfl.h b/WebCore/platform/efl/RenderThemeEfl.h
index 8e5650d..478dfc5 100644
--- a/WebCore/platform/efl/RenderThemeEfl.h
+++ b/WebCore/platform/efl/RenderThemeEfl.h
@@ -142,6 +142,12 @@ public:
virtual void adjustSliderThumbStyle(CSSStyleSelector*, RenderStyle*, Element*) const;
virtual bool paintSliderThumb(RenderObject*, const PaintInfo&, const IntRect&);
+
+ static void setDefaultFontSize(int size);
+
+protected:
+ static float defaultFontSize;
+
private:
void createCanvas();
void createEdje();
diff --git a/WebCore/platform/graphics/GraphicsContext.h b/WebCore/platform/graphics/GraphicsContext.h
index c48f91a..1056d81 100644
--- a/WebCore/platform/graphics/GraphicsContext.h
+++ b/WebCore/platform/graphics/GraphicsContext.h
@@ -48,6 +48,9 @@ class SurfaceOpenVG;
typedef class WebCore::SurfaceOpenVG PlatformGraphicsContext;
#elif PLATFORM(QT)
#include <QPainter>
+namespace WebCore {
+class ContextShadow;
+}
typedef QPainter PlatformGraphicsContext;
#elif PLATFORM(WX)
class wxGCDC;
@@ -329,8 +332,8 @@ namespace WebCore {
void setAlpha(float);
#if PLATFORM(CAIRO)
float getAlpha();
- void createPlatformShadow(PassOwnPtr<ImageBuffer> buffer, const Color& shadowColor, const FloatRect& shadowRect, float kernelSize);
- static void calculateShadowBufferDimensions(IntSize& shadowBufferSize, FloatRect& shadowRect, float& kernelSize, const FloatRect& sourceRect, const FloatSize& shadowSize, float shadowBlur);
+ void createPlatformShadow(PassOwnPtr<ImageBuffer> buffer, const Color& shadowColor, const FloatRect& shadowRect, float radius);
+ static void calculateShadowBufferDimensions(IntSize& shadowBufferSize, FloatRect& shadowRect, float& radius, const FloatRect& sourceRect, const FloatSize& shadowSize, float shadowBlur);
#endif
void setCompositeOperation(CompositeOperator);
@@ -431,6 +434,7 @@ namespace WebCore {
void pushTransparencyLayerInternal(const QRect &rect, qreal opacity, QPixmap& alphaMask);
QPen pen();
static QPainter::CompositionMode toQtCompositionMode(CompositeOperator op);
+ ContextShadow* contextShadow();
#endif
#if PLATFORM(GTK)
diff --git a/WebCore/platform/graphics/GraphicsContext3D.cpp b/WebCore/platform/graphics/GraphicsContext3D.cpp
index 51c4cd5..170bb84 100644
--- a/WebCore/platform/graphics/GraphicsContext3D.cpp
+++ b/WebCore/platform/graphics/GraphicsContext3D.cpp
@@ -144,7 +144,7 @@ bool GraphicsContext3D::extractTextureData(unsigned int width, unsigned int heig
unsigned int format, unsigned int type,
unsigned int unpackAlignment,
bool flipY, bool premultiplyAlpha,
- ArrayBufferView* pixels,
+ const void* pixels,
Vector<uint8_t>& data)
{
// Assumes format, type, etc. have already been validated.
@@ -193,7 +193,7 @@ bool GraphicsContext3D::extractTextureData(unsigned int width, unsigned int heig
unsigned long bytesPerPixel = componentsPerPixel * bytesPerComponent;
data.resize(width * height * bytesPerPixel);
- if (!packPixels(static_cast<uint8_t*>(pixels->baseAddress()),
+ if (!packPixels(static_cast<const uint8_t*>(pixels),
sourceDataFormat,
width, height, unpackAlignment,
format, type,
@@ -424,6 +424,7 @@ void packRGBA8ToRGBA8Premultiply(const uint8_t* source, uint8_t* destination)
destination[0] = sourceR;
destination[1] = sourceG;
destination[2] = sourceB;
+ destination[3] = source[3];
}
// FIXME: this routine is lossy and must be removed.
diff --git a/WebCore/platform/graphics/GraphicsContext3D.h b/WebCore/platform/graphics/GraphicsContext3D.h
index 25d1d06..b583813 100644
--- a/WebCore/platform/graphics/GraphicsContext3D.h
+++ b/WebCore/platform/graphics/GraphicsContext3D.h
@@ -77,15 +77,10 @@ const Platform3DObject NullPlatform3DObject = 0;
#endif
namespace WebCore {
-class ArrayBuffer;
-class ArrayBufferView;
class CanvasRenderingContext;
-class Float32Array;
class HostWindow;
class Image;
class ImageData;
-class Int32Array;
-class Uint8Array;
class WebGLActiveInfo;
struct ActiveInfo {
@@ -468,6 +463,8 @@ public:
int sizeInBytes(int type);
bool isGLES2Compliant() const;
+ bool isGLES2NPOTStrict() const;
+ bool isErrorGeneratedOnOutOfBoundsAccesses() const;
//----------------------------------------------------------------------
// Helpers for texture uploading and pixel readback.
@@ -512,7 +509,7 @@ public:
unsigned int format, unsigned int type,
unsigned int unpackAlignment,
bool flipY, bool premultiplyAlpha,
- ArrayBufferView* pixels,
+ const void* pixels,
Vector<uint8_t>& data);
// Flips the given image data vertically, in-place.
@@ -556,10 +553,8 @@ public:
void blendFuncSeparate(unsigned long srcRGB, unsigned long dstRGB, unsigned long srcAlpha, unsigned long dstAlpha);
void bufferData(unsigned long target, int size, unsigned long usage);
- void bufferData(unsigned long target, ArrayBuffer* data, unsigned long usage);
- void bufferData(unsigned long target, ArrayBufferView* data, unsigned long usage);
- void bufferSubData(unsigned long target, long offset, ArrayBuffer* data);
- void bufferSubData(unsigned long target, long offset, ArrayBufferView* data);
+ void bufferData(unsigned long target, int size, const void* data, unsigned long usage);
+ void bufferSubData(unsigned long target, long offset, int size, const void* data);
unsigned long checkFramebufferStatus(unsigned long target);
void clear(unsigned long mask);
diff --git a/WebCore/platform/graphics/ImageSource.cpp b/WebCore/platform/graphics/ImageSource.cpp
index 7f6d323..c6d97fe 100644
--- a/WebCore/platform/graphics/ImageSource.cpp
+++ b/WebCore/platform/graphics/ImageSource.cpp
@@ -41,8 +41,9 @@ namespace WebCore {
unsigned ImageSource::s_maxPixelsPerDecodedImage = 1024 * 1024;
#endif
-ImageSource::ImageSource()
+ImageSource::ImageSource(bool premultiplyAlpha)
: m_decoder(0)
+ , m_premultiplyAlpha(premultiplyAlpha)
{
}
@@ -77,7 +78,7 @@ void ImageSource::setData(SharedBuffer* data, bool allDataReceived)
// If insufficient bytes are available to determine the image type, no decoder plugin will be
// made.
if (!m_decoder) {
- m_decoder = static_cast<NativeImageSourcePtr>(ImageDecoder::create(*data));
+ m_decoder = static_cast<NativeImageSourcePtr>(ImageDecoder::create(*data, m_premultiplyAlpha));
#if ENABLE(IMAGE_DECODER_DOWN_SAMPLING)
if (m_decoder && s_maxPixelsPerDecodedImage)
m_decoder->setMaxNumPixels(s_maxPixelsPerDecodedImage);
diff --git a/WebCore/platform/graphics/ImageSource.h b/WebCore/platform/graphics/ImageSource.h
index 014c136..189f0f5 100644
--- a/WebCore/platform/graphics/ImageSource.h
+++ b/WebCore/platform/graphics/ImageSource.h
@@ -133,7 +133,7 @@ const int cAnimationNone = -2;
class ImageSource : public Noncopyable {
public:
- ImageSource();
+ ImageSource(bool premultiplyAlpha = true);
~ImageSource();
// Tells the ImageSource that the Image no longer cares about decoded frame
@@ -201,6 +201,7 @@ private:
protected:
#endif
NativeImageSourcePtr m_decoder;
+ bool m_premultiplyAlpha;
#if ENABLE(IMAGE_DECODER_DOWN_SAMPLING)
static unsigned s_maxPixelsPerDecodedImage;
#endif
diff --git a/WebCore/platform/graphics/MediaPlayer.cpp b/WebCore/platform/graphics/MediaPlayer.cpp
index e72987a..87060a4 100644
--- a/WebCore/platform/graphics/MediaPlayer.cpp
+++ b/WebCore/platform/graphics/MediaPlayer.cpp
@@ -194,6 +194,24 @@ static void addMediaEngine(CreateMediaEnginePlayer constructor, MediaEngineSuppo
installedMediaEngines().append(new MediaPlayerFactory(constructor, getSupportedTypes, supportsType));
}
+static const AtomicString& applicationOctetStream()
+{
+ DEFINE_STATIC_LOCAL(const AtomicString, applicationOctetStream, ("application/octet-stream"));
+ return applicationOctetStream;
+}
+
+static const AtomicString& textPlain()
+{
+ DEFINE_STATIC_LOCAL(const AtomicString, textPlain, ("text/plain"));
+ return textPlain;
+}
+
+static const AtomicString& codecs()
+{
+ DEFINE_STATIC_LOCAL(const AtomicString, codecs, ("codecs"));
+ return codecs;
+}
+
static MediaPlayerFactory* chooseBestEngineForTypeAndCodecs(const String& type, const String& codecs)
{
Vector<MediaPlayerFactory*>& engines = installedMediaEngines();
@@ -201,6 +219,14 @@ static MediaPlayerFactory* chooseBestEngineForTypeAndCodecs(const String& type,
if (engines.isEmpty())
return 0;
+ // 4.8.10.3 MIME types - In the absence of a specification to the contrary, the MIME type "application/octet-stream"
+ // when used with parameters, e.g. "application/octet-stream;codecs=theora", is a type that the user agent knows
+ // it cannot render.
+ if (type == applicationOctetStream()) {
+ if (!codecs.isEmpty())
+ return 0;
+ }
+
MediaPlayerFactory* engine = 0;
MediaPlayer::SupportsType supported = MediaPlayer::IsNotSupported;
@@ -252,11 +278,11 @@ MediaPlayer::~MediaPlayer()
void MediaPlayer::load(const String& url, const ContentType& contentType)
{
- String type = contentType.type();
- String codecs = contentType.parameter("codecs");
+ String type = contentType.type().lower();
+ String typeCodecs = contentType.parameter(codecs());
- // if we don't know the MIME type, see if the extension can help
- if (type.isEmpty() || type == "application/octet-stream" || type == "text/plain") {
+ // If the MIME type is unhelpful, see if the type registry has a match for the file extension.
+ if (type.isEmpty() || type == applicationOctetStream() || type == textPlain()) {
size_t pos = url.reverseFind('.');
if (pos != notFound) {
String extension = url.substring(pos + 1);
@@ -268,14 +294,17 @@ void MediaPlayer::load(const String& url, const ContentType& contentType)
MediaPlayerFactory* engine = 0;
if (!type.isEmpty())
- engine = chooseBestEngineForTypeAndCodecs(type, codecs);
+ engine = chooseBestEngineForTypeAndCodecs(type, typeCodecs);
- // if we didn't find an engine that claims the MIME type, just use the first engine
- if (!engine && !installedMediaEngines().isEmpty())
+ // If we didn't find an engine and no MIME type is specified, just use the first engine.
+ if (!engine && type.isEmpty() && !installedMediaEngines().isEmpty())
engine = installedMediaEngines()[0];
- // don't delete and recreate the player unless it comes from a different engine
- if (engine && m_currentMediaEngine != engine) {
+ // Don't delete and recreate the player unless it comes from a different engine
+ if (!engine) {
+ m_currentMediaEngine = engine;
+ m_private.clear();
+ } else if (m_currentMediaEngine != engine) {
m_currentMediaEngine = engine;
m_private.clear();
m_private.set(engine->constructor(this));
@@ -532,14 +561,26 @@ void MediaPlayer::paintCurrentFrameInContext(GraphicsContext* p, const IntRect&
MediaPlayer::SupportsType MediaPlayer::supportsType(ContentType contentType)
{
- String type = contentType.type();
- String codecs = contentType.parameter("codecs");
- MediaPlayerFactory* engine = chooseBestEngineForTypeAndCodecs(type, codecs);
+ String type = contentType.type().lower();
+ String typeCodecs = contentType.parameter(codecs());
+
+ // 4.8.10.3 MIME types - In the absence of a specification to the contrary, the MIME type "application/octet-stream"
+ // when used with parameters, e.g. "application/octet-stream;codecs=theora", is a type that the user agent knows
+ // it cannot render.
+ if (type == applicationOctetStream()) {
+ if (!typeCodecs.isEmpty())
+ return IsNotSupported;
+
+ // The MIME type "application/octet-stream" with no parameters is never a type that the user agent knows it
+ // cannot render.
+ return MayBeSupported;
+ }
+ MediaPlayerFactory* engine = chooseBestEngineForTypeAndCodecs(type, typeCodecs);
if (!engine)
return IsNotSupported;
- return engine->supportsTypeAndCodecs(type, codecs);
+ return engine->supportsTypeAndCodecs(type, typeCodecs);
}
void MediaPlayer::getSupportedTypes(HashSet<String>& types)
diff --git a/WebCore/platform/graphics/cairo/FontCairo.cpp b/WebCore/platform/graphics/cairo/FontCairo.cpp
index 9217a81..f6d8f3d 100644
--- a/WebCore/platform/graphics/cairo/FontCairo.cpp
+++ b/WebCore/platform/graphics/cairo/FontCairo.cpp
@@ -94,15 +94,15 @@ void Font::drawGlyphs(GraphicsContext* context, const SimpleFontData* font, cons
FloatRect rect(FloatPoint(), FloatSize(extents.width, extents.height));
IntSize shadowBufferSize;
FloatRect shadowRect;
- float kernelSize = 0.f;
- GraphicsContext::calculateShadowBufferDimensions(shadowBufferSize, shadowRect, kernelSize, rect, shadowSize, shadowBlur);
+ float radius = 0;
+ context->calculateShadowBufferDimensions(shadowBufferSize, shadowRect, radius, rect, shadowSize, shadowBlur);
// Draw shadow into a new ImageBuffer
OwnPtr<ImageBuffer> shadowBuffer = ImageBuffer::create(shadowBufferSize);
GraphicsContext* shadowContext = shadowBuffer->context();
cairo_t* shadowCr = shadowContext->platformContext();
- cairo_translate(shadowCr, kernelSize, extents.height + kernelSize);
+ cairo_translate(shadowCr, radius, extents.height + radius);
cairo_set_scaled_font(shadowCr, font->platformData().scaledFont());
cairo_show_glyphs(shadowCr, glyphs, numGlyphs);
@@ -113,7 +113,7 @@ void Font::drawGlyphs(GraphicsContext* context, const SimpleFontData* font, cons
cairo_restore(shadowCr);
}
cairo_translate(cr, 0.0, -extents.height);
- context->createPlatformShadow(shadowBuffer.release(), shadowColor, shadowRect, kernelSize);
+ context->createPlatformShadow(shadowBuffer.release(), shadowColor, shadowRect, radius);
#else
cairo_translate(cr, shadowSize.width(), shadowSize.height());
cairo_show_glyphs(cr, glyphs, numGlyphs);
diff --git a/WebCore/platform/graphics/cairo/GraphicsContextCairo.cpp b/WebCore/platform/graphics/cairo/GraphicsContextCairo.cpp
index 9b3096e..3a667ac 100644
--- a/WebCore/platform/graphics/cairo/GraphicsContextCairo.cpp
+++ b/WebCore/platform/graphics/cairo/GraphicsContextCairo.cpp
@@ -61,6 +61,8 @@
#include "GraphicsContextPlatformPrivateCairo.h"
#include "GraphicsContextPrivate.h"
+using namespace std;
+
#ifndef M_PI
#define M_PI 3.14159265358979323846
#endif
@@ -173,18 +175,17 @@ static void addConvexPolygonToContext(cairo_t* context, size_t numPoints, const
cairo_close_path(context);
}
-void GraphicsContext::calculateShadowBufferDimensions(IntSize& shadowBufferSize, FloatRect& shadowRect, float& kernelSize, const FloatRect& sourceRect, const FloatSize& shadowSize, float shadowBlur)
+void GraphicsContext::calculateShadowBufferDimensions(IntSize& shadowBufferSize, FloatRect& shadowRect, float& radius, const FloatRect& sourceRect, const FloatSize& shadowSize, float shadowBlur)
{
#if ENABLE(FILTERS)
- // calculate the kernel size according to the HTML5 canvas shadow specification
- kernelSize = (shadowBlur < 8 ? shadowBlur / 2.f : sqrt(shadowBlur * 2.f));
- int blurRadius = ceil(kernelSize);
+ // limit radius to 128
+ radius = min(128.f, max(shadowBlur, 0.f));
- shadowBufferSize = IntSize(sourceRect.width() + blurRadius * 2, sourceRect.height() + blurRadius * 2);
+ shadowBufferSize = IntSize(sourceRect.width() + radius * 2, sourceRect.height() + radius * 2);
// determine dimensions of shadow rect
shadowRect = FloatRect(sourceRect.location(), shadowBufferSize);
- shadowRect.move(shadowSize.width() - kernelSize, shadowSize.height() - kernelSize);
+ shadowRect.move(shadowSize.width() - radius, shadowSize.height() - radius);
#endif
}
@@ -209,8 +210,8 @@ static inline void drawPathShadow(GraphicsContext* context, GraphicsContextPriva
IntSize shadowBufferSize;
FloatRect shadowRect;
- float kernelSize = 0;
- GraphicsContext::calculateShadowBufferDimensions(shadowBufferSize, shadowRect, kernelSize, rect, shadowSize, shadowBlur);
+ float radius = 0;
+ GraphicsContext::calculateShadowBufferDimensions(shadowBufferSize, shadowRect, radius, rect, shadowSize, shadowBlur);
// Create suitably-sized ImageBuffer to hold the shadow.
OwnPtr<ImageBuffer> shadowBuffer = ImageBuffer::create(shadowBufferSize);
@@ -218,7 +219,7 @@ static inline void drawPathShadow(GraphicsContext* context, GraphicsContextPriva
// Draw shadow into a new ImageBuffer.
cairo_t* shadowContext = shadowBuffer->context()->platformContext();
copyContextProperties(cr, shadowContext);
- cairo_translate(shadowContext, -rect.x() + kernelSize, -rect.y() + kernelSize);
+ cairo_translate(shadowContext, -rect.x() + radius, -rect.y() + radius);
cairo_new_path(shadowContext);
cairo_append_path(shadowContext, path);
@@ -227,7 +228,7 @@ static inline void drawPathShadow(GraphicsContext* context, GraphicsContextPriva
if (strokeShadow)
setPlatformStroke(context, shadowContext, gcp);
- context->createPlatformShadow(shadowBuffer.release(), shadowColor, shadowRect, kernelSize);
+ context->createPlatformShadow(shadowBuffer.release(), shadowColor, shadowRect, radius);
#endif
}
@@ -631,15 +632,15 @@ static void drawBorderlessRectShadow(GraphicsContext* context, const FloatRect&
IntSize shadowBufferSize;
FloatRect shadowRect;
- float kernelSize = 0;
- GraphicsContext::calculateShadowBufferDimensions(shadowBufferSize, shadowRect, kernelSize, rect, shadowSize, shadowBlur);
+ float radius = 0;
+ GraphicsContext::calculateShadowBufferDimensions(shadowBufferSize, shadowRect, radius, rect, shadowSize, shadowBlur);
// Draw shadow into a new ImageBuffer
OwnPtr<ImageBuffer> shadowBuffer = ImageBuffer::create(shadowBufferSize);
GraphicsContext* shadowContext = shadowBuffer->context();
- shadowContext->fillRect(FloatRect(FloatPoint(kernelSize, kernelSize), rect.size()), rectColor, DeviceColorSpace);
+ shadowContext->fillRect(FloatRect(FloatPoint(radius, radius), rect.size()), rectColor, DeviceColorSpace);
- context->createPlatformShadow(shadowBuffer.release(), shadowColor, shadowRect, kernelSize);
+ context->createPlatformShadow(shadowBuffer.release(), shadowColor, shadowRect, radius);
#endif
}
@@ -920,28 +921,28 @@ void GraphicsContext::setPlatformShadow(FloatSize const& size, float, Color cons
}
}
-void GraphicsContext::createPlatformShadow(PassOwnPtr<ImageBuffer> buffer, const Color& shadowColor, const FloatRect& shadowRect, float kernelSize)
+void GraphicsContext::createPlatformShadow(PassOwnPtr<ImageBuffer> buffer, const Color& shadowColor, const FloatRect& shadowRect, float radius)
{
#if ENABLE(FILTERS)
cairo_t* cr = m_data->cr;
- // draw the shadow without blurring, if kernelSize is zero
- if (!kernelSize) {
+ // calculate the standard deviation
+ float sd = FEGaussianBlur::calculateStdDeviation(radius);
+
+ // draw the shadow without blurring, if radius is zero
+ if (!radius || !sd) {
setColor(cr, shadowColor);
cairo_mask_surface(cr, buffer->m_data.m_surface, shadowRect.x(), shadowRect.y());
return;
}
- // limit kernel size to 1000, this is what CG is doing.
- kernelSize = std::min(1000.f, kernelSize);
-
// create filter
RefPtr<Filter> filter = ImageBufferFilter::create();
filter->setSourceImage(buffer);
RefPtr<FilterEffect> source = SourceGraphic::create();
source->setScaledSubRegion(FloatRect(FloatPoint(), shadowRect.size()));
source->setIsAlphaImage(true);
- RefPtr<FilterEffect> blur = FEGaussianBlur::create(source.get(), kernelSize, kernelSize);
+ RefPtr<FilterEffect> blur = FEGaussianBlur::create(source.get(), sd, sd);
blur->setScaledSubRegion(FloatRect(FloatPoint(), shadowRect.size()));
blur->apply(filter.get());
diff --git a/WebCore/platform/graphics/cairo/GraphicsContextPlatformPrivateCairo.h b/WebCore/platform/graphics/cairo/GraphicsContextPlatformPrivateCairo.h
index 97e7e07..81987ef 100644
--- a/WebCore/platform/graphics/cairo/GraphicsContextPlatformPrivateCairo.h
+++ b/WebCore/platform/graphics/cairo/GraphicsContextPlatformPrivateCairo.h
@@ -27,6 +27,7 @@
#include "GraphicsContext.h"
+#include "CairoPath.h"
#include <cairo.h>
#include <math.h>
#include <stdio.h>
diff --git a/WebCore/platform/graphics/cairo/ImageBufferCairo.cpp b/WebCore/platform/graphics/cairo/ImageBufferCairo.cpp
index db66276..976dcb4 100644
--- a/WebCore/platform/graphics/cairo/ImageBufferCairo.cpp
+++ b/WebCore/platform/graphics/cairo/ImageBufferCairo.cpp
@@ -38,10 +38,8 @@
#include "NotImplemented.h"
#include "Pattern.h"
#include "PlatformString.h"
-
#include <cairo.h>
#include <wtf/Vector.h>
-#include <math.h>
using namespace std;
@@ -100,7 +98,7 @@ GraphicsContext* ImageBuffer::context() const
bool ImageBuffer::drawsUsingCopy() const
{
- return true;
+ return false;
}
PassRefPtr<Image> ImageBuffer::copyImage() const
@@ -112,20 +110,23 @@ PassRefPtr<Image> ImageBuffer::copyImage() const
void ImageBuffer::clip(GraphicsContext*, const FloatRect&) const
{
notImplemented();
+ // See https://bugs.webkit.org/show_bug.cgi?id=23526 for why this is unimplemented.
}
void ImageBuffer::draw(GraphicsContext* context, ColorSpace styleColorSpace, const FloatRect& destRect, const FloatRect& srcRect,
CompositeOperator op , bool useLowQualityScale)
{
- RefPtr<Image> imageCopy = copyImage();
- context->drawImage(imageCopy.get(), styleColorSpace, destRect, srcRect, op, useLowQualityScale);
+ // BitmapImage will release the passed in surface on destruction
+ RefPtr<Image> image = BitmapImage::create(cairo_surface_reference(m_data.m_surface));
+ context->drawImage(image.get(), styleColorSpace, destRect, srcRect, op, useLowQualityScale);
}
void ImageBuffer::drawPattern(GraphicsContext* context, const FloatRect& srcRect, const AffineTransform& patternTransform,
const FloatPoint& phase, ColorSpace styleColorSpace, CompositeOperator op, const FloatRect& destRect)
{
- RefPtr<Image> imageCopy = copyImage();
- imageCopy->drawPattern(context, srcRect, patternTransform, phase, styleColorSpace, op, destRect);
+ // BitmapImage will release the passed in surface on destruction
+ RefPtr<Image> image = BitmapImage::create(cairo_surface_reference(m_data.m_surface));
+ image->drawPattern(context, srcRect, patternTransform, phase, styleColorSpace, op, destRect);
}
void ImageBuffer::platformTransformColorSpace(const Vector<int>& lookUpTable)
diff --git a/WebCore/platform/graphics/cairo/ImageCairo.cpp b/WebCore/platform/graphics/cairo/ImageCairo.cpp
index 1582671..d9eb5e6 100644
--- a/WebCore/platform/graphics/cairo/ImageCairo.cpp
+++ b/WebCore/platform/graphics/cairo/ImageCairo.cpp
@@ -33,7 +33,7 @@
#include "AffineTransform.h"
#include "Color.h"
#include "FloatRect.h"
-#include "GRefPtrCairo.h"
+#include "PlatformRefPtrCairo.h"
#include "GraphicsContext.h"
#include "ImageBuffer.h"
#include "ImageObserver.h"
@@ -141,8 +141,8 @@ void BitmapImage::draw(GraphicsContext* context, const FloatRect& dst, const Flo
if (context->getShadow(shadowSize, shadowBlur, shadowColor)) {
IntSize shadowBufferSize;
FloatRect shadowRect;
- float kernelSize (0.0);
- GraphicsContext::calculateShadowBufferDimensions(shadowBufferSize, shadowRect, kernelSize, dstRect, shadowSize, shadowBlur);
+ float radius = 0;
+ context->calculateShadowBufferDimensions(shadowBufferSize, shadowRect, radius, dstRect, shadowSize, shadowBlur);
shadowColor = colorWithOverrideAlpha(shadowColor.rgb(), (shadowColor.alpha() * context->getAlpha()) / 255.f);
//draw shadow into a new ImageBuffer
@@ -153,7 +153,7 @@ void BitmapImage::draw(GraphicsContext* context, const FloatRect& dst, const Flo
cairo_rectangle(shadowContext, 0, 0, dstRect.width(), dstRect.height());
cairo_fill(shadowContext);
- context->createPlatformShadow(shadowBuffer.release(), shadowColor, shadowRect, kernelSize);
+ context->createPlatformShadow(shadowBuffer.release(), shadowColor, shadowRect, radius);
}
#endif
@@ -185,11 +185,11 @@ void Image::drawPattern(GraphicsContext* context, const FloatRect& tileRect, con
cairo_t* cr = context->platformContext();
context->save();
- GRefPtr<cairo_surface_t> clippedImageSurface = 0;
+ PlatformRefPtr<cairo_surface_t> clippedImageSurface = 0;
if (tileRect.size() != size()) {
IntRect imageSize = enclosingIntRect(tileRect);
- clippedImageSurface = adoptGRef(cairo_image_surface_create(CAIRO_FORMAT_ARGB32, imageSize.width(), imageSize.height()));
- GRefPtr<cairo_t> clippedImageContext(cairo_create(clippedImageSurface.get()));
+ clippedImageSurface = adoptPlatformRef(cairo_image_surface_create(CAIRO_FORMAT_ARGB32, imageSize.width(), imageSize.height()));
+ PlatformRefPtr<cairo_t> clippedImageContext(cairo_create(clippedImageSurface.get()));
cairo_set_source_surface(clippedImageContext.get(), image, -tileRect.x(), -tileRect.y());
cairo_paint(clippedImageContext.get());
image = clippedImageSurface.get();
diff --git a/WebCore/platform/graphics/cairo/GRefPtrCairo.cpp b/WebCore/platform/graphics/cairo/PlatformRefPtrCairo.cpp
index d244954..6870560 100644
--- a/WebCore/platform/graphics/cairo/GRefPtrCairo.cpp
+++ b/WebCore/platform/graphics/cairo/PlatformRefPtrCairo.cpp
@@ -17,33 +17,33 @@
*/
#include "config.h"
-#include "GRefPtrCairo.h"
+#include "PlatformRefPtrCairo.h"
#include <cairo.h>
namespace WTF {
-template <> cairo_t* refGPtr(cairo_t* ptr)
+template <> cairo_t* refPlatformPtr(cairo_t* ptr)
{
if (ptr)
cairo_reference(ptr);
return ptr;
}
-template <> void derefGPtr(cairo_t* ptr)
+template <> void derefPlatformPtr(cairo_t* ptr)
{
if (ptr)
cairo_destroy(ptr);
}
-template <> cairo_surface_t* refGPtr(cairo_surface_t* ptr)
+template <> cairo_surface_t* refPlatformPtr(cairo_surface_t* ptr)
{
if (ptr)
cairo_surface_reference(ptr);
return ptr;
}
-template <> void derefGPtr(cairo_surface_t* ptr)
+template <> void derefPlatformPtr(cairo_surface_t* ptr)
{
if (ptr)
cairo_surface_destroy(ptr);
diff --git a/WebCore/platform/graphics/cairo/GRefPtrCairo.h b/WebCore/platform/graphics/cairo/PlatformRefPtrCairo.h
index aef51fe..51d8fa9 100644
--- a/WebCore/platform/graphics/cairo/GRefPtrCairo.h
+++ b/WebCore/platform/graphics/cairo/PlatformRefPtrCairo.h
@@ -17,21 +17,21 @@
* Boston, MA 02110-1301, USA.
*/
-#ifndef GRefPtrCairo_h
-#define GRefPtrCairo_h
+#ifndef PlatformRefPtrCairo_h
+#define PlatformRefPtrCairo_h
-#include "GRefPtr.h"
+#include "PlatformRefPtr.h"
typedef struct _cairo cairo_t;
typedef struct _cairo_surface cairo_surface_t;
namespace WTF {
-template <> cairo_t* refGPtr(cairo_t* ptr);
-template <> void derefGPtr(cairo_t* ptr);
+template <> cairo_t* refPlatformPtr(cairo_t* ptr);
+template <> void derefPlatformPtr(cairo_t* ptr);
-template <> cairo_surface_t* refGPtr(cairo_surface_t* ptr);
-template <> void derefGPtr(cairo_surface_t* ptr);
+template <> cairo_surface_t* refPlatformPtr(cairo_surface_t* ptr);
+template <> void derefPlatformPtr(cairo_surface_t* ptr);
}
diff --git a/WebCore/platform/graphics/cg/ImageSourceCG.cpp b/WebCore/platform/graphics/cg/ImageSourceCG.cpp
index 4a7aecc..5fa4896 100644
--- a/WebCore/platform/graphics/cg/ImageSourceCG.cpp
+++ b/WebCore/platform/graphics/cg/ImageSourceCG.cpp
@@ -63,8 +63,10 @@ void sharedBufferRelease(void* info)
}
#endif
-ImageSource::ImageSource()
+ImageSource::ImageSource(bool premultiplyAlpha)
: m_decoder(0)
+ // FIXME: m_premultiplyAlpha is ignored in cg at the moment.
+ , m_premultiplyAlpha(premultiplyAlpha)
{
}
diff --git a/WebCore/platform/graphics/chromium/CanvasLayerChromium.cpp b/WebCore/platform/graphics/chromium/CanvasLayerChromium.cpp
index 7e732d1..bbf091c 100644
--- a/WebCore/platform/graphics/chromium/CanvasLayerChromium.cpp
+++ b/WebCore/platform/graphics/chromium/CanvasLayerChromium.cpp
@@ -35,11 +35,63 @@
#include "CanvasLayerChromium.h"
#include "GraphicsContext3D.h"
+#include "LayerRendererChromium.h"
#include <GLES2/gl2.h>
namespace WebCore {
-unsigned CanvasLayerChromium::m_shaderProgramId = 0;
+CanvasLayerChromium::SharedValues::SharedValues()
+ : m_canvasShaderProgram(0)
+ , m_shaderSamplerLocation(-1)
+ , m_shaderMatrixLocation(-1)
+ , m_shaderAlphaLocation(-1)
+ , m_initialized(false)
+{
+ char vertexShaderString[] =
+ "attribute vec4 a_position; \n"
+ "attribute vec2 a_texCoord; \n"
+ "uniform mat4 matrix; \n"
+ "varying vec2 v_texCoord; \n"
+ "void main() \n"
+ "{ \n"
+ " gl_Position = matrix * a_position; \n"
+ " v_texCoord = a_texCoord; \n"
+ "} \n";
+
+ // Canvas layers need to be flipped vertically and their colors shouldn't be
+ // swizzled.
+ char fragmentShaderString[] =
+ "precision mediump float; \n"
+ "varying vec2 v_texCoord; \n"
+ "uniform sampler2D s_texture; \n"
+ "uniform float alpha; \n"
+ "void main() \n"
+ "{ \n"
+ " vec4 texColor = texture2D(s_texture, vec2(v_texCoord.x, 1.0 - v_texCoord.y)); \n"
+ " gl_FragColor = vec4(texColor.x, texColor.y, texColor.z, texColor.w) * alpha; \n"
+ "} \n";
+
+ m_canvasShaderProgram = createShaderProgram(vertexShaderString, fragmentShaderString);
+ if (!m_canvasShaderProgram) {
+ LOG_ERROR("CanvasLayerChromium: Failed to create shader program");
+ return;
+ }
+
+ m_shaderSamplerLocation = glGetUniformLocation(m_canvasShaderProgram, "s_texture");
+ m_shaderMatrixLocation = glGetUniformLocation(m_canvasShaderProgram, "matrix");
+ m_shaderAlphaLocation = glGetUniformLocation(m_canvasShaderProgram, "alpha");
+ ASSERT(m_shaderSamplerLocation != -1);
+ ASSERT(m_shaderMatrixLocation != -1);
+ ASSERT(m_shaderAlphaLocation != -1);
+
+ m_initialized = true;
+}
+
+CanvasLayerChromium::SharedValues::~SharedValues()
+{
+ if (m_canvasShaderProgram)
+ GLC(glDeleteProgram(m_canvasShaderProgram));
+}
PassRefPtr<CanvasLayerChromium> CanvasLayerChromium::create(GraphicsLayerChromium* owner)
{
@@ -54,14 +106,8 @@ CanvasLayerChromium::CanvasLayerChromium(GraphicsLayerChromium* owner)
{
}
-unsigned CanvasLayerChromium::textureId()
-{
- return m_textureId;
-}
-
-void CanvasLayerChromium::updateTextureContents(unsigned textureId)
+void CanvasLayerChromium::updateContents()
{
- ASSERT(textureId == m_textureId);
ASSERT(m_context);
if (m_textureChanged) {
glBindTexture(GL_TEXTURE_2D, m_textureId);
@@ -92,5 +138,19 @@ void CanvasLayerChromium::setContext(const GraphicsContext3D* context)
m_textureId = textureId;
}
+void CanvasLayerChromium::draw()
+{
+ ASSERT(layerRenderer());
+ const CanvasLayerChromium::SharedValues* sv = layerRenderer()->canvasLayerSharedValues();
+ ASSERT(sv && sv->initialized());
+ GLC(glActiveTexture(GL_TEXTURE0));
+ GLC(glBindTexture(GL_TEXTURE_2D, m_textureId));
+ layerRenderer()->useShader(sv->canvasShaderProgram());
+ GLC(glUniform1i(sv->shaderSamplerLocation(), 0));
+ drawTexturedQuad(layerRenderer()->projectionMatrix(), drawTransform(),
+ bounds().width(), bounds().height(), drawOpacity(),
+ sv->shaderMatrixLocation(), sv->shaderAlphaLocation());
+}
+
}
#endif // USE(ACCELERATED_COMPOSITING)
diff --git a/WebCore/platform/graphics/chromium/CanvasLayerChromium.h b/WebCore/platform/graphics/chromium/CanvasLayerChromium.h
index 98be270..053efff 100644
--- a/WebCore/platform/graphics/chromium/CanvasLayerChromium.h
+++ b/WebCore/platform/graphics/chromium/CanvasLayerChromium.h
@@ -45,14 +45,29 @@ class CanvasLayerChromium : public LayerChromium {
public:
static PassRefPtr<CanvasLayerChromium> create(GraphicsLayerChromium* owner = 0);
virtual bool drawsContent() { return m_context; }
- virtual bool ownsTexture() { return true; }
- virtual void updateTextureContents(unsigned);
- virtual unsigned textureId();
- virtual unsigned shaderProgramId() { return m_shaderProgramId; }
+ virtual void updateContents();
+ virtual void draw();
void setContext(const GraphicsContext3D* context);
- static void setShaderProgramId(unsigned shaderProgramId) { m_shaderProgramId = shaderProgramId; }
+ class SharedValues {
+ public:
+ SharedValues();
+ ~SharedValues();
+
+ unsigned canvasShaderProgram() const { return m_canvasShaderProgram; }
+ int shaderSamplerLocation() const { return m_shaderSamplerLocation; }
+ int shaderMatrixLocation() const { return m_shaderMatrixLocation; }
+ int shaderAlphaLocation() const { return m_shaderAlphaLocation; }
+ bool initialized() const { return m_initialized; }
+
+ private:
+ unsigned m_canvasShaderProgram;
+ int m_shaderSamplerLocation;
+ int m_shaderMatrixLocation;
+ int m_shaderAlphaLocation;
+ bool m_initialized;
+ };
class PrepareTextureCallback : public Noncopyable {
public:
@@ -66,8 +81,6 @@ private:
unsigned m_textureId;
bool m_textureChanged;
OwnPtr<PrepareTextureCallback> m_prepareTextureCallback;
-
- static unsigned m_shaderProgramId;
};
}
diff --git a/WebCore/platform/graphics/chromium/ContentLayerChromium.cpp b/WebCore/platform/graphics/chromium/ContentLayerChromium.cpp
new file mode 100644
index 0000000..974933d
--- /dev/null
+++ b/WebCore/platform/graphics/chromium/ContentLayerChromium.cpp
@@ -0,0 +1,301 @@
+/*
+ * Copyright (C) 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"
+
+#if USE(ACCELERATED_COMPOSITING)
+
+#include "ContentLayerChromium.h"
+
+#include "LayerRendererChromium.h"
+#include "RenderLayerBacking.h"
+
+#if PLATFORM(SKIA)
+#include "NativeImageSkia.h"
+#include "PlatformContextSkia.h"
+#include "skia/ext/platform_canvas.h"
+#elif PLATFORM(CG)
+#include <CoreGraphics/CGBitmapContext.h>
+#endif
+
+#include <GLES2/gl2.h>
+
+namespace WebCore {
+
+ContentLayerChromium::SharedValues::SharedValues()
+ : m_contentShaderProgram(0)
+ , m_shaderSamplerLocation(-1)
+ , m_shaderMatrixLocation(-1)
+ , m_shaderAlphaLocation(-1)
+ , m_initialized(false)
+{
+ // Shaders for drawing the layer contents.
+ char vertexShaderString[] =
+ "attribute vec4 a_position; \n"
+ "attribute vec2 a_texCoord; \n"
+ "uniform mat4 matrix; \n"
+ "varying vec2 v_texCoord; \n"
+ "void main() \n"
+ "{ \n"
+ " gl_Position = matrix * a_position; \n"
+ " v_texCoord = a_texCoord; \n"
+ "} \n";
+
+ // Note differences between Skia and Core Graphics versions:
+ // - Skia uses BGRA and origin is upper left
+ // - Core Graphics uses RGBA and origin is lower left
+ char fragmentShaderString[] =
+ "precision mediump float; \n"
+ "varying vec2 v_texCoord; \n"
+ "uniform sampler2D s_texture; \n"
+ "uniform float alpha; \n"
+ "void main() \n"
+ "{ \n"
+#if PLATFORM(SKIA)
+ " vec4 texColor = texture2D(s_texture, v_texCoord); \n"
+ " gl_FragColor = vec4(texColor.z, texColor.y, texColor.x, texColor.w) * alpha; \n"
+#elif PLATFORM(CG)
+ " vec4 texColor = texture2D(s_texture, vec2(v_texCoord.x, 1.0 - v_texCoord.y)); \n"
+ " gl_FragColor = vec4(texColor.x, texColor.y, texColor.z, texColor.w) * alpha; \n"
+#else
+#error "Need to implement for your platform."
+#endif
+ "} \n";
+
+ m_contentShaderProgram = createShaderProgram(vertexShaderString, fragmentShaderString);
+ if (!m_contentShaderProgram) {
+ LOG_ERROR("ContentLayerChromium: Failed to create shader program");
+ return;
+ }
+
+ m_shaderSamplerLocation = glGetUniformLocation(m_contentShaderProgram, "s_texture");
+ m_shaderMatrixLocation = glGetUniformLocation(m_contentShaderProgram, "matrix");
+ m_shaderAlphaLocation = glGetUniformLocation(m_contentShaderProgram, "alpha");
+ ASSERT(m_shaderSamplerLocation != -1);
+ ASSERT(m_shaderMatrixLocation != -1);
+ ASSERT(m_shaderAlphaLocation != -1);
+
+ m_initialized = true;
+}
+
+ContentLayerChromium::SharedValues::~SharedValues()
+{
+ if (m_contentShaderProgram)
+ GLC(glDeleteProgram(m_contentShaderProgram));
+}
+
+
+PassRefPtr<ContentLayerChromium> ContentLayerChromium::create(GraphicsLayerChromium* owner)
+{
+ return adoptRef(new ContentLayerChromium(owner));
+}
+
+ContentLayerChromium::ContentLayerChromium(GraphicsLayerChromium* owner)
+ : LayerChromium(owner)
+ , m_contentsTexture(0)
+{
+}
+
+ContentLayerChromium::~ContentLayerChromium()
+{
+ if (m_contentsTexture)
+ GLC(glDeleteTextures(1, &m_contentsTexture));
+}
+
+
+void ContentLayerChromium::updateContents()
+{
+ RenderLayerBacking* backing = static_cast<RenderLayerBacking*>(m_owner->client());
+ if (!backing || backing->paintingGoesToWindow())
+ return;
+
+ ASSERT(drawsContent());
+
+ ASSERT(layerRenderer());
+
+ // FIXME: Remove this test when tiled layers are implemented.
+ m_skipsDraw = false;
+ if (!layerRenderer()->checkTextureSize(m_bounds)) {
+ m_skipsDraw = true;
+ return;
+ }
+
+ void* pixels = 0;
+ IntRect dirtyRect(m_dirtyRect);
+ IntSize requiredTextureSize;
+ IntSize bitmapSize;
+
+#if PLATFORM(SKIA)
+ const SkBitmap* skiaBitmap = 0;
+ OwnPtr<skia::PlatformCanvas> canvas;
+ OwnPtr<PlatformContextSkia> skiaContext;
+ OwnPtr<GraphicsContext> graphicsContext;
+
+ requiredTextureSize = m_bounds;
+ IntRect boundsRect(IntPoint(0, 0), m_bounds);
+
+ // If the texture needs to be reallocated then we must redraw the entire
+ // contents of the layer.
+ if (requiredTextureSize != m_allocatedTextureSize)
+ dirtyRect = boundsRect;
+ else {
+ // Clip the dirtyRect to the size of the layer to avoid drawing outside
+ // the bounds of the backing texture.
+ dirtyRect.intersect(boundsRect);
+ }
+
+ canvas.set(new skia::PlatformCanvas(dirtyRect.width(), dirtyRect.height(), false));
+ skiaContext.set(new PlatformContextSkia(canvas.get()));
+
+#if OS(WINDOWS)
+ // This is needed to get text to show up correctly. Without it,
+ // GDI renders with zero alpha and the text becomes invisible.
+ // Unfortunately, setting this to true disables cleartype.
+ // FIXME: Does this take us down a very slow text rendering path?
+ // FIXME: why is this is a windows-only call ?
+ skiaContext->setDrawingToImageBuffer(true);
+#endif
+
+ graphicsContext.set(new GraphicsContext(reinterpret_cast<PlatformGraphicsContext*>(skiaContext.get())));
+
+ // Bring the canvas into the coordinate system of the paint rect.
+ canvas->translate(static_cast<SkScalar>(-dirtyRect.x()), static_cast<SkScalar>(-dirtyRect.y()));
+
+ m_owner->paintGraphicsLayerContents(*graphicsContext, dirtyRect);
+ const SkBitmap& bitmap = canvas->getDevice()->accessBitmap(false);
+ skiaBitmap = &bitmap;
+ ASSERT(skiaBitmap);
+
+ SkAutoLockPixels lock(*skiaBitmap);
+ SkBitmap::Config skiaConfig = skiaBitmap->config();
+ // FIXME: do we need to support more image configurations?
+ if (skiaConfig == SkBitmap::kARGB_8888_Config) {
+ pixels = skiaBitmap->getPixels();
+ bitmapSize = IntSize(skiaBitmap->width(), skiaBitmap->height());
+ }
+#elif PLATFORM(CG)
+ requiredTextureSize = m_bounds;
+ IntRect boundsRect(IntPoint(0, 0), m_bounds);
+
+ // If the texture needs to be reallocated then we must redraw the entire
+ // contents of the layer.
+ if (requiredTextureSize != m_allocatedTextureSize)
+ dirtyRect = boundsRect;
+ else {
+ // Clip the dirtyRect to the size of the layer to avoid drawing outside
+ // the bounds of the backing texture.
+ dirtyRect.intersect(boundsRect);
+ }
+
+ Vector<uint8_t> tempVector;
+ int rowBytes = 4 * dirtyRect.width();
+ tempVector.resize(rowBytes * dirtyRect.height());
+ memset(tempVector.data(), 0, tempVector.size());
+ RetainPtr<CGColorSpaceRef> colorSpace(AdoptCF, CGColorSpaceCreateDeviceRGB());
+ RetainPtr<CGContextRef> contextCG(AdoptCF, CGBitmapContextCreate(tempVector.data(),
+ dirtyRect.width(), dirtyRect.height(), 8, rowBytes,
+ colorSpace.get(),
+ kCGImageAlphaPremultipliedLast));
+
+ GraphicsContext graphicsContext(contextCG.get());
+
+ // Translate the graphics contxt into the coordinate system of the dirty rect.
+ graphicsContext.translate(-dirtyRect.x(), -dirtyRect.y());
+
+ m_owner->paintGraphicsLayerContents(graphicsContext, dirtyRect);
+
+ pixels = tempVector.data();
+ bitmapSize = dirtyRect.size();
+#else
+#error "Need to implement for your platform."
+#endif
+
+ unsigned textureId = m_contentsTexture;
+ if (!textureId)
+ textureId = layerRenderer()->createLayerTexture();
+
+ if (pixels)
+ updateTextureRect(pixels, bitmapSize, requiredTextureSize, dirtyRect, textureId);
+}
+
+void ContentLayerChromium::updateTextureRect(void* pixels, const IntSize& bitmapSize, const IntSize& requiredTextureSize, const IntRect& updateRect, unsigned textureId)
+{
+ if (!pixels)
+ return;
+
+ glBindTexture(GL_TEXTURE_2D, textureId);
+
+ // If the texture id or size changed since last time then we need to tell GL
+ // to re-allocate a texture.
+ if (m_contentsTexture != textureId || requiredTextureSize != m_allocatedTextureSize) {
+ ASSERT(bitmapSize == requiredTextureSize);
+ GLC(glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, requiredTextureSize.width(), requiredTextureSize.height(), 0, GL_RGBA, GL_UNSIGNED_BYTE, pixels));
+
+ m_contentsTexture = textureId;
+ m_allocatedTextureSize = requiredTextureSize;
+ } else {
+ ASSERT(updateRect.width() <= m_allocatedTextureSize.width() && updateRect.height() <= m_allocatedTextureSize.height());
+ ASSERT(updateRect.width() == bitmapSize.width() && updateRect.height() == bitmapSize.height());
+#if PLATFORM(CG)
+ // The origin is at the lower left in Core Graphics' coordinate system. We need to correct for this here.
+ GLC(glTexSubImage2D(GL_TEXTURE_2D, 0,
+ updateRect.x(), m_allocatedTextureSize.height() - updateRect.height() - updateRect.y(),
+ updateRect.width(), updateRect.height(),
+ GL_RGBA, GL_UNSIGNED_BYTE, pixels));
+#elif PLATFORM(SKIA)
+ GLC(glTexSubImage2D(GL_TEXTURE_2D, 0, updateRect.x(), updateRect.y(), updateRect.width(), updateRect.height(), GL_RGBA, GL_UNSIGNED_BYTE, pixels));
+#else
+#error "Need to implement for your platform."
+#endif
+ }
+
+ m_dirtyRect.setSize(FloatSize());
+ m_contentsDirty = false;
+}
+
+void ContentLayerChromium::draw()
+{
+ if (m_skipsDraw)
+ return;
+
+ ASSERT(layerRenderer());
+ const ContentLayerChromium::SharedValues* sv = layerRenderer()->contentLayerSharedValues();
+ ASSERT(sv && sv->initialized());
+ GLC(glActiveTexture(GL_TEXTURE0));
+ GLC(glBindTexture(GL_TEXTURE_2D, m_contentsTexture));
+ layerRenderer()->useShader(sv->contentShaderProgram());
+ GLC(glUniform1i(sv->shaderSamplerLocation(), 0));
+ drawTexturedQuad(layerRenderer()->projectionMatrix(), drawTransform(),
+ bounds().width(), bounds().height(), drawOpacity(),
+ sv->shaderMatrixLocation(), sv->shaderAlphaLocation());
+}
+
+}
+#endif // USE(ACCELERATED_COMPOSITING)
diff --git a/WebCore/platform/graphics/chromium/ContentLayerChromium.h b/WebCore/platform/graphics/chromium/ContentLayerChromium.h
new file mode 100644
index 0000000..3e15372
--- /dev/null
+++ b/WebCore/platform/graphics/chromium/ContentLayerChromium.h
@@ -0,0 +1,90 @@
+/*
+ * Copyright (C) 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 ContentLayerChromium_h
+#define ContentLayerChromium_h
+
+#if USE(ACCELERATED_COMPOSITING)
+
+#include "LayerChromium.h"
+
+namespace WebCore {
+
+// A Layer that requires a GraphicsContext to render its contents.
+class ContentLayerChromium : public LayerChromium {
+ friend class LayerRendererChromium;
+public:
+ static PassRefPtr<ContentLayerChromium> create(GraphicsLayerChromium* owner = 0);
+
+ ~ContentLayerChromium();
+
+ virtual void updateContents();
+ virtual void draw();
+ virtual bool drawsContent() { return m_owner && m_owner->drawsContent(); }
+
+ // Stores values that are shared between instances of this class that are
+ // associated with the same LayerRendererChromium (and hence the same GL
+ // context).
+ class SharedValues {
+ public:
+ SharedValues();
+ ~SharedValues();
+
+ unsigned contentShaderProgram() const { return m_contentShaderProgram; }
+ int shaderSamplerLocation() const { return m_shaderSamplerLocation; }
+ int shaderMatrixLocation() const { return m_shaderMatrixLocation; }
+ int shaderAlphaLocation() const { return m_shaderAlphaLocation; }
+ int initialized() const { return m_initialized; }
+
+ private:
+ unsigned m_contentShaderProgram;
+ int m_shaderSamplerLocation;
+ int m_shaderMatrixLocation;
+ int m_shaderAlphaLocation;
+ int m_initialized;
+ };
+
+protected:
+ ContentLayerChromium(GraphicsLayerChromium* owner);
+
+ void updateTextureRect(void* pixels, const IntSize& bitmapSize, const IntSize& requiredTextureSize,
+ const IntRect& updateRect, unsigned textureId);
+
+ unsigned m_contentsTexture;
+ IntSize m_allocatedTextureSize;
+ bool m_skipsDraw;
+
+};
+
+}
+#endif // USE(ACCELERATED_COMPOSITING)
+
+#endif
diff --git a/WebCore/platform/graphics/chromium/GLES2Canvas.cpp b/WebCore/platform/graphics/chromium/GLES2Canvas.cpp
index 534de7b..c0cb87c 100644
--- a/WebCore/platform/graphics/chromium/GLES2Canvas.cpp
+++ b/WebCore/platform/graphics/chromium/GLES2Canvas.cpp
@@ -34,13 +34,11 @@
#include "GLES2Canvas.h"
-#include "Float32Array.h"
#include "FloatRect.h"
#include "GLES2Texture.h"
#include "GraphicsContext3D.h"
#include "IntRect.h"
#include "PlatformString.h"
-#include "Uint16Array.h"
#define _USE_MATH_DEFINES
#include <math.h>
@@ -79,7 +77,6 @@ struct GLES2Canvas::State {
GLES2Canvas::GLES2Canvas(GraphicsContext3D* context, const IntSize& size)
: m_context(context)
, m_quadVertices(0)
- , m_quadIndices(0)
, m_simpleProgram(0)
, m_texProgram(0)
, m_simpleMatrixLocation(-1)
@@ -111,40 +108,33 @@ GLES2Canvas::~GLES2Canvas()
m_context->deleteProgram(m_simpleProgram);
m_context->deleteProgram(m_texProgram);
m_context->deleteBuffer(m_quadVertices);
- m_context->deleteBuffer(m_quadIndices);
}
void GLES2Canvas::clearRect(const FloatRect& rect)
{
- m_context->scissor(rect.x(), rect.y(), rect.width(), rect.height());
- m_context->enable(GraphicsContext3D::SCISSOR_TEST);
- m_context->clear(GraphicsContext3D::COLOR_BUFFER_BIT);
- m_context->disable(GraphicsContext3D::SCISSOR_TEST);
+ if (m_state->m_ctm.isIdentity()) {
+ m_context->scissor(rect.x(), rect.y(), rect.width(), rect.height());
+ m_context->enable(GraphicsContext3D::SCISSOR_TEST);
+ m_context->clear(GraphicsContext3D::COLOR_BUFFER_BIT);
+ m_context->disable(GraphicsContext3D::SCISSOR_TEST);
+ } else {
+ save();
+ setCompositeOperation(CompositeClear);
+ fillRect(rect, Color(RGBA32(0)), DeviceColorSpace);
+ restore();
+ }
}
void GLES2Canvas::fillRect(const FloatRect& rect, const Color& color, ColorSpace colorSpace)
{
- m_context->bindBuffer(GraphicsContext3D::ARRAY_BUFFER, getQuadVertices());
- m_context->bindBuffer(GraphicsContext3D::ELEMENT_ARRAY_BUFFER, getQuadIndices());
-
- float rgba[4];
- color.getRGBA(rgba[0], rgba[1], rgba[2], rgba[3]);
- m_context->uniform4f(m_simpleColorLocation, rgba[0] * rgba[3], rgba[1] * rgba[3], rgba[2] * rgba[3], rgba[3]);
-
- m_context->drawElements(GraphicsContext3D::TRIANGLES, 6, GraphicsContext3D::UNSIGNED_SHORT, 0);
-}
-
-void GLES2Canvas::fillRect(const FloatRect& rect)
-{
applyCompositeOperator(m_state->m_compositeOp);
m_context->bindBuffer(GraphicsContext3D::ARRAY_BUFFER, getQuadVertices());
- m_context->bindBuffer(GraphicsContext3D::ELEMENT_ARRAY_BUFFER, getQuadIndices());
m_context->useProgram(getSimpleProgram());
float rgba[4];
- m_state->m_fillColor.getRGBA(rgba[0], rgba[1], rgba[2], rgba[3]);
+ color.getRGBA(rgba[0], rgba[1], rgba[2], rgba[3]);
m_context->uniform4f(m_simpleColorLocation, rgba[0] * rgba[3], rgba[1] * rgba[3], rgba[2] * rgba[3], rgba[3]);
AffineTransform matrix(m_flipMatrix);
@@ -159,7 +149,12 @@ void GLES2Canvas::fillRect(const FloatRect& rect)
m_context->enableVertexAttribArray(m_simplePositionLocation);
- m_context->drawElements(GraphicsContext3D::TRIANGLES, 6, GraphicsContext3D::UNSIGNED_SHORT, 0);
+ m_context->drawArrays(GraphicsContext3D::TRIANGLE_STRIP, 0, 4);
+}
+
+void GLES2Canvas::fillRect(const FloatRect& rect)
+{
+ fillRect(rect, m_state->m_fillColor, DeviceColorSpace);
}
void GLES2Canvas::setFillColor(const Color& color, ColorSpace colorSpace)
@@ -215,7 +210,6 @@ void GLES2Canvas::drawTexturedRect(GLES2Texture* texture, const FloatRect& srcRe
applyCompositeOperator(compositeOp);
m_context->bindBuffer(GraphicsContext3D::ARRAY_BUFFER, getQuadVertices());
- m_context->bindBuffer(GraphicsContext3D::ELEMENT_ARRAY_BUFFER, getQuadIndices());
checkGLError("glBindBuffer");
m_context->useProgram(getTexProgram());
@@ -275,8 +269,8 @@ void GLES2Canvas::drawTexturedRectTile(GLES2Texture* texture, int tile, const Fl
m_context->uniformMatrix3fv(m_texTexMatrixLocation, false /*transpose*/, texMat, 1 /*count*/);
checkGLError("glUniformMatrix3fv");
- m_context->drawElements(GraphicsContext3D::TRIANGLES, 6, GraphicsContext3D::UNSIGNED_SHORT, 0);
- checkGLError("glDrawElements");
+ m_context->drawArrays(GraphicsContext3D::TRIANGLE_STRIP, 0, 4);
+ checkGLError("glDrawArrays");
}
void GLES2Canvas::setCompositeOperation(CompositeOperator op)
@@ -351,30 +345,16 @@ unsigned GLES2Canvas::getQuadVertices()
if (!m_quadVertices) {
float vertices[] = { 0.0f, 0.0f, 1.0f,
1.0f, 0.0f, 1.0f,
- 1.0f, 1.0f, 1.0f,
- 0.0f, 1.0f, 1.0f };
+ 0.0f, 1.0f, 1.0f,
+ 1.0f, 1.0f, 1.0f };
m_quadVertices = m_context->createBuffer();
- RefPtr<Float32Array> vertexArray = Float32Array::create(vertices, sizeof(vertices) / sizeof(float));
m_context->bindBuffer(GraphicsContext3D::ARRAY_BUFFER, m_quadVertices);
- m_context->bufferData(GraphicsContext3D::ARRAY_BUFFER, vertexArray.get(), GraphicsContext3D::STATIC_DRAW);
+ m_context->bufferData(GraphicsContext3D::ARRAY_BUFFER, sizeof(vertices), vertices, GraphicsContext3D::STATIC_DRAW);
}
return m_quadVertices;
}
-unsigned GLES2Canvas::getQuadIndices()
-{
- if (!m_quadIndices) {
- unsigned short indices[] = { 0, 1, 2, 0, 2, 3};
-
- m_quadIndices = m_context->createBuffer();
- RefPtr<Uint16Array> indexArray = Uint16Array::create(indices, sizeof(indices) / sizeof(unsigned short));
- m_context->bindBuffer(GraphicsContext3D::ELEMENT_ARRAY_BUFFER, m_quadIndices);
- m_context->bufferData(GraphicsContext3D::ELEMENT_ARRAY_BUFFER, indexArray.get(), GraphicsContext3D::STATIC_DRAW);
- }
- return m_quadIndices;
-}
-
static unsigned loadShader(GraphicsContext3D* context, unsigned type, const char* shaderSource)
{
unsigned shader = context->createShader(type);
diff --git a/WebCore/platform/graphics/chromium/GLES2Canvas.h b/WebCore/platform/graphics/chromium/GLES2Canvas.h
index 0ad07fc..d00510a 100644
--- a/WebCore/platform/graphics/chromium/GLES2Canvas.h
+++ b/WebCore/platform/graphics/chromium/GLES2Canvas.h
@@ -85,7 +85,6 @@ private:
void applyCompositeOperator(CompositeOperator);
void checkGLError(const char* header);
unsigned getQuadVertices();
- unsigned getQuadIndices();
unsigned getSimpleProgram();
unsigned getTexProgram();
@@ -94,7 +93,6 @@ private:
WTF::Vector<State> m_stateStack;
State* m_state;
unsigned m_quadVertices;
- unsigned m_quadIndices;
unsigned m_simpleProgram;
unsigned m_texProgram;
int m_simpleMatrixLocation;
diff --git a/WebCore/platform/graphics/chromium/GraphicsLayerChromium.cpp b/WebCore/platform/graphics/chromium/GraphicsLayerChromium.cpp
index 1d67857..648e35f 100644
--- a/WebCore/platform/graphics/chromium/GraphicsLayerChromium.cpp
+++ b/WebCore/platform/graphics/chromium/GraphicsLayerChromium.cpp
@@ -45,6 +45,7 @@
#include "GraphicsLayerChromium.h"
+#include "ContentLayerChromium.h"
#include "FloatConversion.h"
#include "FloatRect.h"
#include "Image.h"
@@ -52,7 +53,6 @@
#include "LayerChromium.h"
#include "PlatformString.h"
#include "SystemTime.h"
-#include "TransformLayerChromium.h"
#include <wtf/CurrentTime.h>
#include <wtf/StringExtras.h>
@@ -97,7 +97,7 @@ GraphicsLayerChromium::GraphicsLayerChromium(GraphicsLayerClient* client)
, m_contentsLayerPurpose(NoContentsLayer)
, m_contentsLayerHasBackgroundColor(false)
{
- m_layer = LayerChromium::create(this);
+ m_layer = ContentLayerChromium::create(this);
updateDebugIndicators();
}
@@ -538,7 +538,7 @@ void GraphicsLayerChromium::updateLayerPreserves3D()
{
if (m_preserves3D && !m_transformLayer) {
// Create the transform layer.
- m_transformLayer = TransformLayerChromium::create(this);
+ m_transformLayer = LayerChromium::create(this);
// Copy the position from this layer.
updateLayerPosition();
diff --git a/WebCore/platform/graphics/chromium/ImageLayerChromium.cpp b/WebCore/platform/graphics/chromium/ImageLayerChromium.cpp
index 3cc7cad..09b388d 100644
--- a/WebCore/platform/graphics/chromium/ImageLayerChromium.cpp
+++ b/WebCore/platform/graphics/chromium/ImageLayerChromium.cpp
@@ -34,6 +34,8 @@
#include "ImageLayerChromium.h"
+#include "LayerRendererChromium.h"
+
#if PLATFORM(SKIA)
#include "NativeImageSkia.h"
#include "PlatformContextSkia.h"
@@ -54,7 +56,7 @@ PassRefPtr<ImageLayerChromium> ImageLayerChromium::create(GraphicsLayerChromium*
}
ImageLayerChromium::ImageLayerChromium(GraphicsLayerChromium* owner)
- : LayerChromium(owner)
+ : ContentLayerChromium(owner)
, m_contents(0)
{
}
@@ -68,8 +70,10 @@ void ImageLayerChromium::setContents(NativeImagePtr contents)
setNeedsDisplay();
}
-void ImageLayerChromium::updateTextureContents(unsigned textureId)
+void ImageLayerChromium::updateContents()
{
+ ASSERT(layerRenderer());
+
void* pixels = 0;
IntRect dirtyRect(m_dirtyRect);
IntSize requiredTextureSize;
@@ -129,6 +133,17 @@ void ImageLayerChromium::updateTextureContents(unsigned textureId)
#else
#error "Need to implement for your platform."
#endif
+ // FIXME: Remove this test when tiled layers are implemented.
+ m_skipsDraw = false;
+ if (!layerRenderer()->checkTextureSize(requiredTextureSize)) {
+ m_skipsDraw = true;
+ return;
+ }
+
+ unsigned textureId = m_contentsTexture;
+ if (!textureId)
+ textureId = layerRenderer()->createLayerTexture();
+
if (pixels)
updateTextureRect(pixels, bitmapSize, requiredTextureSize, dirtyRect, textureId);
}
diff --git a/WebCore/platform/graphics/chromium/ImageLayerChromium.h b/WebCore/platform/graphics/chromium/ImageLayerChromium.h
index 9355b2d..e95284c 100644
--- a/WebCore/platform/graphics/chromium/ImageLayerChromium.h
+++ b/WebCore/platform/graphics/chromium/ImageLayerChromium.h
@@ -34,16 +34,18 @@
#if USE(ACCELERATED_COMPOSITING)
-#include "LayerChromium.h"
+#include "ContentLayerChromium.h"
namespace WebCore {
// A Layer that contains only an Image element.
-class ImageLayerChromium : public LayerChromium {
+class ImageLayerChromium : public ContentLayerChromium {
public:
static PassRefPtr<ImageLayerChromium> create(GraphicsLayerChromium* owner = 0);
+
+ virtual void updateContents();
virtual bool drawsContent() { return m_contents; }
- virtual void updateTextureContents(unsigned textureId);
+
void setContents(NativeImagePtr);
private:
diff --git a/WebCore/platform/graphics/chromium/LayerChromium.cpp b/WebCore/platform/graphics/chromium/LayerChromium.cpp
index 21d8d12..3553878 100644
--- a/WebCore/platform/graphics/chromium/LayerChromium.cpp
+++ b/WebCore/platform/graphics/chromium/LayerChromium.cpp
@@ -48,7 +48,93 @@ namespace WebCore {
using namespace std;
-unsigned LayerChromium::m_shaderProgramId = 0;
+const unsigned LayerChromium::s_positionAttribLocation = 0;
+const unsigned LayerChromium::s_texCoordAttribLocation = 1;
+
+static GLuint loadShader(GLenum type, const char* shaderSource)
+{
+ GLuint shader = glCreateShader(type);
+ if (!shader)
+ return 0;
+ GLC(glShaderSource(shader, 1, &shaderSource, 0));
+ GLC(glCompileShader(shader));
+ GLint compiled;
+ GLC(glGetShaderiv(shader, GL_COMPILE_STATUS, &compiled));
+ if (!compiled) {
+ GLC(glDeleteShader(shader));
+ return 0;
+ }
+ return shader;
+}
+
+LayerChromium::SharedValues::SharedValues()
+ : m_quadVerticesVbo(0)
+ , m_quadElementsVbo(0)
+ , m_maxTextureSize(0)
+ , m_borderShaderProgram(0)
+ , m_borderShaderMatrixLocation(-1)
+ , m_borderShaderColorLocation(-1)
+ , m_initialized(false)
+{
+ // Vertex positions and texture coordinates for the 4 corners of a 1x1 quad.
+ GLfloat vertices[] = { -0.5f, 0.5f, 0.0f, 0.0f, 1.0f,
+ -0.5f, -0.5f, 0.0f, 0.0f, 0.0f,
+ 0.5f, -0.5f, 0.0f, 1.0f, 0.0f,
+ 0.5f, 0.5f, 0.0f, 1.0f, 1.0f };
+ GLushort indices[] = { 0, 1, 2, 0, 2, 3, // The two triangles that make up the layer quad.
+ 0, 1, 2, 3}; // A line path for drawing the layer border.
+
+ GLuint vboIds[2];
+ GLC(glGenBuffers(2, vboIds));
+ m_quadVerticesVbo = vboIds[0];
+ m_quadElementsVbo = vboIds[1];
+ GLC(glBindBuffer(GL_ARRAY_BUFFER, m_quadVerticesVbo));
+ GLC(glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW));
+ GLC(glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_quadElementsVbo));
+ GLC(glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW));
+
+ // Get the max texture size supported by the system.
+ GLC(glGetIntegerv(GL_MAX_TEXTURE_SIZE, &m_maxTextureSize));
+
+ // Shaders for drawing the debug borders around the layers.
+ char borderVertexShaderString[] =
+ "attribute vec4 a_position; \n"
+ "uniform mat4 matrix; \n"
+ "void main() \n"
+ "{ \n"
+ " gl_Position = matrix * a_position; \n"
+ "} \n";
+ char borderFragmentShaderString[] =
+ "precision mediump float; \n"
+ "uniform vec4 color; \n"
+ "void main() \n"
+ "{ \n"
+ " gl_FragColor = color; \n"
+ "} \n";
+
+ m_borderShaderProgram = createShaderProgram(borderVertexShaderString, borderFragmentShaderString);
+ if (!m_borderShaderProgram) {
+ LOG_ERROR("ContentLayerChromium: Failed to create shader program");
+ return;
+ }
+
+ m_borderShaderMatrixLocation = glGetUniformLocation(m_borderShaderProgram, "matrix");
+ m_borderShaderColorLocation = glGetUniformLocation(m_borderShaderProgram, "color");
+ ASSERT(m_borderShaderMatrixLocation != -1);
+ ASSERT(m_borderShaderColorLocation != -1);
+
+ m_initialized = true;
+}
+
+LayerChromium::SharedValues::~SharedValues()
+{
+ GLuint vboIds[2] = { m_quadVerticesVbo, m_quadElementsVbo };
+ GLC(glDeleteBuffers(2, vboIds));
+
+ if (m_borderShaderProgram)
+ GLC(glDeleteProgram(m_borderShaderProgram));
+}
+
PassRefPtr<LayerChromium> LayerChromium::create(GraphicsLayerChromium* owner)
{
@@ -62,13 +148,10 @@ LayerChromium::LayerChromium(GraphicsLayerChromium* owner)
, m_anchorPoint(0.5, 0.5)
, m_backgroundColor(0, 0, 0, 0)
, m_borderColor(0, 0, 0, 0)
- , m_layerRenderer(0)
- , m_edgeAntialiasingMask(0)
, m_opacity(1.0)
, m_zPosition(0.0)
, m_anchorPointZ(0)
, m_borderWidth(0)
- , m_allocatedTextureId(0)
, m_clearsContext(false)
, m_doubleSided(true)
, m_hidden(false)
@@ -76,6 +159,7 @@ LayerChromium::LayerChromium(GraphicsLayerChromium* owner)
, m_opaque(true)
, m_geometryFlipped(false)
, m_needsDisplayOnBoundsChange(false)
+ , m_layerRenderer(0)
{
}
@@ -87,10 +171,6 @@ LayerChromium::~LayerChromium()
// Remove the superlayer reference from all sublayers.
removeAllSublayers();
-
- // Notify the renderer to clean up the texture associated with the layer.
- if (m_layerRenderer)
- m_layerRenderer->freeLayerTexture(this);
}
void LayerChromium::setLayerRenderer(LayerRendererChromium* renderer)
@@ -101,140 +181,46 @@ void LayerChromium::setLayerRenderer(LayerRendererChromium* renderer)
m_layerRenderer = renderer;
}
-void LayerChromium::updateTextureContents(unsigned textureId)
+unsigned LayerChromium::createShaderProgram(const char* vertexShaderSource, const char* fragmentShaderSource)
{
- RenderLayerBacking* backing = static_cast<RenderLayerBacking*>(m_owner->client());
- if (!backing || backing->paintingGoesToWindow())
- return;
-
- ASSERT(drawsContent());
-
- void* pixels = 0;
- IntRect dirtyRect(m_dirtyRect);
- IntSize requiredTextureSize;
- IntSize bitmapSize;
-
-#if PLATFORM(SKIA)
- const SkBitmap* skiaBitmap = 0;
- OwnPtr<skia::PlatformCanvas> canvas;
- OwnPtr<PlatformContextSkia> skiaContext;
- OwnPtr<GraphicsContext> graphicsContext;
-
- requiredTextureSize = m_bounds;
- IntRect boundsRect(IntPoint(0, 0), m_bounds);
-
- // If the texture needs to be reallocated then we must redraw the entire
- // contents of the layer.
- if (requiredTextureSize != m_allocatedTextureSize)
- dirtyRect = boundsRect;
- else {
- // Clip the dirtyRect to the size of the layer to avoid drawing outside
- // the bounds of the backing texture.
- dirtyRect.intersect(boundsRect);
+ GLuint vertexShader = loadShader(GL_VERTEX_SHADER, vertexShaderSource);
+ if (!vertexShader) {
+ LOG_ERROR("Failed to create vertex shader");
+ return 0;
}
- canvas.set(new skia::PlatformCanvas(dirtyRect.width(), dirtyRect.height(), false));
- skiaContext.set(new PlatformContextSkia(canvas.get()));
-
-#if OS(WINDOWS)
- // This is needed to get text to show up correctly. Without it,
- // GDI renders with zero alpha and the text becomes invisible.
- // Unfortunately, setting this to true disables cleartype.
- // FIXME: Does this take us down a very slow text rendering path?
- // FIXME: why is this is a windows-only call ?
- skiaContext->setDrawingToImageBuffer(true);
-#endif
-
- graphicsContext.set(new GraphicsContext(reinterpret_cast<PlatformGraphicsContext*>(skiaContext.get())));
-
- // Bring the canvas into the coordinate system of the paint rect.
- canvas->translate(static_cast<SkScalar>(-dirtyRect.x()), static_cast<SkScalar>(-dirtyRect.y()));
-
- m_owner->paintGraphicsLayerContents(*graphicsContext, dirtyRect);
- const SkBitmap& bitmap = canvas->getDevice()->accessBitmap(false);
- skiaBitmap = &bitmap;
- ASSERT(skiaBitmap);
-
- SkAutoLockPixels lock(*skiaBitmap);
- SkBitmap::Config skiaConfig = skiaBitmap->config();
- // FIXME: do we need to support more image configurations?
- if (skiaConfig == SkBitmap::kARGB_8888_Config) {
- pixels = skiaBitmap->getPixels();
- bitmapSize = IntSize(skiaBitmap->width(), skiaBitmap->height());
- }
-#elif PLATFORM(CG)
- requiredTextureSize = m_bounds;
- IntRect boundsRect(IntPoint(0, 0), m_bounds);
-
- // If the texture needs to be reallocated then we must redraw the entire
- // contents of the layer.
- if (requiredTextureSize != m_allocatedTextureSize)
- dirtyRect = boundsRect;
- else {
- // Clip the dirtyRect to the size of the layer to avoid drawing outside
- // the bounds of the backing texture.
- dirtyRect.intersect(boundsRect);
+ GLuint fragmentShader = loadShader(GL_FRAGMENT_SHADER, fragmentShaderSource);
+ if (!fragmentShader) {
+ GLC(glDeleteShader(vertexShader));
+ LOG_ERROR("Failed to create fragment shader");
+ return 0;
}
- Vector<uint8_t> tempVector;
- int rowBytes = 4 * dirtyRect.width();
- tempVector.resize(rowBytes * dirtyRect.height());
- memset(tempVector.data(), 0, tempVector.size());
- RetainPtr<CGColorSpaceRef> colorSpace(AdoptCF, CGColorSpaceCreateDeviceRGB());
- RetainPtr<CGContextRef> contextCG(AdoptCF, CGBitmapContextCreate(tempVector.data(),
- dirtyRect.width(), dirtyRect.height(), 8, rowBytes,
- colorSpace.get(),
- kCGImageAlphaPremultipliedLast));
-
- GraphicsContext graphicsContext(contextCG.get());
-
- // Translate the graphics contxt into the coordinate system of the dirty rect.
- graphicsContext.translate(-dirtyRect.x(), -dirtyRect.y());
-
- m_owner->paintGraphicsLayerContents(graphicsContext, dirtyRect);
-
- pixels = tempVector.data();
- bitmapSize = dirtyRect.size();
-#else
-#error "Need to implement for your platform."
-#endif
+ GLuint programObject = glCreateProgram();
+ if (!programObject) {
+ LOG_ERROR("Failed to create shader program");
+ return 0;
+ }
- if (pixels)
- updateTextureRect(pixels, bitmapSize, requiredTextureSize, dirtyRect, textureId);
-}
+ GLC(glAttachShader(programObject, vertexShader));
+ GLC(glAttachShader(programObject, fragmentShader));
-void LayerChromium::updateTextureRect(void* pixels, const IntSize& bitmapSize, const IntSize& requiredTextureSize, const IntRect& updateRect, unsigned textureId)
-{
- if (!pixels)
- return;
+ // Bind the common attrib locations.
+ GLC(glBindAttribLocation(programObject, s_positionAttribLocation, "a_position"));
+ GLC(glBindAttribLocation(programObject, s_texCoordAttribLocation, "a_texCoord"));
- glBindTexture(GL_TEXTURE_2D, textureId);
- // If the texture id or size changed since last time then we need to tell GL
- // to re-allocate a texture.
- if (m_allocatedTextureId != textureId || requiredTextureSize != m_allocatedTextureSize) {
- ASSERT(bitmapSize == requiredTextureSize);
- glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, requiredTextureSize.width(), requiredTextureSize.height(), 0, GL_RGBA, GL_UNSIGNED_BYTE, pixels);
-
- m_allocatedTextureId = textureId;
- m_allocatedTextureSize = requiredTextureSize;
- } else {
- ASSERT(updateRect.width() <= m_allocatedTextureSize.width() && updateRect.height() <= m_allocatedTextureSize.height());
- ASSERT(updateRect.width() == bitmapSize.width() && updateRect.height() == bitmapSize.height());
-#if PLATFORM(CG)
- // The origin is at the lower left in Core Graphics' coordinate system. We need to correct for this here.
- glTexSubImage2D(GL_TEXTURE_2D, 0,
- updateRect.x(), m_allocatedTextureSize.height() - updateRect.height() - updateRect.y(),
- updateRect.width(), updateRect.height(),
- GL_RGBA, GL_UNSIGNED_BYTE, pixels);
-#elif PLATFORM(SKIA)
- glTexSubImage2D(GL_TEXTURE_2D, 0, updateRect.x(), updateRect.y(), updateRect.width(), updateRect.height(), GL_RGBA, GL_UNSIGNED_BYTE, pixels);
-#else
-#error "Need to implement for your platform."
-#endif
+ GLC(glLinkProgram(programObject));
+ GLint linked;
+ GLC(glGetProgramiv(programObject, GL_LINK_STATUS, &linked));
+ if (!linked) {
+ LOG_ERROR("Failed to link shader program");
+ GLC(glDeleteProgram(programObject));
+ return 0;
}
- m_dirtyRect.setSize(FloatSize());
- m_contentsDirty = false;
+ GLC(glDeleteShader(vertexShader));
+ GLC(glDeleteShader(fragmentShader));
+ return programObject;
}
void LayerChromium::setNeedsCommit()
@@ -377,5 +363,86 @@ void LayerChromium::setNeedsDisplay()
m_contentsDirty = true;
}
+void LayerChromium::toGLMatrix(float* flattened, const TransformationMatrix& m)
+{
+ flattened[0] = m.m11();
+ flattened[1] = m.m12();
+ flattened[2] = m.m13();
+ flattened[3] = m.m14();
+ flattened[4] = m.m21();
+ flattened[5] = m.m22();
+ flattened[6] = m.m23();
+ flattened[7] = m.m24();
+ flattened[8] = m.m31();
+ flattened[9] = m.m32();
+ flattened[10] = m.m33();
+ flattened[11] = m.m34();
+ flattened[12] = m.m41();
+ flattened[13] = m.m42();
+ flattened[14] = m.m43();
+ flattened[15] = m.m44();
+}
+
+void LayerChromium::drawTexturedQuad(const TransformationMatrix& projectionMatrix, const TransformationMatrix& drawMatrix,
+ float width, float height, float opacity,
+ int matrixLocation, int alphaLocation)
+{
+ static GLfloat glMatrix[16];
+
+ TransformationMatrix renderMatrix = drawMatrix;
+
+ // Apply a scaling factor to size the quad from 1x1 to its intended size.
+ renderMatrix.scale3d(width, height, 1);
+
+ // Apply the projection matrix before sending the transform over to the shader.
+ renderMatrix.multiply(projectionMatrix);
+
+ toGLMatrix(&glMatrix[0], renderMatrix);
+
+ GLC(glUniformMatrix4fv(matrixLocation, 1, false, &glMatrix[0]));
+
+ if (alphaLocation != -1)
+ GLC(glUniform1f(alphaLocation, opacity));
+
+ GLC(glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, 0));
+}
+
+void LayerChromium::drawDebugBorder()
+{
+ static GLfloat glMatrix[16];
+ if (!borderColor().alpha())
+ return;
+
+ ASSERT(layerRenderer());
+ const SharedValues* sv = layerRenderer()->layerSharedValues();
+ ASSERT(sv && sv->initialized());
+ layerRenderer()->useShader(sv->borderShaderProgram());
+ TransformationMatrix renderMatrix = drawTransform();
+ renderMatrix.scale3d(bounds().width(), bounds().height(), 1);
+ renderMatrix.multiply(layerRenderer()->projectionMatrix());
+ toGLMatrix(&glMatrix[0], renderMatrix);
+ GLC(glUniformMatrix4fv(sv->borderShaderMatrixLocation(), 1, false, &glMatrix[0]));
+
+ GLC(glUniform4f(sv->borderShaderColorLocation(), borderColor().red() / 255.0, borderColor().green() / 255.0, borderColor().blue() / 255.0, 1));
+
+ GLC(glLineWidth(borderWidth()));
+
+ // The indices for the line are stored in the same array as the triangle indices.
+ GLC(glDrawElements(GL_LINE_LOOP, 4, GL_UNSIGNED_SHORT, (void*)(6 * sizeof(unsigned short))));
+}
+
+// static
+void LayerChromium::prepareForDraw(const SharedValues* sv)
+{
+ GLC(glBindBuffer(GL_ARRAY_BUFFER, sv->quadVerticesVbo()));
+ GLC(glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, sv->quadElementsVbo()));
+ GLuint offset = 0;
+ GLC(glVertexAttribPointer(s_positionAttribLocation, 3, GL_FLOAT, GL_FALSE, 5 * sizeof(GLfloat), (GLvoid*)offset));
+ offset += 3 * sizeof(GLfloat);
+ GLC(glVertexAttribPointer(s_texCoordAttribLocation, 2, GL_FLOAT, GL_FALSE, 5 * sizeof(GLfloat), (GLvoid*)offset));
+ GLC(glEnableVertexAttribArray(s_positionAttribLocation));
+ GLC(glEnableVertexAttribArray(s_texCoordAttribLocation));
+}
+
}
#endif // USE(ACCELERATED_COMPOSITING)
diff --git a/WebCore/platform/graphics/chromium/LayerChromium.h b/WebCore/platform/graphics/chromium/LayerChromium.h
index 9fba415..0d0d362 100644
--- a/WebCore/platform/graphics/chromium/LayerChromium.h
+++ b/WebCore/platform/graphics/chromium/LayerChromium.h
@@ -55,19 +55,24 @@ namespace WebCore {
class GraphicsContext3D;
class LayerRendererChromium;
-// Base class for composited layers. The implementation covers layers that require
-// a GraphicsContext to render their contents. Special layer types are derived from
+// Base class for composited layers. Special layer types are derived from
// this class.
class LayerChromium : public RefCounted<LayerChromium> {
+ friend class LayerRendererChromium;
public:
static PassRefPtr<LayerChromium> create(GraphicsLayerChromium* owner = 0);
~LayerChromium();
+ const LayerChromium* rootLayer() const;
+ LayerChromium* superlayer() const;
void addSublayer(PassRefPtr<LayerChromium>);
void insertSublayer(PassRefPtr<LayerChromium>, size_t index);
void replaceSublayer(LayerChromium* reference, PassRefPtr<LayerChromium> newLayer);
void removeFromSuperlayer();
+ void removeAllSublayers();
+ void setSublayers(const Vector<RefPtr<LayerChromium> >&);
+ const Vector<RefPtr<LayerChromium> >& getSublayers() const { return m_sublayers; }
void setAnchorPoint(const FloatPoint& anchorPoint) { m_anchorPoint = anchorPoint; setNeedsCommit(); }
FloatPoint anchorPoint() const { return m_anchorPoint; }
@@ -93,9 +98,6 @@ public:
void setDoubleSided(bool doubleSided) { m_doubleSided = doubleSided; setNeedsCommit(); }
bool doubleSided() const { return m_doubleSided; }
- void setEdgeAntialiasingMask(uint32_t mask) { m_edgeAntialiasingMask = mask; setNeedsCommit(); }
- uint32_t edgeAntialiasingMask() const { return m_edgeAntialiasingMask; }
-
void setFrame(const FloatRect&);
FloatRect frame() const { return m_frame; }
@@ -120,76 +122,99 @@ public:
bool opaque() const { return m_opaque; }
void setPosition(const FloatPoint& position) { m_position = position; setNeedsCommit(); }
-
FloatPoint position() const { return m_position; }
void setZPosition(float zPosition) { m_zPosition = zPosition; setNeedsCommit(); }
float zPosition() const { return m_zPosition; }
- const LayerChromium* rootLayer() const;
-
- void removeAllSublayers();
-
- void setSublayers(const Vector<RefPtr<LayerChromium> >&);
-
- const Vector<RefPtr<LayerChromium> >& getSublayers() const { return m_sublayers; }
-
void setSublayerTransform(const TransformationMatrix& transform) { m_sublayerTransform = transform; setNeedsCommit(); }
const TransformationMatrix& sublayerTransform() const { return m_sublayerTransform; }
- LayerChromium* superlayer() const;
-
-
void setTransform(const TransformationMatrix& transform) { m_transform = transform; setNeedsCommit(); }
const TransformationMatrix& transform() const { return m_transform; }
+ // FIXME: This setting is currently ignored.
void setGeometryFlipped(bool flipped) { m_geometryFlipped = flipped; setNeedsCommit(); }
bool geometryFlipped() const { return m_geometryFlipped; }
- virtual void updateTextureContents(unsigned textureId);
- bool contentsDirty() { return m_contentsDirty; }
-
void setDrawTransform(const TransformationMatrix& transform) { m_drawTransform = transform; }
const TransformationMatrix& drawTransform() const { return m_drawTransform; }
void setDrawOpacity(float opacity) { m_drawOpacity = opacity; }
float drawOpacity() const { return m_drawOpacity; }
- virtual bool drawsContent() { return m_owner && m_owner->drawsContent(); }
-
- // Return true if the layer has its own GL texture and false if the texture
- // needs to be allocated by the compositor.
- virtual bool ownsTexture() { return false; }
-
- // Returns the id of the GL texture that stores the contents of this layer.
- // Derived layer classes that own their own textures should overwrite this method.
- virtual unsigned textureId() { return m_allocatedTextureId; }
-
bool preserves3D() { return m_owner && m_owner->preserves3D(); }
void setLayerRenderer(LayerRendererChromium*);
- static void setShaderProgramId(unsigned shaderProgramId) { m_shaderProgramId = shaderProgramId; }
- virtual unsigned shaderProgramId() { return m_shaderProgramId; }
-
void setOwner(GraphicsLayerChromium* owner) { m_owner = owner; }
+ bool contentsDirty() { return m_contentsDirty; }
+
+ // These methods typically need to be overwritten by derived classes.
+ virtual bool drawsContent() { return false; }
+ virtual void updateContents() { };
+ virtual void draw() { };
+
+ void drawDebugBorder();
+
+ // Stores values that are shared between instances of this class that are
+ // associated with the same LayerRendererChromium (and hence the same GL
+ // context).
+ class SharedValues {
+ public:
+ SharedValues();
+ ~SharedValues();
+
+ unsigned quadVerticesVbo() const { return m_quadVerticesVbo; }
+ unsigned quadElementsVbo() const { return m_quadElementsVbo; }
+ int maxTextureSize() const { return m_maxTextureSize; }
+ unsigned borderShaderProgram() const { return m_borderShaderProgram; }
+ int borderShaderMatrixLocation() const { return m_borderShaderMatrixLocation; }
+ int borderShaderColorLocation() const { return m_borderShaderColorLocation; }
+ bool initialized() const { return m_initialized; }
+
+ private:
+ unsigned m_quadVerticesVbo;
+ unsigned m_quadElementsVbo;
+ int m_maxTextureSize;
+ unsigned m_borderShaderProgram;
+ int m_borderShaderMatrixLocation;
+ int m_borderShaderColorLocation;
+ bool m_initialized;
+ };
+
+ static void prepareForDraw(const SharedValues*);
+
protected:
GraphicsLayerChromium* m_owner;
LayerChromium(GraphicsLayerChromium* owner);
- void updateTextureRect(void* pixels, const IntSize& bitmapSize, const IntSize& requiredTextureSize, const IntRect& dirtyRect, unsigned textureId);
+
+ LayerRendererChromium* layerRenderer() const { return m_layerRenderer; }
+
+ static void drawTexturedQuad(const TransformationMatrix& projectionMatrix, const TransformationMatrix& layerMatrix,
+ float width, float height, float opacity,
+ int matrixLocation, int alphaLocation);
+
+ static void toGLMatrix(float*, const TransformationMatrix&);
+
+ static unsigned createShaderProgram(const char* vertexShaderSource, const char* fragmentShaderSource);
IntSize m_bounds;
FloatRect m_dirtyRect;
bool m_contentsDirty;
+ // All layer shaders share the same attribute locations for the vertex positions
+ // and texture coordinates. This allows switching shaders without rebinding attribute
+ // arrays.
+ static const unsigned s_positionAttribLocation;
+ static const unsigned s_texCoordAttribLocation;
+
private:
void setNeedsCommit();
void setSuperlayer(LayerChromium* superlayer) { m_superlayer = superlayer; }
- void paintMe();
-
size_t numSublayers() const
{
return m_sublayers.size();
@@ -204,35 +229,17 @@ private:
Vector<RefPtr<LayerChromium> > m_sublayers;
LayerChromium* m_superlayer;
+ // Layer properties.
IntSize m_backingStoreSize;
FloatPoint m_position;
FloatPoint m_anchorPoint;
Color m_backgroundColor;
Color m_borderColor;
-
- LayerRendererChromium* m_layerRenderer;
-
- FloatRect m_frame;
- TransformationMatrix m_transform;
- TransformationMatrix m_sublayerTransform;
-
- TransformationMatrix m_drawTransform;
-
- uint32_t m_edgeAntialiasingMask;
float m_opacity;
float m_zPosition;
float m_anchorPointZ;
float m_borderWidth;
-
float m_drawOpacity;
-
- unsigned m_allocatedTextureId;
- IntSize m_allocatedTextureSize;
-
- // The shader program used by all layers of this type is the same.
- // This static can be shadowed by derived classes to use a special shader.
- static unsigned m_shaderProgramId;
-
bool m_clearsContext;
bool m_doubleSided;
bool m_hidden;
@@ -241,6 +248,14 @@ private:
bool m_geometryFlipped;
bool m_needsDisplayOnBoundsChange;
+ // Points to the layer renderer that updates and draws this layer.
+ LayerRendererChromium* m_layerRenderer;
+
+ FloatRect m_frame;
+ TransformationMatrix m_transform;
+ TransformationMatrix m_sublayerTransform;
+ TransformationMatrix m_drawTransform;
+
String m_name;
};
diff --git a/WebCore/platform/graphics/chromium/LayerRendererChromium.cpp b/WebCore/platform/graphics/chromium/LayerRendererChromium.cpp
index 2f70efa..cf23871 100644
--- a/WebCore/platform/graphics/chromium/LayerRendererChromium.cpp
+++ b/WebCore/platform/graphics/chromium/LayerRendererChromium.cpp
@@ -35,10 +35,10 @@
#include "LayerRendererChromium.h"
#include "CanvasLayerChromium.h"
+#include "ContentLayerChromium.h"
#include "GLES2Context.h"
#include "LayerChromium.h"
#include "NotImplemented.h"
-#include "TransformLayerChromium.h"
#if PLATFORM(SKIA)
#include "NativeImageSkia.h"
#include "PlatformContextSkia.h"
@@ -50,101 +50,6 @@
namespace WebCore {
-#ifndef NDEBUG
-static WTFLogChannel LogLayerRenderer = { 0x00000000, "LayerRenderer", WTFLogChannelOn };
-#endif
-
-static void checkGLError()
-{
-#ifndef NDEBUG
- GLenum error = glGetError();
- if (error)
- LOG_ERROR("GL Error: %d " , error);
-#endif
-}
-
-static GLuint loadShader(GLenum type, const char* shaderSource)
-{
- GLuint shader = glCreateShader(type);
- if (!shader)
- return 0;
- glShaderSource(shader, 1, &shaderSource, 0);
- glCompileShader(shader);
- GLint compiled;
- glGetShaderiv(shader, GL_COMPILE_STATUS, &compiled);
- if (!compiled) {
- glDeleteShader(shader);
- return 0;
- }
- return shader;
-}
-
-static GLuint loadShaderProgram(const char* vertexShaderSource, const char* fragmentShaderSource)
-{
- GLuint vertexShader;
- GLuint fragmentShader;
- GLuint programObject;
- GLint linked;
- vertexShader = loadShader(GL_VERTEX_SHADER, vertexShaderSource);
- if (!vertexShader)
- return 0;
- fragmentShader = loadShader(GL_FRAGMENT_SHADER, fragmentShaderSource);
- if (!fragmentShader) {
- glDeleteShader(vertexShader);
- return 0;
- }
- programObject = glCreateProgram();
- if (!programObject)
- return 0;
- glAttachShader(programObject, vertexShader);
- glAttachShader(programObject, fragmentShader);
- glLinkProgram(programObject);
- glGetProgramiv(programObject, GL_LINK_STATUS, &linked);
- if (!linked) {
- glDeleteProgram(programObject);
- return 0;
- }
- glDeleteShader(vertexShader);
- glDeleteShader(fragmentShader);
- return programObject;
-}
-
-bool LayerRendererChromium::createLayerShader(ShaderProgramType type, const char* vertexShaderSource, const char* fragmentShaderSource)
-{
- unsigned programId = loadShaderProgram(vertexShaderSource, fragmentShaderSource);
- ASSERT(programId);
-
- ShaderProgram* program = &m_shaderPrograms[type];
-
- program->m_shaderProgramId = programId;
- program->m_samplerLocation = glGetUniformLocation(programId, "s_texture");
- program->m_matrixLocation = glGetUniformLocation(programId, "matrix");
- program->m_alphaLocation = glGetUniformLocation(programId, "alpha");
-
- return programId;
-}
-
-
-static void toGLMatrix(float* flattened, const TransformationMatrix& m)
-{
- flattened[0] = m.m11();
- flattened[1] = m.m12();
- flattened[2] = m.m13();
- flattened[3] = m.m14();
- flattened[4] = m.m21();
- flattened[5] = m.m22();
- flattened[6] = m.m23();
- flattened[7] = m.m24();
- flattened[8] = m.m31();
- flattened[9] = m.m32();
- flattened[10] = m.m33();
- flattened[11] = m.m34();
- flattened[12] = m.m41();
- flattened[13] = m.m42();
- flattened[14] = m.m43();
- flattened[15] = m.m44();
-}
-
static TransformationMatrix orthoMatrix(float left, float right, float bottom, float top, float nearZ, float farZ)
{
float deltaX = right - left;
@@ -162,21 +67,6 @@ static TransformationMatrix orthoMatrix(float left, float right, float bottom, f
return ortho;
}
-// Creates a GL texture object to be used for transfering the layer's bitmap into.
-static GLuint createLayerTexture()
-{
- GLuint textureId = 0;
- glGenTextures(1, &textureId);
- glBindTexture(GL_TEXTURE_2D, textureId);
- // Do basic linear filtering on resize.
- glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
- glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
- // NPOT textures in GL ES only work when the wrap mode is set to GL_CLAMP_TO_EDGE.
- glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
- glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
- return textureId;
-}
-
static inline bool compareLayerZ(const LayerChromium* a, const LayerChromium* b)
{
const TransformationMatrix& transformA = a->drawTransform();
@@ -185,51 +75,35 @@ static inline bool compareLayerZ(const LayerChromium* a, const LayerChromium* b)
return transformA.m43() < transformB.m43();
}
-ShaderProgram::ShaderProgram()
- : m_shaderProgramId(0)
- , m_samplerLocation(-1)
- , m_matrixLocation(-1)
- , m_alphaLocation(-1)
-{
-}
-
PassOwnPtr<LayerRendererChromium> LayerRendererChromium::create(PassOwnPtr<GLES2Context> gles2Context)
{
return new LayerRendererChromium(gles2Context);
}
LayerRendererChromium::LayerRendererChromium(PassOwnPtr<GLES2Context> gles2Context)
- : m_rootLayerTextureWidth(0)
+ : m_rootLayerTextureId(0)
+ , m_rootLayerTextureWidth(0)
, m_rootLayerTextureHeight(0)
- , m_positionLocation(0)
- , m_texCoordLocation(1)
+ , m_scrollShaderProgram(0)
, m_rootLayer(0)
, m_needsDisplay(false)
, m_scrollPosition(IntPoint(-1, -1))
- , m_currentShaderProgramType(NumShaderProgramTypes)
+ , m_currentShader(0)
, m_gles2Context(gles2Context)
{
- m_quadVboIds[Vertices] = m_quadVboIds[LayerElements] = 0;
- m_hardwareCompositing = (m_gles2Context && initializeSharedGLObjects());
+ m_hardwareCompositing = (m_gles2Context && initializeSharedObjects());
}
LayerRendererChromium::~LayerRendererChromium()
{
- if (m_hardwareCompositing) {
- makeContextCurrent();
- glDeleteBuffers(3, m_quadVboIds);
-
- for (int i = 0; i < NumShaderProgramTypes; i++) {
- if (m_shaderPrograms[i].m_shaderProgramId)
- glDeleteProgram(m_shaderPrograms[i].m_shaderProgramId);
- }
- }
+ cleanupSharedObjects();
+}
- // Free up all GL textures.
- for (TextureIdMap::iterator iter = m_textureIdMap.begin(); iter != m_textureIdMap.end(); ++iter) {
- glDeleteTextures(1, &(iter->second));
- iter->first->setLayerRenderer(0);
- }
+void LayerRendererChromium::debugGLCall(const char* command, const char* file, int line)
+{
+ GLenum error = glGetError();
+ if (error != GL_NO_ERROR)
+ LOG_ERROR("GL command failed: File: %s\n\tLine %d\n\tcommand: %s, error %x\n", file, line, command, error);
}
// Creates a canvas and an associated graphics context that the root layer will
@@ -268,43 +142,14 @@ void LayerRendererChromium::setRootLayerCanvasSize(const IntSize& size)
m_rootLayerCanvasSize = size;
}
-void LayerRendererChromium::useShaderProgram(ShaderProgramType programType)
+void LayerRendererChromium::useShader(unsigned programId)
{
- if (programType != m_currentShaderProgramType) {
- ShaderProgram* program = &m_shaderPrograms[programType];
- glUseProgram(program->m_shaderProgramId);
- m_currentShaderProgramType = programType;
-
- // Set the uniform locations matching the program.
- m_samplerLocation = program->m_samplerLocation;
- m_matrixLocation = program->m_matrixLocation;
- m_alphaLocation = program->m_alphaLocation;
+ if (programId != m_currentShader) {
+ GLC(glUseProgram(programId));
+ m_currentShader = programId;
}
}
-void LayerRendererChromium::drawTexturedQuad(const TransformationMatrix& matrix, float width, float height, float opacity)
-{
- static GLfloat glMatrix[16];
-
- TransformationMatrix renderMatrix = matrix;
-
- // Apply a scaling factor to size the quad from 1x1 to its intended size.
- renderMatrix.scale3d(width, height, 1);
-
- // Apply the projection matrix before sending the transform over to the shader.
- renderMatrix.multiply(m_projectionMatrix);
-
- toGLMatrix(&glMatrix[0], renderMatrix);
-
- glUniformMatrix4fv(m_matrixLocation, 1, false, &glMatrix[0]);
-
- if (m_alphaLocation != -1)
- glUniform1f(m_alphaLocation, opacity);
-
- glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, 0);
-}
-
-
// Updates the contents of the root layer texture that fall inside the updateRect
// and re-composits all sublayers.
void LayerRendererChromium::drawLayers(const IntRect& updateRect, const IntRect& visibleRect,
@@ -315,17 +160,13 @@ void LayerRendererChromium::drawLayers(const IntRect& updateRect, const IntRect&
if (!m_rootLayer)
return;
- // If the size of the visible area has changed then allocate a new texture
- // to store the contents of the root layer and adjust the projection matrix
- // and viewport.
makeContextCurrent();
- checkGLError();
-
- glBindTexture(GL_TEXTURE_2D, m_rootLayerTextureId);
-
- checkGLError();
+ GLC(glBindTexture(GL_TEXTURE_2D, m_rootLayerTextureId));
+ // If the size of the visible area has changed then allocate a new texture
+ // to store the contents of the root layer and adjust the projection matrix
+ // and viewport.
int visibleRectWidth = visibleRect.width();
int visibleRectHeight = visibleRect.height();
if (visibleRectWidth != m_rootLayerTextureWidth || visibleRectHeight != m_rootLayerTextureHeight) {
@@ -333,38 +174,18 @@ void LayerRendererChromium::drawLayers(const IntRect& updateRect, const IntRect&
m_rootLayerTextureHeight = visibleRect.height();
m_projectionMatrix = orthoMatrix(0, visibleRectWidth, visibleRectHeight, 0, -1000, 1000);
- glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, m_rootLayerTextureWidth, m_rootLayerTextureHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0);
-
- checkGLError();
+ GLC(glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, m_rootLayerTextureWidth, m_rootLayerTextureHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0));
}
// The GL viewport covers the entire visible area, including the scrollbars.
- glViewport(0, 0, visibleRectWidth, visibleRectHeight);
-
- checkGLError();
-
- // The layer, scroll and debug border shaders all use the same vertex attributes
- // so we can bind them only once.
- glBindBuffer(GL_ARRAY_BUFFER, m_quadVboIds[Vertices]);
- checkGLError();
- glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_quadVboIds[LayerElements]);
- checkGLError();
- GLuint offset = 0;
- glVertexAttribPointer(m_positionLocation, 3, GL_FLOAT, GL_FALSE, 5 * sizeof(GLfloat), (GLvoid*)(offset));
- checkGLError();
- offset += 3 * sizeof(GLfloat);
- glVertexAttribPointer(m_texCoordLocation, 2, GL_FLOAT, GL_FALSE, 5 * sizeof(GLfloat), (GLvoid*)(offset));
- checkGLError();
- glEnableVertexAttribArray(m_positionLocation);
- checkGLError();
- glEnableVertexAttribArray(m_texCoordLocation);
- checkGLError();
- glActiveTexture(GL_TEXTURE0);
- checkGLError();
- glDisable(GL_DEPTH_TEST);
- checkGLError();
- glDisable(GL_CULL_FACE);
- checkGLError();
+ GLC(glViewport(0, 0, visibleRectWidth, visibleRectHeight));
+
+ // Bind the common vertex attributes used for drawing all the layers.
+ LayerChromium::prepareForDraw(layerSharedValues());
+
+ GLC(glDisable(GL_DEPTH_TEST));
+ GLC(glDisable(GL_CULL_FACE));
+ GLC(glDepthFunc(GL_LEQUAL));
if (m_scrollPosition == IntPoint(-1, -1))
m_scrollPosition = scrollPosition;
@@ -390,21 +211,21 @@ void LayerRendererChromium::drawLayers(const IntRect& updateRect, const IntRect&
#error "Need to implement for your platform."
#endif
- scrolledLayerMatrix.translate3d((int)floorf(0.5 * visibleRect.width()) - scrollDelta.x(),
- (int)floorf(0.5 * visibleRect.height()) + scaleFactor * scrollDelta.y(), 0);
+ scrolledLayerMatrix.translate3d(0.5 * visibleRect.width() - scrollDelta.x(),
+ 0.5 * visibleRect.height() + scaleFactor * scrollDelta.y(), 0);
scrolledLayerMatrix.scale3d(1, -1, 1);
- // Switch shaders to avoid RGB swizzling.
- useShaderProgram(ScrollLayerProgram);
- glUniform1i(m_shaderPrograms[ScrollLayerProgram].m_samplerLocation, 0);
- checkGLError();
-
- drawTexturedQuad(scrolledLayerMatrix, visibleRect.width(), visibleRect.height(), 1);
- checkGLError();
+ useShader(m_scrollShaderProgram);
+ GLC(glUniform1i(m_scrollShaderSamplerLocation, 0));
+ LayerChromium::drawTexturedQuad(m_projectionMatrix, scrolledLayerMatrix,
+ visibleRect.width(), visibleRect.height(), 1,
+ m_scrollShaderMatrixLocation, -1);
- glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, contentRect.width(), contentRect.height());
-
- checkGLError();
+ GLC(glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, contentRect.width(), contentRect.height()));
+ m_scrollPosition = scrollPosition;
+ } else if (abs(scrollDelta.y()) > contentRect.height() || abs(scrollDelta.x()) > contentRect.width()) {
+ // Scrolling larger than the contentRect size does not preserve any of the pixels, so there is
+ // no need to copy framebuffer pixels back into the texture.
m_scrollPosition = scrollPosition;
}
@@ -423,154 +244,92 @@ void LayerRendererChromium::drawLayers(const IntRect& updateRect, const IntRect&
ASSERT(rootLayerWidth == updateRect.width() && rootLayerHeight == updateRect.height());
void* pixels = bitmap.getPixels();
- checkGLError();
// Copy the contents of the updated rect to the root layer texture.
- glTexSubImage2D(GL_TEXTURE_2D, 0, updateRect.x(), updateRect.y(), updateRect.width(), updateRect.height(), GL_RGBA, GL_UNSIGNED_BYTE, pixels);
- checkGLError();
+ GLC(glTexSubImage2D(GL_TEXTURE_2D, 0, updateRect.x(), updateRect.y(), updateRect.width(), updateRect.height(), GL_RGBA, GL_UNSIGNED_BYTE, pixels));
#elif PLATFORM(CG)
// Get the contents of the updated rect.
ASSERT(static_cast<int>(CGBitmapContextGetWidth(m_rootLayerCGContext.get())) == updateRect.width() && static_cast<int>(CGBitmapContextGetHeight(m_rootLayerCGContext.get())) == updateRect.height());
void* pixels = m_rootLayerBackingStore.data();
- checkGLError();
// Copy the contents of the updated rect to the root layer texture.
// The origin is at the lower left in Core Graphics' coordinate system. We need to correct for this here.
- glTexSubImage2D(GL_TEXTURE_2D, 0,
- updateRect.x(), m_rootLayerTextureHeight - updateRect.y() - updateRect.height(),
- updateRect.width(), updateRect.height(),
- GL_RGBA, GL_UNSIGNED_BYTE, pixels);
- checkGLError();
+ GLC(glTexSubImage2D(GL_TEXTURE_2D, 0,
+ updateRect.x(), m_rootLayerTextureHeight - updateRect.y() - updateRect.height(),
+ updateRect.width(), updateRect.height(),
+ GL_RGBA, GL_UNSIGNED_BYTE, pixels));
#else
#error "Need to implement for your platform."
#endif
}
glClearColor(0, 0, 1, 1);
- checkGLError();
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
- checkGLError();
// Render the root layer using a quad that takes up the entire visible area of the window.
- useShaderProgram(ContentLayerProgram);
- checkGLError();
- glUniform1i(m_samplerLocation, 0);
- checkGLError();
+ // We reuse the shader program used by ContentLayerChromium.
+ const ContentLayerChromium::SharedValues* contentLayerValues = contentLayerSharedValues();
+ useShader(contentLayerValues->contentShaderProgram());
+ GLC(glUniform1i(contentLayerValues->shaderSamplerLocation(), 0));
TransformationMatrix layerMatrix;
layerMatrix.translate3d(visibleRect.width() * 0.5f, visibleRect.height() * 0.5f, 0);
- drawTexturedQuad(layerMatrix, visibleRect.width(), visibleRect.height(), 1);
- checkGLError();
+ LayerChromium::drawTexturedQuad(m_projectionMatrix, layerMatrix,
+ visibleRect.width(), visibleRect.height(), 1,
+ contentLayerValues->shaderMatrixLocation(), contentLayerValues->shaderAlphaLocation());
// If culling is enabled then we will cull the backface.
- glCullFace(GL_BACK);
- checkGLError();
+ GLC(glCullFace(GL_BACK));
// The orthographic projection is setup such that Y starts at zero and
// increases going down the page so we need to adjust the winding order of
// front facing triangles.
- glFrontFace(GL_CW);
- checkGLError();
+ GLC(glFrontFace(GL_CW));
// The shader used to render layers returns pre-multiplied alpha colors
// so we need to send the blending mode appropriately.
- glEnable(GL_BLEND);
- checkGLError();
- glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
-
- checkGLError();
+ GLC(glEnable(GL_BLEND));
+ GLC(glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA));
// Translate all the composited layers by the scroll position.
TransformationMatrix matrix;
matrix.translate3d(-m_scrollPosition.x(), -m_scrollPosition.y(), 0);
+ // Traverse the layer tree and update the layer transforms.
float opacity = 1;
- m_layerList.shrink(0);
const Vector<RefPtr<LayerChromium> >& sublayers = m_rootLayer->getSublayers();
- for (size_t i = 0; i < sublayers.size(); i++)
- updateLayersRecursive(sublayers[i].get(), matrix, opacity, visibleRect);
-
- // Sort layers by the z coordinate of their center so that layers further
- // away get drawn first.
- std::stable_sort(m_layerList.begin(), m_layerList.end(), compareLayerZ);
+ size_t i;
+ for (i = 0; i < sublayers.size(); i++)
+ updateLayersRecursive(sublayers[i].get(), matrix, opacity);
// Enable scissoring to avoid rendering composited layers over the scrollbars.
- glEnable(GL_SCISSOR_TEST);
- glScissor(0, visibleRect.height() - contentRect.height(), contentRect.width(), contentRect.height());
+ GLC(glEnable(GL_SCISSOR_TEST));
+ GLC(glScissor(0, visibleRect.height() - contentRect.height(), contentRect.width(), contentRect.height()));
- for (size_t j = 0; j < m_layerList.size(); j++)
- drawLayer(m_layerList[j]);
+ // Traverse the layer tree one more time to draw the layers.
+ m_visibleRect = visibleRect;
+ for (i = 0; i < sublayers.size(); i++)
+ drawLayersRecursive(sublayers[i].get());
- glDisable(GL_SCISSOR_TEST);
+ GLC(glDisable(GL_SCISSOR_TEST));
- glFlush();
m_gles2Context->swapBuffers();
m_needsDisplay = false;
}
-// Returns the id of the texture currently associated with the layer or
-// -1 if the id hasn't been registered yet.
-int LayerRendererChromium::getTextureId(LayerChromium* layer)
+// FIXME: This method should eventually be replaced by a proper texture manager.
+unsigned LayerRendererChromium::createLayerTexture()
{
- TextureIdMap::iterator textureId = m_textureIdMap.find(layer);
- if (textureId != m_textureIdMap.end())
- return textureId->second;
-
- return -1;
-}
-
-// Allocates a new texture for the layer and registers it in the textureId map.
-// FIXME: We will need to come up with a more sophisticated allocation strategy here.
-int LayerRendererChromium::assignTextureForLayer(LayerChromium* layer)
-{
- GLuint textureId = createLayerTexture();
-
- // FIXME: Check that textureId is valid
- m_textureIdMap.set(layer, textureId);
-
- layer->setLayerRenderer(this);
-
+ GLuint textureId = 0;
+ GLC(glGenTextures(1, &textureId));
+ GLC(glBindTexture(GL_TEXTURE_2D, textureId));
+ // Do basic linear filtering on resize.
+ GLC(glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR));
+ GLC(glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR));
+ // NPOT textures in GL ES only work when the wrap mode is set to GL_CLAMP_TO_EDGE.
+ GLC(glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE));
+ GLC(glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE));
return textureId;
}
-bool LayerRendererChromium::freeLayerTexture(LayerChromium* layer)
-{
- TextureIdMap::iterator textureId = m_textureIdMap.find(layer);
- if (textureId == m_textureIdMap.end())
- return false;
- // Free up the texture.
- glDeleteTextures(1, &(textureId->second));
- m_textureIdMap.remove(textureId);
- return true;
-}
-
-// Draws a debug border around the layer's bounds.
-void LayerRendererChromium::drawDebugBorder(LayerChromium* layer, const TransformationMatrix& matrix)
-{
- static GLfloat glMatrix[16];
- Color borderColor = layer->borderColor();
- if (!borderColor.alpha())
- return;
-
- useShaderProgram(DebugBorderProgram);
- TransformationMatrix renderMatrix = matrix;
- IntSize bounds = layer->bounds();
- renderMatrix.scale3d(bounds.width(), bounds.height(), 1);
- renderMatrix.multiply(m_projectionMatrix);
- toGLMatrix(&glMatrix[0], renderMatrix);
- unsigned borderMatrixLocation = m_shaderPrograms[DebugBorderProgram].m_matrixLocation;
- glUniformMatrix4fv(borderMatrixLocation, 1, false, &glMatrix[0]);
-
- glUniform4f(m_borderColorLocation, borderColor.red() / 255.0,
- borderColor.green() / 255.0,
- borderColor.blue() / 255.0,
- 1);
-
- glLineWidth(layer->borderWidth());
-
- // The indices for the line are stored in the same array as the triangle indices.
- glDrawElements(GL_LINE_LOOP, 4, GL_UNSIGNED_SHORT, (void*)(6 * sizeof(unsigned short)));
- checkGLError();
-}
-
// Returns true if any part of the layer falls within the visibleRect
bool LayerRendererChromium::isLayerVisible(LayerChromium* layer, const TransformationMatrix& matrix, const IntRect& visibleRect)
{
@@ -588,9 +347,9 @@ bool LayerRendererChromium::isLayerVisible(LayerChromium* layer, const Transform
return mappedRect.intersects(FloatRect(-1, -1, 2, 2));
}
-// Updates and caches the layer transforms and opacity values that will be used
-// when rendering them.
-void LayerRendererChromium::updateLayersRecursive(LayerChromium* layer, const TransformationMatrix& parentMatrix, float opacity, const IntRect& visibleRect)
+// Recursively walks the layer tree starting at the given node and updates the
+// transform and opacity values.
+void LayerRendererChromium::updateLayersRecursive(LayerChromium* layer, const TransformationMatrix& parentMatrix, float opacity)
{
// Compute the new matrix transformation that will be applied to this layer and
// all its sublayers. It's important to remember that the layer's position
@@ -627,23 +386,11 @@ void LayerRendererChromium::updateLayersRecursive(LayerChromium* layer, const Tr
// M = M[p] * Tr[l] * M[l] * Tr[c]
localMatrix.translate3d(centerOffsetX, centerOffsetY, -layer->anchorPointZ());
- // Check if the layer falls within the visible bounds of the page.
- bool layerVisible = isLayerVisible(layer, localMatrix, visibleRect);
-
- bool skipLayer = false;
- if (bounds.width() > 2048 || bounds.height() > 2048) {
- if (layer->drawsContent())
- LOG(LayerRenderer, "Skipping layer with size %d %d", bounds.width(), bounds.height());
- skipLayer = true;
- }
-
// Calculate the layer's opacity.
opacity *= layer->opacity();
layer->setDrawTransform(localMatrix);
layer->setDrawOpacity(opacity);
- if (layerVisible && !skipLayer)
- m_layerList.append(layer);
// Flatten to 2D if the layer doesn't preserve 3D.
if (!layer->preserves3D()) {
@@ -667,29 +414,71 @@ void LayerRendererChromium::updateLayersRecursive(LayerChromium* layer, const Tr
const Vector<RefPtr<LayerChromium> >& sublayers = layer->getSublayers();
for (size_t i = 0; i < sublayers.size(); i++)
- updateLayersRecursive(sublayers[i].get(), localMatrix, opacity, visibleRect);
+ updateLayersRecursive(sublayers[i].get(), localMatrix, opacity);
+
+ layer->setLayerRenderer(this);
+}
+
+// Recursively walk the layer tree and draw the layers.
+void LayerRendererChromium::drawLayersRecursive(LayerChromium* layer)
+{
+ static bool depthTestEnabledForSubtree = false;
+
+ // Check if the layer falls within the visible bounds of the page.
+ bool layerVisible = isLayerVisible(layer, layer->drawTransform(), m_visibleRect);
+
+ // Enable depth testing for this layer and all its descendants if preserves3D is set.
+ bool mustClearDepth = false;
+ if (layer->preserves3D()) {
+ if (!depthTestEnabledForSubtree) {
+ GLC(glEnable(GL_DEPTH_TEST));
+ depthTestEnabledForSubtree = true;
+
+ // Need to clear the depth buffer when we're done rendering this subtree.
+ mustClearDepth = true;
+ }
+ }
+
+ if (layerVisible)
+ drawLayer(layer);
+
+ // If we're using depth testing then we need to sort the children in Z to
+ // get the transparency to work properly.
+ if (depthTestEnabledForSubtree) {
+ const Vector<RefPtr<LayerChromium> >& sublayers = layer->getSublayers();
+ Vector<LayerChromium*> sublayerList;
+ size_t i;
+ for (i = 0; i < sublayers.size(); i++)
+ sublayerList.append(sublayers[i].get());
+
+ // Sort by the z coordinate of the layer center so that layers further away
+ // are drawn first.
+ std::stable_sort(sublayerList.begin(), sublayerList.end(), compareLayerZ);
+
+ for (i = 0; i < sublayerList.size(); i++)
+ drawLayersRecursive(sublayerList[i]);
+ } else {
+ const Vector<RefPtr<LayerChromium> >& sublayers = layer->getSublayers();
+ for (size_t i = 0; i < sublayers.size(); i++)
+ drawLayersRecursive(sublayers[i].get());
+ }
+
+ if (mustClearDepth) {
+ GLC(glDisable(GL_DEPTH_TEST));
+ GLC(glClear(GL_DEPTH_BUFFER_BIT));
+ depthTestEnabledForSubtree = false;
+ }
}
void LayerRendererChromium::drawLayer(LayerChromium* layer)
{
- const TransformationMatrix& localMatrix = layer->drawTransform();
IntSize bounds = layer->bounds();
if (layer->drawsContent()) {
- int textureId;
- if (layer->ownsTexture())
- textureId = layer->textureId();
- else {
- textureId = getTextureId(layer);
- // If no texture has been created for the layer yet then create one now.
- if (textureId == -1)
- textureId = assignTextureForLayer(layer);
- }
-
- // Redraw the contents of the layer if necessary.
+ // Update the contents of the layer if necessary.
if (layer->contentsDirty()) {
// Update the backing texture contents for any dirty portion of the layer.
- layer->updateTextureContents(textureId);
+ layer->updateContents();
m_gles2Context->makeCurrent();
}
@@ -698,13 +487,11 @@ void LayerRendererChromium::drawLayer(LayerChromium* layer)
else
glEnable(GL_CULL_FACE);
- glBindTexture(GL_TEXTURE_2D, textureId);
- useShaderProgram(static_cast<ShaderProgramType>(layer->shaderProgramId()));
- drawTexturedQuad(localMatrix, bounds.width(), bounds.height(), layer->drawOpacity());
+ layer->draw();
}
// Draw the debug border if there is one.
- drawDebugBorder(layer, localMatrix);
+ layer->drawDebugBorder();
}
bool LayerRendererChromium::makeContextCurrent()
@@ -712,21 +499,22 @@ bool LayerRendererChromium::makeContextCurrent()
return m_gles2Context->makeCurrent();
}
-void LayerRendererChromium::bindCommonAttribLocations(ShaderProgramType program)
+// Checks whether a given size is within the maximum allowed texture size range.
+bool LayerRendererChromium::checkTextureSize(const IntSize& textureSize)
{
- unsigned programId = m_shaderPrograms[program].m_shaderProgramId;
- glBindAttribLocation(programId, m_positionLocation, "a_position");
- glBindAttribLocation(programId, m_texCoordLocation, "a_texCoord");
-
- // Re-link the program for the new attribute locations to take effect.
- glLinkProgram(programId);
- checkGLError();
+ if (textureSize.width() > m_maxTextureSize || textureSize.height() > m_maxTextureSize)
+ return false;
+ return true;
}
-bool LayerRendererChromium::initializeSharedGLObjects()
+bool LayerRendererChromium::initializeSharedObjects()
{
- // Shaders for drawing the layer contents.
- char vertexShaderString[] =
+ makeContextCurrent();
+
+ // Vertex and fragment shaders for rendering the scrolled root layer quad.
+ // They differ from a regular content layer shader in that they don't swizzle
+ // the colors or take an alpha value.
+ char scrollVertexShaderString[] =
"attribute vec4 a_position; \n"
"attribute vec2 a_texCoord; \n"
"uniform mat4 matrix; \n"
@@ -736,30 +524,6 @@ bool LayerRendererChromium::initializeSharedGLObjects()
" gl_Position = matrix * a_position; \n"
" v_texCoord = a_texCoord; \n"
"} \n";
- // Note differences between Skia and Core Graphics versions:
- // - Skia uses BGRA and origin is upper left
- // - Core Graphics uses RGBA and origin is lower left
- char fragmentShaderString[] =
- "precision mediump float; \n"
- "varying vec2 v_texCoord; \n"
- "uniform sampler2D s_texture; \n"
- "uniform float alpha; \n"
- "void main() \n"
- "{ \n"
-#if PLATFORM(SKIA)
- " vec4 texColor = texture2D(s_texture, v_texCoord); \n"
- " gl_FragColor = vec4(texColor.z, texColor.y, texColor.x, texColor.w) * alpha; \n"
-#elif PLATFORM(CG)
- " vec4 texColor = texture2D(s_texture, vec2(v_texCoord.x, 1.0 - v_texCoord.y)); \n"
- " gl_FragColor = vec4(texColor.x, texColor.y, texColor.z, texColor.w) * alpha; \n"
-#else
-#error "Need to implement for your platform."
-#endif
- "} \n";
-
- // Fragment shader used for rendering the scrolled root layer quad. It differs
- // from fragmentShaderString in that it doesn't swizzle the colors and doesn't
- // take an alpha value.
char scrollFragmentShaderString[] =
"precision mediump float; \n"
"varying vec2 v_texCoord; \n"
@@ -770,101 +534,67 @@ bool LayerRendererChromium::initializeSharedGLObjects()
" gl_FragColor = vec4(texColor.x, texColor.y, texColor.z, texColor.w); \n"
"} \n";
- // Canvas layers need to be flipped vertically and their colors shouldn't be
- // swizzled.
- char canvasFragmentShaderString[] =
- "precision mediump float; \n"
- "varying vec2 v_texCoord; \n"
- "uniform sampler2D s_texture; \n"
- "uniform float alpha; \n"
- "void main() \n"
- "{ \n"
- " vec4 texColor = texture2D(s_texture, vec2(v_texCoord.x, 1.0 - v_texCoord.y)); \n"
- " gl_FragColor = vec4(texColor.x, texColor.y, texColor.z, texColor.w) * alpha; \n"
- "} \n";
-
- // Shaders for drawing the debug borders around the layers.
- char borderVertexShaderString[] =
- "attribute vec4 a_position; \n"
- "uniform mat4 matrix; \n"
- "void main() \n"
- "{ \n"
- " gl_Position = matrix * a_position; \n"
- "} \n";
- char borderFragmentShaderString[] =
- "precision mediump float; \n"
- "uniform vec4 color; \n"
- "void main() \n"
- "{ \n"
- " gl_FragColor = color; \n"
- "} \n";
-
- GLfloat vertices[] = { -0.5f, 0.5f, 0.0f, // Position 0
- 0.0f, 1.0f, // TexCoord 0
- -0.5f, -0.5f, 0.0f, // Position 1
- 0.0f, 0.0f, // TexCoord 1
- 0.5f, -0.5f, 0.0f, // Position 2
- 1.0f, 0.0f, // TexCoord 2
- 0.5f, 0.5f, 0.0f, // Position 3
- 1.0f, 1.0f // TexCoord 3
- };
- GLushort indices[] = { 0, 1, 2, 0, 2, 3, // The two triangles that make up the layer quad.
- 0, 1, 2, 3}; // A line path for drawing the layer border.
-
- makeContextCurrent();
-
- if (!createLayerShader(ContentLayerProgram, vertexShaderString, fragmentShaderString)) {
- LOG_ERROR("Failed to create shader program for content layers");
- return false;
- }
- LayerChromium::setShaderProgramId(ContentLayerProgram);
-
- if (!createLayerShader(CanvasLayerProgram, vertexShaderString, canvasFragmentShaderString)) {
- LOG_ERROR("Failed to create shader program for Canvas layers");
+ m_scrollShaderProgram = LayerChromium::createShaderProgram(scrollVertexShaderString, scrollFragmentShaderString);
+ if (!m_scrollShaderProgram) {
+ LOG_ERROR("LayerRendererChromium: Failed to create scroll shader program");
+ cleanupSharedObjects();
return false;
}
- CanvasLayerChromium::setShaderProgramId(CanvasLayerProgram);
- if (!createLayerShader(ScrollLayerProgram, vertexShaderString, scrollFragmentShaderString)) {
- LOG_ERROR("Failed to create shader program for scrolling layer");
+ GLC(m_scrollShaderSamplerLocation = glGetUniformLocation(m_scrollShaderProgram, "s_texture"));
+ GLC(m_scrollShaderMatrixLocation = glGetUniformLocation(m_scrollShaderProgram, "matrix"));
+ if (m_scrollShaderSamplerLocation == -1 || m_scrollShaderMatrixLocation == -1) {
+ LOG_ERROR("Failed to initialize scroll shader.");
+ cleanupSharedObjects();
return false;
}
- if (!createLayerShader(DebugBorderProgram, borderVertexShaderString, borderFragmentShaderString)) {
- LOG_ERROR("Failed to create shader program for debug borders");
- return false;
- }
-
- // Specify the attrib location for the position and texCoord and make it the same for all programs to
- // avoid binding re-binding the vertex attributes.
- bindCommonAttribLocations(ContentLayerProgram);
- bindCommonAttribLocations(CanvasLayerProgram);
- bindCommonAttribLocations(DebugBorderProgram);
- bindCommonAttribLocations(ScrollLayerProgram);
-
- // Get the location of the color uniform for the debug border shader program.
- m_borderColorLocation = glGetUniformLocation(m_shaderPrograms[DebugBorderProgram].m_shaderProgramId, "color");
-
- glGenBuffers(3, m_quadVboIds);
- glBindBuffer(GL_ARRAY_BUFFER, m_quadVboIds[Vertices]);
- glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
- glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_quadVboIds[LayerElements]);
- glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW);
-
// Create a texture object to hold the contents of the root layer.
m_rootLayerTextureId = createLayerTexture();
if (!m_rootLayerTextureId) {
LOG_ERROR("Failed to create texture for root layer");
+ cleanupSharedObjects();
return false;
}
// Turn off filtering for the root layer to avoid blurring from the repeated
// writes and reads to the framebuffer that happen while scrolling.
- glBindTexture(GL_TEXTURE_2D, m_rootLayerTextureId);
- glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
- glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+ GLC(glBindTexture(GL_TEXTURE_2D, m_rootLayerTextureId));
+ GLC(glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST));
+ GLC(glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST));
+
+ // Get the max texture size supported by the system.
+ GLC(glGetIntegerv(GL_MAX_TEXTURE_SIZE, &m_maxTextureSize));
+
+ m_layerSharedValues = adoptPtr(new LayerChromium::SharedValues());
+ m_contentLayerSharedValues = adoptPtr(new ContentLayerChromium::SharedValues());
+ m_canvasLayerSharedValues = adoptPtr(new CanvasLayerChromium::SharedValues());
+ if (!m_layerSharedValues->initialized() || !m_contentLayerSharedValues->initialized() || !m_canvasLayerSharedValues->initialized()) {
+ cleanupSharedObjects();
+ return false;
+ }
return true;
}
+
+void LayerRendererChromium::cleanupSharedObjects()
+{
+ makeContextCurrent();
+
+ m_layerSharedValues.clear();
+ m_contentLayerSharedValues.clear();
+ m_canvasLayerSharedValues.clear();
+
+ if (m_scrollShaderProgram) {
+ GLC(glDeleteProgram(m_scrollShaderProgram));
+ m_scrollShaderProgram = 0;
+ }
+
+ if (m_rootLayerTextureId) {
+ GLC(glDeleteTextures(1, &m_rootLayerTextureId));
+ m_rootLayerTextureId = 0;
+ }
+}
+
} // namespace WebCore
#endif // USE(ACCELERATED_COMPOSITING)
diff --git a/WebCore/platform/graphics/chromium/LayerRendererChromium.h b/WebCore/platform/graphics/chromium/LayerRendererChromium.h
index e4474b5..24bbe65 100644
--- a/WebCore/platform/graphics/chromium/LayerRendererChromium.h
+++ b/WebCore/platform/graphics/chromium/LayerRendererChromium.h
@@ -34,6 +34,8 @@
#if USE(ACCELERATED_COMPOSITING)
+#include "CanvasLayerChromium.h"
+#include "ContentLayerChromium.h"
#include "IntRect.h"
#include "LayerChromium.h"
#include "SkBitmap.h"
@@ -51,16 +53,6 @@ namespace WebCore {
class GLES2Context;
-class ShaderProgram {
-public:
- ShaderProgram();
-
- unsigned m_shaderProgramId;
- int m_samplerLocation;
- int m_matrixLocation;
- int m_alphaLocation;
-};
-
// Class that handles drawing of composited render layers using GL.
class LayerRendererChromium : public Noncopyable {
public:
@@ -78,73 +70,58 @@ public:
void setNeedsDisplay() { m_needsDisplay = true; }
- // Frees the texture associated with the given layer.
- bool freeLayerTexture(LayerChromium*);
-
bool hardwareCompositing() const { return m_hardwareCompositing; }
void setRootLayerCanvasSize(const IntSize&);
GraphicsContext* rootLayerGraphicsContext() const { return m_rootLayerGraphicsContext.get(); }
-private:
- enum ShaderProgramType { DebugBorderProgram, ScrollLayerProgram, ContentLayerProgram, CanvasLayerProgram, NumShaderProgramTypes };
+ unsigned createLayerTexture();
- void updateLayersRecursive(LayerChromium* layer, const TransformationMatrix& parentMatrix, float opacity, const IntRect& visibleRect);
+ static void debugGLCall(const char* command, const char* file, int line);
- void drawLayer(LayerChromium*);
+ const TransformationMatrix& projectionMatrix() const { return m_projectionMatrix; }
- void drawDebugBorder(LayerChromium*, const TransformationMatrix&);
+ void useShader(unsigned);
- void drawTexturedQuad(const TransformationMatrix& matrix, float width, float height, float opacity);
+ bool checkTextureSize(const IntSize&);
- bool isLayerVisible(LayerChromium*, const TransformationMatrix&, const IntRect& visibleRect);
+ const LayerChromium::SharedValues* layerSharedValues() const { return m_layerSharedValues.get(); }
+ const ContentLayerChromium::SharedValues* contentLayerSharedValues() const { return m_contentLayerSharedValues.get(); }
+ const CanvasLayerChromium::SharedValues* canvasLayerSharedValues() const { return m_canvasLayerSharedValues.get(); }
- bool createLayerShader(ShaderProgramType, const char* vertexShaderSource, const char* fragmentShaderSource);
+private:
+ void updateLayersRecursive(LayerChromium* layer, const TransformationMatrix& parentMatrix, float opacity);
- void useShaderProgram(ShaderProgramType);
+ void drawLayersRecursive(LayerChromium*);
- void bindCommonAttribLocations(ShaderProgramType);
+ void drawLayer(LayerChromium*);
- enum VboIds { Vertices, LayerElements };
+ bool isLayerVisible(LayerChromium*, const TransformationMatrix&, const IntRect& visibleRect);
- // These are here only temporarily and should be removed once we switch over to GGL
bool makeContextCurrent();
- bool initializeSharedGLObjects();
- int getTextureId(LayerChromium*);
- int assignTextureForLayer(LayerChromium*);
-
- ShaderProgram m_shaderPrograms[NumShaderProgramTypes];
+ bool initializeSharedObjects();
+ void cleanupSharedObjects();
unsigned m_rootLayerTextureId;
int m_rootLayerTextureWidth;
int m_rootLayerTextureHeight;
- // Shader uniform and attribute locations.
- const int m_positionLocation;
- const int m_texCoordLocation;
- int m_samplerLocation;
- int m_matrixLocation;
- int m_alphaLocation;
- int m_borderColorLocation;
+ // Scroll shader uniform locations.
+ unsigned m_scrollShaderProgram;
+ int m_scrollShaderSamplerLocation;
+ int m_scrollShaderMatrixLocation;
- unsigned m_quadVboIds[3];
TransformationMatrix m_projectionMatrix;
RefPtr<LayerChromium> m_rootLayer;
- Vector<LayerChromium*> m_layerList;
-
bool m_needsDisplay;
IntPoint m_scrollPosition;
bool m_hardwareCompositing;
- ShaderProgramType m_currentShaderProgramType;
-
- // Map associating layers with textures ids used by the GL compositor.
- typedef HashMap<LayerChromium*, unsigned> TextureIdMap;
- TextureIdMap m_textureIdMap;
+ unsigned int m_currentShader;
#if PLATFORM(SKIA)
OwnPtr<skia::PlatformCanvas> m_rootLayerCanvas;
@@ -158,9 +135,33 @@ private:
IntSize m_rootLayerCanvasSize;
+ IntRect m_visibleRect;
+
+ int m_maxTextureSize;
+
+ // Store values that are shared between instances of each layer type
+ // associated with this instance of the compositor. Since there can be
+ // multiple instances of the compositor running in the same renderer process
+ // we cannot store these values in static variables.
+ OwnPtr<LayerChromium::SharedValues> m_layerSharedValues;
+ OwnPtr<ContentLayerChromium::SharedValues> m_contentLayerSharedValues;
+ OwnPtr<CanvasLayerChromium::SharedValues> m_canvasLayerSharedValues;
+
OwnPtr<GLES2Context> m_gles2Context;
};
+// Setting DEBUG_GL_CALLS to 1 will call glGetError() after almost every GL
+// call made by the compositor. Useful for debugging rendering issues but
+// will significantly degrade performance.
+#define DEBUG_GL_CALLS 0
+
+#if DEBUG_GL_CALLS && !defined ( NDEBUG )
+#define GLC(x) { (x), LayerRendererChromium::debugGLCall(#x, __FILE__, __LINE__); }
+#else
+#define GLC(x) (x)
+#endif
+
+
}
#endif // USE(ACCELERATED_COMPOSITING)
diff --git a/WebCore/platform/graphics/chromium/TilingData.cpp b/WebCore/platform/graphics/chromium/TilingData.cpp
index c52288d..4da242b 100755
--- a/WebCore/platform/graphics/chromium/TilingData.cpp
+++ b/WebCore/platform/graphics/chromium/TilingData.cpp
@@ -117,18 +117,22 @@ int TilingData::tilePositionX(int xIndex) const
{
ASSERT(xIndex >= 0 && xIndex < numTilesX());
- if (!xIndex)
- return 0;
- return tilePositionX(xIndex - 1) + tileSizeX(xIndex - 1);
+ int pos = 0;
+ for (int i = 0; i < xIndex; i++)
+ pos += tileSizeX(i);
+
+ return pos;
}
int TilingData::tilePositionY(int yIndex) const
{
ASSERT(yIndex >= 0 && yIndex < numTilesY());
- if (!yIndex)
- return 0;
- return tilePositionX(yIndex - 1) + tileSizeY(yIndex - 1);
+ int pos = 0;
+ for (int i = 0; i < yIndex; i++)
+ pos += tileSizeY(i);
+
+ return pos;
}
int TilingData::tileSizeX(int xIndex) const
diff --git a/WebCore/platform/graphics/chromium/VideoFrameChromium.h b/WebCore/platform/graphics/chromium/VideoFrameChromium.h
new file mode 100644
index 0000000..bbd677e
--- /dev/null
+++ b/WebCore/platform/graphics/chromium/VideoFrameChromium.h
@@ -0,0 +1,81 @@
+/*
+ * Copyright (C) 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 VideoFrameChromium_h
+#define VideoFrameChromium_h
+
+namespace WebCore {
+
+// A class that represents a video frame in chromium.
+class VideoFrameChromium {
+public:
+ static const unsigned cMaxPlanes;
+ static const unsigned cNumRGBPlanes;
+ static const unsigned cRGBPlane;
+ static const unsigned cNumYUVPlanes;
+ static const unsigned cYPlane;
+ static const unsigned cUPlane;
+ static const unsigned cVPlane;
+
+ // These enums must be kept in sync with WebKit::WebVideoFrame.
+ enum Format {
+ Invalid,
+ RGB555,
+ RGB565,
+ RGB24,
+ RGB32,
+ RGBA,
+ YV12,
+ YV16,
+ NV12,
+ Empty,
+ ASCII,
+ };
+
+ enum SurfaceType {
+ TypeSystemMemory,
+ TypeOMXBufferHead,
+ TypeEGLImage,
+ TypeMFBuffer,
+ TypeDirect3DSurface
+ };
+
+ virtual SurfaceType surfaceType() const = 0;
+ virtual Format format() const = 0;
+ virtual unsigned width() const = 0;
+ virtual unsigned height() const = 0;
+ virtual unsigned planes() const = 0;
+ virtual int stride(unsigned plane) const = 0;
+ virtual const void* data(unsigned plane) const = 0;
+};
+
+} // namespace WebCore
+
+#endif
diff --git a/WebCore/platform/graphics/chromium/TransformLayerChromium.h b/WebCore/platform/graphics/chromium/VideoFrameProvider.h
index 3d5ce94..f0bad08 100644
--- a/WebCore/platform/graphics/chromium/TransformLayerChromium.h
+++ b/WebCore/platform/graphics/chromium/VideoFrameProvider.h
@@ -28,28 +28,28 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
+#ifndef VideoFrameProvider_h
+#define VideoFrameProvider_h
-#ifndef TransformLayerChromium_h
-#define TransformLayerChromium_h
-
-#if USE(ACCELERATED_COMPOSITING)
-
-#include "LayerChromium.h"
+#include "VideoFrameChromium.h"
namespace WebCore {
-// A Layer that doesn't draw any content but simply exists to group and
-// transform its descendants.
-class TransformLayerChromium : public LayerChromium {
+class VideoFrameProvider {
public:
- static PassRefPtr<TransformLayerChromium> create(GraphicsLayerChromium* owner = 0);
- virtual bool drawsContent() { return false; }
-
-private:
- TransformLayerChromium(GraphicsLayerChromium* owner);
+ // This function returns a pointer to a VideoFrameChromium, which is
+ // the WebCore wrapper for a video frame in Chromium. getCurrentFrame()
+ // places a lock on the frame in Chromium. Calls to this method should
+ // always be followed with a call to putCurrentFrame().
+ // The ownership of the object is not transferred to the caller and
+ // the caller should not free the returned object.
+ virtual VideoFrameChromium* getCurrentFrame() = 0;
+ // This function releases the lock on the video frame in chromium. It should
+ // always be called after getCurrentFrame(). Frames passed into this method
+ // should no longer be referenced after the call is made.
+ virtual void putCurrentFrame(VideoFrameChromium*) = 0;
};
-}
-#endif // USE(ACCELERATED_COMPOSITING)
+} // namespace WebCore
#endif
diff --git a/WebCore/platform/graphics/chromium/VideoLayerChromium.cpp b/WebCore/platform/graphics/chromium/VideoLayerChromium.cpp
index 89b6ec1..7ff98b9 100644
--- a/WebCore/platform/graphics/chromium/VideoLayerChromium.cpp
+++ b/WebCore/platform/graphics/chromium/VideoLayerChromium.cpp
@@ -48,23 +48,24 @@
namespace WebCore {
-PassRefPtr<VideoLayerChromium> VideoLayerChromium::create(GraphicsLayerChromium* owner)
+PassRefPtr<VideoLayerChromium> VideoLayerChromium::create(GraphicsLayerChromium* owner,
+ VideoFrameProvider* provider)
{
- return adoptRef(new VideoLayerChromium(owner));
+ return adoptRef(new VideoLayerChromium(owner, provider));
}
-VideoLayerChromium::VideoLayerChromium(GraphicsLayerChromium* owner)
- : LayerChromium(owner)
- , m_allocatedTextureId(0)
+VideoLayerChromium::VideoLayerChromium(GraphicsLayerChromium* owner, VideoFrameProvider* provider)
+ : ContentLayerChromium(owner)
#if PLATFORM(SKIA)
, m_canvas(0)
, m_skiaContext(0)
#endif
, m_graphicsContext(0)
+ , m_provider(provider)
{
}
-void VideoLayerChromium::updateTextureContents(unsigned textureId)
+void VideoLayerChromium::updateContents()
{
RenderLayerBacking* backing = static_cast<RenderLayerBacking*>(m_owner->client());
if (!backing || backing->paintingGoesToWindow())
@@ -109,9 +110,20 @@ void VideoLayerChromium::updateTextureContents(unsigned textureId)
// Bring the canvas into the coordinate system of the paint rect.
m_canvas->translate(static_cast<SkScalar>(-dirtyRect.x()), static_cast<SkScalar>(-dirtyRect.y()));
+ // FIXME: Remove this test when tiled layers are implemented.
+ m_skipsDraw = false;
+ if (!layerRenderer()->checkTextureSize(requiredTextureSize)) {
+ m_skipsDraw = true;
+ return;
+ }
+
+ unsigned textureId = m_contentsTexture;
+ if (!textureId)
+ textureId = layerRenderer()->createLayerTexture();
+
// If the texture id or size changed since last time, then we need to tell GL
// to re-allocate a texture.
- if (m_allocatedTextureId != textureId || requiredTextureSize != m_allocatedTextureSize)
+ if (m_contentsTexture != textureId || requiredTextureSize != m_allocatedTextureSize)
createTextureRect(requiredTextureSize, dirtyRect, textureId);
else
updateTextureRect(dirtyRect, textureId);
@@ -150,7 +162,7 @@ void VideoLayerChromium::createTextureRect(const IntSize& requiredTextureSize, c
ASSERT(bitmapSize == requiredTextureSize);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, requiredTextureSize.width(), requiredTextureSize.height(), 0, GL_RGBA, GL_UNSIGNED_BYTE, pixels);
- m_allocatedTextureId = textureId;
+ m_contentsTexture = textureId;
m_allocatedTextureSize = requiredTextureSize;
updateCompleted();
diff --git a/WebCore/platform/graphics/chromium/VideoLayerChromium.h b/WebCore/platform/graphics/chromium/VideoLayerChromium.h
index 746299f..3507cb2 100644
--- a/WebCore/platform/graphics/chromium/VideoLayerChromium.h
+++ b/WebCore/platform/graphics/chromium/VideoLayerChromium.h
@@ -34,30 +34,31 @@
#if USE(ACCELERATED_COMPOSITING)
-#include "LayerChromium.h"
+#include "ContentLayerChromium.h"
+#include "VideoFrameProvider.h"
namespace WebCore {
// A Layer that contains a Video element.
-class VideoLayerChromium : public LayerChromium {
+class VideoLayerChromium : public ContentLayerChromium {
public:
- static PassRefPtr<VideoLayerChromium> create(GraphicsLayerChromium* owner = 0);
+ static PassRefPtr<VideoLayerChromium> create(GraphicsLayerChromium* owner = 0,
+ VideoFrameProvider* = 0);
virtual bool drawsContent() { return true; }
- virtual void updateTextureContents(unsigned textureId);
+ virtual void updateContents();
private:
- VideoLayerChromium(GraphicsLayerChromium* owner);
+ VideoLayerChromium(GraphicsLayerChromium* owner, VideoFrameProvider*);
void createTextureRect(const IntSize& requiredTextureSize, const IntRect& updateRect, unsigned textureId);
void updateTextureRect(const IntRect& updateRect, unsigned textureId);
void updateCompleted();
- unsigned m_allocatedTextureId;
- IntSize m_allocatedTextureSize;
#if PLATFORM(SKIA)
OwnPtr<skia::PlatformCanvas> m_canvas;
OwnPtr<PlatformContextSkia> m_skiaContext;
#endif
OwnPtr<GraphicsContext> m_graphicsContext;
+ OwnPtr<VideoFrameProvider> m_provider;
};
}
diff --git a/WebCore/platform/graphics/filters/FEComposite.cpp b/WebCore/platform/graphics/filters/FEComposite.cpp
index 0bafc48..d9f00ce 100644
--- a/WebCore/platform/graphics/filters/FEComposite.cpp
+++ b/WebCore/platform/graphics/filters/FEComposite.cpp
@@ -136,7 +136,7 @@ void FEComposite::apply(Filter* filter)
break;
case FECOMPOSITE_OPERATOR_IN:
filterContext->save();
- filterContext->clipToImageBuffer(m_in->resultImage(), calculateDrawingRect(m_in2->scaledSubRegion()));
+ filterContext->clipToImageBuffer(m_in2->resultImage(), calculateDrawingRect(m_in2->scaledSubRegion()));
filterContext->drawImageBuffer(m_in->resultImage(), DeviceColorSpace, calculateDrawingRect(m_in->scaledSubRegion()));
filterContext->restore();
break;
diff --git a/WebCore/platform/graphics/filters/FEGaussianBlur.cpp b/WebCore/platform/graphics/filters/FEGaussianBlur.cpp
index 70465a0..44bb65a 100644
--- a/WebCore/platform/graphics/filters/FEGaussianBlur.cpp
+++ b/WebCore/platform/graphics/filters/FEGaussianBlur.cpp
@@ -200,6 +200,12 @@ TextStream& FEGaussianBlur::externalRepresentation(TextStream& ts, int indent) c
return ts;
}
+float FEGaussianBlur::calculateStdDeviation(float radius)
+{
+ // Blur radius represents 2/3 times the kernel size, the dest pixel is half of the radius applied 3 times
+ return max((radius * 2 / 3.f - 0.5f) / gGaussianKernelFactor, 0.f);
+}
+
} // namespace WebCore
#endif // ENABLE(FILTERS)
diff --git a/WebCore/platform/graphics/filters/FEGaussianBlur.h b/WebCore/platform/graphics/filters/FEGaussianBlur.h
index 4c7c43c..ad5c5a3 100644
--- a/WebCore/platform/graphics/filters/FEGaussianBlur.h
+++ b/WebCore/platform/graphics/filters/FEGaussianBlur.h
@@ -43,6 +43,8 @@ public:
void dump();
TextStream& externalRepresentation(TextStream&, int indent) const;
+ static float calculateStdDeviation(float);
+
private:
FEGaussianBlur(FilterEffect*, const float&, const float&);
static void kernelPosition(int boxBlur, unsigned& std, int& dLeft, int& dRight);
diff --git a/WebCore/platform/graphics/gstreamer/GStreamerGWorld.cpp b/WebCore/platform/graphics/gstreamer/GStreamerGWorld.cpp
index c5022f9..96a639b 100644
--- a/WebCore/platform/graphics/gstreamer/GStreamerGWorld.cpp
+++ b/WebCore/platform/graphics/gstreamer/GStreamerGWorld.cpp
@@ -21,24 +21,178 @@
#include "GStreamerGWorld.h"
-#include "MediaPlayerPrivateGStreamer.h"
+#include "GOwnPtrGStreamer.h"
+
+#include <gst/gst.h>
+#include <gst/interfaces/xoverlay.h>
+
+#if PLATFORM(GTK)
+#include <gtk/gtk.h>
+#ifdef GDK_WINDOWING_X11
+#include <gdk/gdkx.h> // for GDK_WINDOW_XID
+#endif
+#endif
using namespace std;
namespace WebCore {
-PassRefPtr<GStreamerGWorld> GStreamerGWorld::createGWorld(MediaPlayerPrivateGStreamer* player)
+gboolean gstGWorldSyncMessageCallback(GstBus* bus, GstMessage* message, gpointer data)
+{
+ ASSERT(GST_MESSAGE_TYPE(message) == GST_MESSAGE_ELEMENT);
+
+ GStreamerGWorld* gstGWorld = static_cast<GStreamerGWorld*>(data);
+
+ if (gst_structure_has_name(message->structure, "prepare-xwindow-id"))
+ gstGWorld->setWindowOverlay(message);
+ return TRUE;
+}
+
+PassRefPtr<GStreamerGWorld> GStreamerGWorld::createGWorld(GstElement* pipeline)
{
- return adoptRef(new GStreamerGWorld(player));
+ return adoptRef(new GStreamerGWorld(pipeline));
}
-GStreamerGWorld::GStreamerGWorld(MediaPlayerPrivateGStreamer* player)
- : m_player(player)
+GStreamerGWorld::GStreamerGWorld(GstElement* pipeline)
+ : m_pipeline(pipeline)
+ , m_dynamicPadName(0)
{
+ // XOverlay messages need to be handled synchronously.
+ GstBus* bus = gst_pipeline_get_bus(GST_PIPELINE(m_pipeline));
+ gst_bus_set_sync_handler(bus, gst_bus_sync_signal_handler, this);
+ g_signal_connect(bus, "sync-message::element", G_CALLBACK(gstGWorldSyncMessageCallback), this);
+ gst_object_unref(bus);
}
GStreamerGWorld::~GStreamerGWorld()
{
+ exitFullscreen();
+
+ m_pipeline = 0;
+}
+
+bool GStreamerGWorld::enterFullscreen()
+{
+ if (m_dynamicPadName)
+ return false;
+
+ if (!m_videoWindow)
+ m_videoWindow = PlatformVideoWindow::createWindow();
+
+ GstElement* platformVideoSink = gst_element_factory_make("autovideosink", "platformVideoSink");
+ GstElement* colorspace = gst_element_factory_make("ffmpegcolorspace", "colorspace");
+ GstElement* queue = gst_element_factory_make("queue", "queue");
+ GstElement* videoScale = gst_element_factory_make("videoscale", "videoScale");
+
+ // Get video sink bin and the tee inside.
+ GOwnPtr<GstElement> videoSink;
+ g_object_get(m_pipeline, "video-sink", &videoSink.outPtr(), NULL);
+ GstElement* tee = gst_bin_get_by_name(GST_BIN(videoSink.get()), "videoTee");
+
+ // Add and link a queue, ffmpegcolorspace and sink in the bin.
+ gst_bin_add_many(GST_BIN(videoSink.get()), platformVideoSink, videoScale, colorspace, queue, NULL);
+ gst_element_link_many(queue, colorspace, videoScale, platformVideoSink, NULL);
+
+ // Link a new src pad from tee to queue.
+ GstPad* srcPad = gst_element_get_request_pad(tee, "src%d");
+ GstPad* sinkPad = gst_element_get_static_pad(queue, "sink");
+ gst_pad_link(srcPad, sinkPad);
+ gst_object_unref(GST_OBJECT(sinkPad));
+
+ m_dynamicPadName = gst_pad_get_name(srcPad);
+
+ // Roll new elements to pipeline state.
+ gst_element_sync_state_with_parent(queue);
+ gst_element_sync_state_with_parent(colorspace);
+ gst_element_sync_state_with_parent(videoScale);
+ gst_element_sync_state_with_parent(platformVideoSink);
+
+ gst_object_unref(tee);
+
+ // Query the current media segment informations and send them towards
+ // the new tee branch downstream.
+
+ GstQuery* query = gst_query_new_segment(GST_FORMAT_TIME);
+ gboolean queryResult = gst_element_query(m_pipeline, query);
+
+ // See https://bugzilla.gnome.org/show_bug.cgi?id=620490.
+#if GST_CHECK_VERSION(0, 10, 30)
+ if (!queryResult) {
+ gst_query_unref(query);
+ gst_object_unref(GST_OBJECT(srcPad));
+ return true;
+ }
+#endif
+
+ GstFormat format;
+ gint64 position;
+ if (!gst_element_query_position(m_pipeline, &format, &position))
+ position = 0;
+
+ gdouble rate;
+ gint64 startValue, stopValue;
+ gst_query_parse_segment(query, &rate, &format, &startValue, &stopValue);
+
+ GstEvent* event = gst_event_new_new_segment(FALSE, rate, format, startValue, stopValue, position);
+ gst_pad_push_event(srcPad, event);
+
+ gst_query_unref(query);
+ gst_object_unref(GST_OBJECT(srcPad));
+ return true;
+}
+
+void GStreamerGWorld::exitFullscreen()
+{
+ if (!m_dynamicPadName)
+ return;
+
+ // Get video sink bin and the elements to remove.
+ GOwnPtr<GstElement> videoSink;
+ g_object_get(m_pipeline, "video-sink", &videoSink.outPtr(), NULL);
+ GstElement* tee = gst_bin_get_by_name(GST_BIN(videoSink.get()), "videoTee");
+ GstElement* platformVideoSink = gst_bin_get_by_name(GST_BIN(videoSink.get()), "platformVideoSink");
+ GstElement* queue = gst_bin_get_by_name(GST_BIN(videoSink.get()), "queue");
+ GstElement* colorspace = gst_bin_get_by_name(GST_BIN(videoSink.get()), "colorspace");
+ GstElement* videoScale = gst_bin_get_by_name(GST_BIN(videoSink.get()), "videoScale");
+
+ // Get pads to unlink and remove.
+ GstPad* srcPad = gst_element_get_static_pad(tee, m_dynamicPadName);
+ GstPad* sinkPad = gst_element_get_static_pad(queue, "sink");
+
+ // Unlink and release request pad.
+ gst_pad_unlink(srcPad, sinkPad);
+ gst_element_release_request_pad(tee, srcPad);
+ gst_object_unref(GST_OBJECT(srcPad));
+ gst_object_unref(GST_OBJECT(sinkPad));
+
+ // Unlink, remove and cleanup queue, ffmpegcolorspace, videoScale and sink.
+ gst_element_unlink_many(queue, colorspace, videoScale, platformVideoSink, NULL);
+ gst_bin_remove_many(GST_BIN(videoSink.get()), queue, colorspace, videoScale, platformVideoSink, NULL);
+ gst_element_set_state(queue, GST_STATE_NULL);
+ gst_element_set_state(colorspace, GST_STATE_NULL);
+ gst_element_set_state(videoScale, GST_STATE_NULL);
+ gst_element_set_state(platformVideoSink, GST_STATE_NULL);
+ gst_object_unref(queue);
+ gst_object_unref(colorspace);
+ gst_object_unref(videoScale);
+ gst_object_unref(platformVideoSink);
+
+ gst_object_unref(tee);
+ m_dynamicPadName = 0;
+}
+
+void GStreamerGWorld::setWindowOverlay(GstMessage* message)
+{
+ GstObject* sink = GST_MESSAGE_SRC(message);
+
+ if (!GST_IS_X_OVERLAY(sink))
+ return;
+
+ if (g_object_class_find_property(G_OBJECT_GET_CLASS(sink), "force-aspect-ratio"))
+ g_object_set(sink, "force-aspect-ratio", TRUE, NULL);
+
+ if (m_videoWindow)
+ gst_x_overlay_set_xwindow_id(GST_X_OVERLAY(sink), m_videoWindow->videoWindowId());
}
}
diff --git a/WebCore/platform/graphics/gstreamer/GStreamerGWorld.h b/WebCore/platform/graphics/gstreamer/GStreamerGWorld.h
index b626298..659052a 100644
--- a/WebCore/platform/graphics/gstreamer/GStreamerGWorld.h
+++ b/WebCore/platform/graphics/gstreamer/GStreamerGWorld.h
@@ -23,25 +23,43 @@
#if ENABLE(VIDEO)
+#include "PlatformVideoWindow.h"
#include "RefCounted.h"
#include "RefPtr.h"
#include <glib.h>
+typedef struct _GstElement GstElement;
+typedef struct _GstMessage GstMessage;
+typedef struct _GstBus GstBus;
+typedef struct _GstBin GstBin;
namespace WebCore {
class MediaPlayerPrivateGStreamer;
+gboolean gstGWorldSyncMessageCallback(GstBus* bus, GstMessage* message, gpointer data);
class GStreamerGWorld : public RefCounted<GStreamerGWorld> {
+ friend gboolean gstGWorldSyncMessageCallback(GstBus* bus, GstMessage* message, gpointer data);
public:
- static PassRefPtr<GStreamerGWorld> createGWorld(MediaPlayerPrivateGStreamer*);
+ static PassRefPtr<GStreamerGWorld> createGWorld(GstElement*);
~GStreamerGWorld();
+ GstElement* pipeline() const { return m_pipeline; }
+
+ // Returns the full-screen window created
+ bool enterFullscreen();
+ void exitFullscreen();
+
+ void setWindowOverlay(GstMessage* message);
+ PlatformVideoWindow* platformVideoWindow() const { return m_videoWindow.get(); }
+
private:
- GStreamerGWorld(MediaPlayerPrivateGStreamer*);
- MediaPlayerPrivateGStreamer* m_player;
+ GStreamerGWorld(GstElement*);
+ GstElement* m_pipeline;
+ RefPtr<PlatformVideoWindow> m_videoWindow;
+ gchar* m_dynamicPadName;
};
}
diff --git a/WebCore/platform/graphics/gstreamer/MediaPlayerPrivateGStreamer.cpp b/WebCore/platform/graphics/gstreamer/MediaPlayerPrivateGStreamer.cpp
index 7184439..d9d2d97 100644
--- a/WebCore/platform/graphics/gstreamer/MediaPlayerPrivateGStreamer.cpp
+++ b/WebCore/platform/graphics/gstreamer/MediaPlayerPrivateGStreamer.cpp
@@ -54,7 +54,6 @@
#include <GOwnPtr.h>
#include <gst/gst.h>
#include <gst/interfaces/mixer.h>
-#include <gst/interfaces/xoverlay.h>
#include <gst/video/video.h>
#include <limits>
#include <math.h>
@@ -1385,7 +1384,7 @@ void MediaPlayerPrivateGStreamer::createGSTPlayBin()
ASSERT(!m_playBin);
m_playBin = gst_element_factory_make("playbin2", "play");
- m_gstGWorld = GStreamerGWorld::createGWorld(this);
+ m_gstGWorld = GStreamerGWorld::createGWorld(m_playBin);
GstBus* bus = gst_pipeline_get_bus(GST_PIPELINE(m_playBin));
gst_bus_add_signal_watch(bus);
diff --git a/WebCore/platform/graphics/gstreamer/PlatformVideoWindow.h b/WebCore/platform/graphics/gstreamer/PlatformVideoWindow.h
new file mode 100644
index 0000000..83dc5dd
--- /dev/null
+++ b/WebCore/platform/graphics/gstreamer/PlatformVideoWindow.h
@@ -0,0 +1,54 @@
+/*
+ * Copyright (C) 2010 Igalia S.L
+ *
+ * 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 PlatformVideoWindow_h
+#define PlatformVideoWindow_h
+
+#if ENABLE(VIDEO)
+
+#include <wtf/PassRefPtr.h>
+#include <wtf/RefCounted.h>
+
+#if PLATFORM(GTK)
+#include <gtk/gtk.h>
+typedef GtkWidget PlatformWindowType;
+#endif
+
+namespace WebCore {
+
+class PlatformVideoWindow : public RefCounted<PlatformVideoWindow> {
+ public:
+ static PassRefPtr<PlatformVideoWindow> createWindow() { return adoptRef(new PlatformVideoWindow()); }
+
+ PlatformVideoWindow();
+ ~PlatformVideoWindow();
+
+ PlatformWindowType* window() const { return m_window; }
+ gulong videoWindowId() const { return m_videoWindowId; }
+
+ private:
+ gulong m_videoWindowId;
+ PlatformWindowType* m_videoWindow;
+ PlatformWindowType* m_window;
+ };
+}
+
+#endif
+
+#endif
diff --git a/WebCore/platform/graphics/gstreamer/PlatformVideoWindowGtk.cpp b/WebCore/platform/graphics/gstreamer/PlatformVideoWindowGtk.cpp
new file mode 100644
index 0000000..185f535
--- /dev/null
+++ b/WebCore/platform/graphics/gstreamer/PlatformVideoWindowGtk.cpp
@@ -0,0 +1,60 @@
+/*
+ * Copyright (C) 2010 Igalia S.L
+ *
+ * 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 "PlatformVideoWindow.h"
+
+#ifdef GDK_WINDOWING_X11
+#include <gdk/gdkx.h> // for GDK_WINDOW_XID
+#endif
+
+using namespace WebCore;
+
+PlatformVideoWindow::PlatformVideoWindow()
+{
+ m_window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
+ gtk_widget_set_events(m_window, GDK_POINTER_MOTION_MASK | GDK_KEY_PRESS_MASK | GDK_FOCUS_CHANGE_MASK);
+
+ m_videoWindow = gtk_drawing_area_new();
+ gtk_widget_set_double_buffered(m_videoWindow, FALSE);
+ gtk_container_add(GTK_CONTAINER(m_window), m_videoWindow);
+
+ gtk_widget_realize(m_window);
+
+#ifdef GDK_WINDOWING_X11
+ m_videoWindowId = GDK_WINDOW_XID(gtk_widget_get_window(m_window));
+#endif
+
+}
+
+PlatformVideoWindow::~PlatformVideoWindow()
+{
+ if (m_videoWindow && m_window) {
+ gtk_container_remove(GTK_CONTAINER(m_window), m_videoWindow);
+ gtk_widget_destroy(m_videoWindow);
+ m_videoWindow = 0;
+ }
+
+ if (m_window) {
+ gtk_widget_destroy(m_window);
+ m_window = 0;
+ }
+
+ m_videoWindowId = 0;
+}
diff --git a/WebCore/platform/graphics/gtk/ImageBufferGtk.cpp b/WebCore/platform/graphics/gtk/ImageBufferGtk.cpp
index d0b0274..821cc12 100644
--- a/WebCore/platform/graphics/gtk/ImageBufferGtk.cpp
+++ b/WebCore/platform/graphics/gtk/ImageBufferGtk.cpp
@@ -44,7 +44,7 @@ String ImageBuffer::toDataURL(const String& mimeType, const double* quality) con
if (type != "jpeg" && type != "png" && type != "tiff" && type != "ico" && type != "bmp")
return "data:,";
- GRefPtr<GdkPixbuf> pixbuf = cairoImageSurfaceToGdkPixbuf(m_data.m_surface);
+ PlatformRefPtr<GdkPixbuf> pixbuf = cairoImageSurfaceToGdkPixbuf(m_data.m_surface);
if (!pixbuf)
return "data:,";
diff --git a/WebCore/platform/graphics/mac/FontCustomPlatformData.cpp b/WebCore/platform/graphics/mac/FontCustomPlatformData.cpp
index c591ddc..a600d73 100644
--- a/WebCore/platform/graphics/mac/FontCustomPlatformData.cpp
+++ b/WebCore/platform/graphics/mac/FontCustomPlatformData.cpp
@@ -31,8 +31,10 @@ namespace WebCore {
FontCustomPlatformData::~FontCustomPlatformData()
{
+#if defined(BUILDING_ON_TIGER) || defined(BUILDING_ON_LEOPARD)
if (m_atsContainer)
ATSFontDeactivate(m_atsContainer, NULL, kATSOptionFlagsDefault);
+#endif
CGFontRelease(m_cgFont);
}
diff --git a/WebCore/platform/graphics/mac/FontPlatformDataMac.mm b/WebCore/platform/graphics/mac/FontPlatformDataMac.mm
index 33de3c3..d905b62 100644
--- a/WebCore/platform/graphics/mac/FontPlatformDataMac.mm
+++ b/WebCore/platform/graphics/mac/FontPlatformDataMac.mm
@@ -39,9 +39,10 @@ FontPlatformData::FontPlatformData(NSFont *nsFont, bool syntheticBold, bool synt
, m_isColorBitmapFont(false)
#endif
{
- if (nsFont)
- CFRetain(nsFont);
- m_size = nsFont ? [nsFont pointSize] : 0.0f;
+ ASSERT_ARG(nsFont, nsFont);
+
+ CFRetain(nsFont);
+ m_size = [nsFont pointSize];
#ifndef BUILDING_ON_TIGER
m_cgFont.adoptCF(CTFontCopyGraphicsFont(toCTFontRef(nsFont), 0));
m_atsuFontID = CTFontGetPlatformFont(toCTFontRef(nsFont), 0);
@@ -95,14 +96,17 @@ const FontPlatformData& FontPlatformData::operator=(const FontPlatformData& f)
void FontPlatformData::setFont(NSFont *font)
{
+ ASSERT_ARG(font, font);
+ ASSERT(m_font != reinterpret_cast<NSFont *>(-1));
+
if (m_font == font)
return;
- if (font)
- CFRetain(font);
- if (m_font && m_font != reinterpret_cast<NSFont *>(-1))
+
+ CFRetain(font);
+ if (m_font)
CFRelease(m_font);
m_font = font;
- m_size = font ? [font pointSize] : 0.0f;
+ m_size = [font pointSize];
#ifndef BUILDING_ON_TIGER
m_cgFont.adoptCF(CTFontCopyGraphicsFont(toCTFontRef(font), 0));
m_atsuFontID = CTFontGetPlatformFont(toCTFontRef(font), 0);
diff --git a/WebCore/platform/graphics/mac/GraphicsContext3DMac.mm b/WebCore/platform/graphics/mac/GraphicsContext3DMac.mm
index be1d278..ab4ef4b 100644
--- a/WebCore/platform/graphics/mac/GraphicsContext3DMac.mm
+++ b/WebCore/platform/graphics/mac/GraphicsContext3DMac.mm
@@ -312,6 +312,16 @@ bool GraphicsContext3D::isGLES2Compliant() const
return false;
}
+bool GraphicsContext3D::isGLES2NPOTStrict() const
+{
+ return false;
+}
+
+bool GraphicsContext3D::isErrorGeneratedOnOutOfBoundsAccesses() const
+{
+ return false;
+}
+
void GraphicsContext3D::reshape(int width, int height)
{
if (width == m_currentWidth && height == m_currentHeight || !m_contextObj)
@@ -557,40 +567,16 @@ void GraphicsContext3D::bufferData(unsigned long target, int size, unsigned long
::glBufferData(target, size, 0, usage);
}
-void GraphicsContext3D::bufferData(unsigned long target, ArrayBuffer* array, unsigned long usage)
-{
- if (!array || !array->byteLength())
- return;
-
- ensureContext(m_contextObj);
- ::glBufferData(target, array->byteLength(), array->data(), usage);
-}
-
-void GraphicsContext3D::bufferData(unsigned long target, ArrayBufferView* array, unsigned long usage)
-{
- if (!array || !array->length())
- return;
-
- ensureContext(m_contextObj);
- ::glBufferData(target, array->byteLength(), array->baseAddress(), usage);
-}
-
-void GraphicsContext3D::bufferSubData(unsigned long target, long offset, ArrayBuffer* array)
+void GraphicsContext3D::bufferData(unsigned long target, int size, const void* data, unsigned long usage)
{
- if (!array || !array->byteLength())
- return;
-
ensureContext(m_contextObj);
- ::glBufferSubData(target, offset, array->byteLength(), array->data());
+ ::glBufferData(target, size, data, usage);
}
-void GraphicsContext3D::bufferSubData(unsigned long target, long offset, ArrayBufferView* array)
+void GraphicsContext3D::bufferSubData(unsigned long target, long offset, int size, const void* data)
{
- if (!array || !array->length())
- return;
-
ensureContext(m_contextObj);
- ::glBufferSubData(target, offset, array->byteLength(), array->baseAddress());
+ ::glBufferSubData(target, offset, size, data);
}
unsigned long GraphicsContext3D::checkFramebufferStatus(unsigned long target)
diff --git a/WebCore/platform/graphics/mac/GraphicsLayerCA.mm b/WebCore/platform/graphics/mac/GraphicsLayerCA.mm
index cb4ca58..315cc00 100644
--- a/WebCore/platform/graphics/mac/GraphicsLayerCA.mm
+++ b/WebCore/platform/graphics/mac/GraphicsLayerCA.mm
@@ -1213,6 +1213,18 @@ void GraphicsLayerCA::updateContentsOpaque()
void GraphicsLayerCA::updateBackfaceVisibility()
{
+ if (m_structuralLayer && structuralLayerPurpose() == StructuralLayerForReplicaFlattening) {
+ [m_structuralLayer.get() setDoubleSided:m_backfaceVisibility];
+
+ if (LayerMap* layerCloneMap = m_structuralLayerClones.get()) {
+ LayerMap::const_iterator end = layerCloneMap->end();
+ for (LayerMap::const_iterator it = layerCloneMap->begin(); it != end; ++it) {
+ CALayer *currLayer = it->second.get();
+ [currLayer setDoubleSided:m_backfaceVisibility];
+ }
+ }
+ }
+
[m_layer.get() setDoubleSided:m_backfaceVisibility];
if (LayerMap* layerCloneMap = m_layerClones.get()) {
@@ -1243,7 +1255,7 @@ void GraphicsLayerCA::ensureStructuralLayer(StructuralLayerPurpose purpose)
// Release the structural layer.
m_structuralLayer = 0;
- // Update the properties of m_layer now that we no loner have a structural layer.
+ // Update the properties of m_layer now that we no longer have a structural layer.
updateLayerPosition();
updateLayerSize();
updateAnchorPoint();
@@ -1294,6 +1306,7 @@ void GraphicsLayerCA::ensureStructuralLayer(StructuralLayerPurpose purpose)
updateAnchorPoint();
updateTransform();
updateChildrenTransform();
+ updateBackfaceVisibility();
// Set properties of m_layer to their default values, since these are expressed on on the structural layer.
CGPoint point = CGPointMake(m_size.width() / 2.0f, m_size.height() / 2.0f);
diff --git a/WebCore/platform/graphics/qt/ContextShadow.cpp b/WebCore/platform/graphics/qt/ContextShadow.cpp
index 0511218..829ca82 100644
--- a/WebCore/platform/graphics/qt/ContextShadow.cpp
+++ b/WebCore/platform/graphics/qt/ContextShadow.cpp
@@ -28,8 +28,80 @@
#include "config.h"
#include "ContextShadow.h"
+#include <QTimerEvent>
+#include <wtf/Noncopyable.h>
+
namespace WebCore {
+// ContextShadow needs a scratch image as the buffer for the blur filter.
+// Instead of creating and destroying the buffer for every operation,
+// we create a buffer which will be automatically purged via a timer.
+
+class ShadowBuffer: public QObject {
+public:
+ ShadowBuffer(QObject* parent = 0);
+
+ QImage* scratchImage(const QSize& size);
+
+ void schedulePurge();
+
+protected:
+ void timerEvent(QTimerEvent* event);
+
+private:
+ QImage image;
+ int timerId;
+};
+
+ShadowBuffer::ShadowBuffer(QObject* parent)
+ : QObject(parent)
+ , timerId(0)
+{
+}
+
+QImage* ShadowBuffer::scratchImage(const QSize& size)
+{
+ int width = size.width();
+ int height = size.height();
+
+ // We do not need to recreate the buffer if the buffer is reasonably
+ // larger than the requested size. However, if the requested size is
+ // much smaller than our buffer, reduce our buffer so that we will not
+ // keep too many allocated pixels for too long.
+ if (!image.isNull() && (image.width() > width) && (image.height() > height))
+ if (((2 * width) > image.width()) && ((2 * height) > image.height())) {
+ image.fill(Qt::transparent);
+ return &image;
+ }
+
+ // Round to the nearest 32 pixels so we do not grow the buffer everytime
+ // there is larger request by 1 pixel.
+ width = (1 + (width >> 5)) << 5;
+ height = (1 + (height >> 5)) << 5;
+
+ image = QImage(width, height, QImage::Format_ARGB32_Premultiplied);
+ image.fill(Qt::transparent);
+ return &image;
+}
+
+void ShadowBuffer::schedulePurge()
+{
+ static const double BufferPurgeDelay = 2; // seconds
+ killTimer(timerId);
+ timerId = startTimer(BufferPurgeDelay * 1000);
+}
+
+void ShadowBuffer::timerEvent(QTimerEvent* event)
+{
+ if (event->timerId() == timerId) {
+ killTimer(timerId);
+ image = QImage();
+ }
+ QObject::timerEvent(event);
+}
+
+Q_GLOBAL_STATIC(ShadowBuffer, scratchShadowBuffer)
+
ContextShadow::ContextShadow()
: type(NoShadow)
, blurRadius(0)
@@ -203,54 +275,66 @@ static void shadowBlur(QImage& image, int radius, const QColor& shadowColor)
p.end();
}
-void ContextShadow::drawShadowRect(QPainter* p, const QRectF& rect)
+QPainter* ContextShadow::beginShadowLayer(QPainter* p, const QRectF &rect)
{
- if (type == NoShadow)
- return;
-
- if (type == BlurShadow) {
- QRectF shadowRect = rect.translated(offset);
-
- // We expand the area by the blur radius * 2 to give extra space
- // for the blur transition.
- int extra = blurRadius * 2;
- QRectF bufferRect = shadowRect.adjusted(-extra, -extra, extra, extra);
- QRect alignedBufferRect = bufferRect.toAlignedRect();
-
- QRect clipRect;
- if (p->hasClipping())
- clipRect = p->clipRegion().boundingRect();
- else
- clipRect = p->transform().inverted().mapRect(p->window());
-
- if (!clipRect.contains(alignedBufferRect)) {
+ // We expand the area by the blur radius * 2 to give extra space
+ // for the blur transition.
+ int extra = (type == BlurShadow) ? blurRadius * 2 : 0;
+
+ QRectF shadowRect = rect.translated(offset);
+ QRectF bufferRect = shadowRect.adjusted(-extra, -extra, extra, extra);
+ m_layerRect = bufferRect.toAlignedRect();
+
+ QRect clipRect;
+ if (p->hasClipping())
+#if QT_VERSION >= QT_VERSION_CHECK(4, 8, 0)
+ clipRect = p->clipBoundingRect();
+#else
+ clipRect = p->clipRegion().boundingRect();
+#endif
+ else
+ clipRect = p->transform().inverted().mapRect(p->window());
+
+ if (!clipRect.contains(m_layerRect)) {
+
+ // No need to have the buffer larger than the clip.
+ m_layerRect = m_layerRect.intersected(clipRect);
+ if (m_layerRect.isEmpty())
+ return 0;
+
+ // We adjust again because the pixels at the borders are still
+ // potentially affected by the pixels outside the buffer.
+ if (type == BlurShadow)
+ m_layerRect.adjust(-extra, -extra, extra, extra);
+ }
- // No need to have the buffer larger that the clip.
- alignedBufferRect = alignedBufferRect.intersected(clipRect);
- if (alignedBufferRect.isEmpty())
- return;
+ ShadowBuffer* shadowBuffer = scratchShadowBuffer();
+ QImage* shadowImage = shadowBuffer->scratchImage(m_layerRect.size());
+ m_layerImage = QImage(*shadowImage);
- // We adjust again because the pixels at the borders are still
- // potentially affected by the pixels outside the buffer.
- alignedBufferRect.adjust(-extra, -extra, extra, extra);
- }
+ m_layerPainter = new QPainter;
+ m_layerPainter->begin(&m_layerImage);
+ m_layerPainter->setFont(p->font());
+ m_layerPainter->translate(offset);
- QImage shadowImage(alignedBufferRect.size(), QImage::Format_ARGB32_Premultiplied);
- shadowImage.fill(Qt::transparent);
- QPainter shadowPainter(&shadowImage);
+ // The origin is now the top left corner of the scratch image.
+ m_layerPainter->translate(-m_layerRect.topLeft());
- shadowPainter.fillRect(shadowRect.translated(-alignedBufferRect.topLeft()), color);
- shadowPainter.end();
+ return m_layerPainter;
+}
- shadowBlur(shadowImage, blurRadius, color);
+void ContextShadow::endShadowLayer(QPainter* p)
+{
+ m_layerPainter->end();
+ delete m_layerPainter;
+ m_layerPainter = 0;
- p->drawImage(alignedBufferRect.topLeft(), shadowImage);
+ if (type == BlurShadow)
+ shadowBlur(m_layerImage, blurRadius, color);
- return;
- }
+ p->drawImage(m_layerRect.topLeft(), m_layerImage);
- p->fillRect(rect.translated(offset), color);
+ scratchShadowBuffer()->schedulePurge();
}
-
}
diff --git a/WebCore/platform/graphics/qt/ContextShadow.h b/WebCore/platform/graphics/qt/ContextShadow.h
index e114ebc..7140340 100644
--- a/WebCore/platform/graphics/qt/ContextShadow.h
+++ b/WebCore/platform/graphics/qt/ContextShadow.h
@@ -58,12 +58,35 @@ public:
void clear();
- // Draws the shadow for colored rectangle (can't be filled with pattern
- // or gradient) according to the shadow parameters.
- // Note: 'rect' specifies the rectangle which casts the shadow,
- // NOT the bounding box of the shadow.
- void drawShadowRect(QPainter* p, const QRectF& rect);
+ // The pair beginShadowLayer and endShadowLayer creates a temporary image
+ // where the caller can draw onto, using the returned QPainter. This
+ // QPainter instance must be used only to draw between the call to
+ // beginShadowLayer and endShadowLayer.
+ //
+ // Note: multiple/nested shadow layer is NOT allowed.
+ //
+ // The current clip region will be used to optimize the size of the
+ // temporary image. Thus, the original painter should not change any
+ // clipping until endShadowLayer.
+ // If the shadow will be completely outside the clipping region,
+ // beginShadowLayer will return 0.
+ //
+ // The returned QPainter will have the transformation matrix and clipping
+ // properly initialized to start doing the painting (no need to account
+ // for the shadow offset), however it will not have the same render hints,
+ // pen, brush, etc as the passed QPainter. This is intentional, usually
+ // shadow has different properties than the shape which casts the shadow.
+ //
+ // Once endShadowLayer is called, the temporary image will be drawn
+ // with the original painter. If blur radius is specified, the shadow
+ // will be filtered first.
+ QPainter* beginShadowLayer(QPainter* p, const QRectF& rect);
+ void endShadowLayer(QPainter* p);
+private:
+ QRect m_layerRect;
+ QImage m_layerImage;
+ QPainter* m_layerPainter;
};
} // namespace WebCore
diff --git a/WebCore/platform/graphics/qt/FontQt.cpp b/WebCore/platform/graphics/qt/FontQt.cpp
index 59320cb..2b246de 100644
--- a/WebCore/platform/graphics/qt/FontQt.cpp
+++ b/WebCore/platform/graphics/qt/FontQt.cpp
@@ -23,6 +23,7 @@
#include "Font.h"
#include "AffineTransform.h"
+#include "ContextShadow.h"
#include "FontDescription.h"
#include "FontFallbackList.h"
#include "FontSelector.h"
@@ -108,12 +109,6 @@ static void drawTextCommon(GraphicsContext* ctx, const TextRun& run, const Float
QString string = fromRawDataWithoutRef(sanitized);
QPointF pt(point.x(), point.y());
- // text shadow
- FloatSize shadowSize;
- float shadowBlur;
- Color shadowColor;
- bool hasShadow = ctx->textDrawingMode() == cTextFill && ctx->getShadow(shadowSize, shadowBlur, shadowColor);
-
if (from > 0 || to < run.length()) {
if (isComplexText) {
QTextLayout layout(string, font);
@@ -125,32 +120,46 @@ static void drawTextCommon(GraphicsContext* ctx, const TextRun& run, const Float
QFontMetrics fm(font);
int ascent = fm.ascent();
- QRectF clip(point.x() + x1, point.y() - ascent, x2 - x1, fm.height());
+ QRectF boundingRect(point.x() + x1, point.y() - ascent, x2 - x1, fm.height());
+ QRectF clip = boundingRect;
+
+ ContextShadow* ctxShadow = ctx->contextShadow();
- if (hasShadow) {
- // TODO: when blur support is added, the clip will need to account
- // for the blur radius
+ if (ctxShadow->type != ContextShadow::NoShadow) {
qreal dx1 = 0, dx2 = 0, dy1 = 0, dy2 = 0;
- if (shadowSize.width() > 0)
- dx2 = shadowSize.width();
+ if (ctxShadow->offset.x() > 0)
+ dx2 = ctxShadow->offset.x();
else
- dx1 = -shadowSize.width();
- if (shadowSize.height() > 0)
- dy2 = shadowSize.height();
+ dx1 = -ctxShadow->offset.x();
+ if (ctxShadow->offset.y() > 0)
+ dy2 = ctxShadow->offset.y();
else
- dy1 = -shadowSize.height();
+ dy1 = -ctxShadow->offset.y();
// expand the clip rect to include the text shadow as well
clip.adjust(dx1, dx2, dy1, dy2);
+ clip.adjust(-ctxShadow->blurRadius, -ctxShadow->blurRadius, ctxShadow->blurRadius, ctxShadow->blurRadius);
}
p->save();
p->setClipRect(clip.toRect(), Qt::IntersectClip);
pt.setY(pt.y() - ascent);
- if (hasShadow) {
- p->save();
- p->setPen(QColor(shadowColor));
- p->translate(shadowSize.width(), shadowSize.height());
- line.draw(p, pt);
- p->restore();
+
+ if (ctxShadow->type != ContextShadow::NoShadow) {
+ ContextShadow* ctxShadow = ctx->contextShadow();
+ if (ctxShadow->type != ContextShadow::BlurShadow) {
+ p->save();
+ p->setPen(ctxShadow->color);
+ p->translate(ctxShadow->offset);
+ line.draw(p, pt);
+ p->restore();
+ } else {
+ QPainter* shadowPainter = ctxShadow->beginShadowLayer(p, boundingRect);
+ if (shadowPainter) {
+ // Since it will be blurred anyway, we don't care about render hints.
+ shadowPainter->setPen(ctxShadow->color);
+ line.draw(shadowPainter, pt);
+ ctxShadow->endShadowLayer(p);
+ }
+ }
}
p->setPen(textFillPen);
line.draw(p, pt);
@@ -169,16 +178,29 @@ static void drawTextCommon(GraphicsContext* ctx, const TextRun& run, const Float
int flags = run.rtl() ? Qt::TextForceRightToLeft : Qt::TextForceLeftToRight;
#if QT_VERSION >= QT_VERSION_CHECK(4, 7, 0)
// See QWebPagePrivate::QWebPagePrivate() where the default path is set to Complex for Qt 4.6 and earlier.
- if (!isComplexText)
+ if (!isComplexText && !(ctx->textDrawingMode() & cTextStroke))
flags |= Qt::TextBypassShaping;
#endif
- if (hasShadow) {
- // TODO: text shadow blur support
- p->save();
- p->setPen(QColor(shadowColor));
- p->translate(shadowSize.width(), shadowSize.height());
- p->drawText(pt, string, flags, run.padding());
- p->restore();
+ if (ctx->contextShadow()->type != ContextShadow::NoShadow) {
+ ContextShadow* ctxShadow = ctx->contextShadow();
+ if (ctxShadow->type != ContextShadow::BlurShadow) {
+ p->save();
+ p->setPen(ctxShadow->color);
+ p->translate(ctxShadow->offset);
+ p->drawText(pt, string, flags, run.padding());
+ p->restore();
+ } else {
+ QFontMetrics fm(font);
+ QRectF boundingRect(point.x(), point.y() - fm.ascent(), fm.width(string), fm.height());
+ QPainter* shadowPainter = ctxShadow->beginShadowLayer(p, boundingRect);
+ if (shadowPainter) {
+ // Since it will be blurred anyway, we don't care about render hints.
+ shadowPainter->setFont(p->font());
+ shadowPainter->setPen(ctxShadow->color);
+ shadowPainter->drawText(pt, string, flags, run.padding());
+ ctxShadow->endShadowLayer(p);
+ }
+ }
}
if (ctx->textDrawingMode() & cTextStroke) {
QPainterPath path;
diff --git a/WebCore/platform/graphics/qt/GradientQt.cpp b/WebCore/platform/graphics/qt/GradientQt.cpp
index 1f05a15..72bb009 100644
--- a/WebCore/platform/graphics/qt/GradientQt.cpp
+++ b/WebCore/platform/graphics/qt/GradientQt.cpp
@@ -46,8 +46,15 @@ QGradient* Gradient::platformGradient()
if (m_gradient)
return m_gradient;
+ bool reversed = m_r0 > m_r1;
+
+ qreal innerRadius = reversed ? m_r1 : m_r0;
+ qreal outerRadius = reversed ? m_r0 : m_r1;
+ QPointF center = reversed ? m_p0 : m_p1;
+ QPointF focalPoint = reversed ? m_p1 : m_p0;
+
if (m_radial)
- m_gradient = new QRadialGradient(m_p1.x(), m_p1.y(), m_r1, m_p0.x(), m_p0.y());
+ m_gradient = new QRadialGradient(center, outerRadius, focalPoint);
else
m_gradient = new QLinearGradient(m_p0.x(), m_p0.y(), m_p1.x(), m_p1.y());
@@ -65,9 +72,19 @@ QGradient* Gradient::platformGradient()
lastStop = stopIterator->stop + lastStopDiff;
else
lastStop = stopIterator->stop;
- if (m_radial && m_r0)
- lastStop = m_r0 / m_r1 + lastStop * (1.0f - m_r0 / m_r1);
- m_gradient->setColorAt(qMin(lastStop, qreal(1.0f)), stopColor);
+
+ if (m_radial && !qFuzzyCompare(1 + outerRadius, qreal(1))) {
+ lastStop = lastStop * (1.0f - innerRadius / outerRadius);
+ if (!reversed)
+ lastStop += innerRadius / outerRadius;
+ }
+
+ qreal stopPosition = qMin(lastStop, qreal(1.0f));
+
+ if (m_radial && reversed)
+ stopPosition = 1 - stopPosition;
+
+ m_gradient->setColorAt(stopPosition, stopColor);
// Keep the lastStop as orginal value, since the following stopColor depend it
lastStop = stopIterator->stop;
++stopIterator;
diff --git a/WebCore/platform/graphics/qt/GraphicsContext3DQt.cpp b/WebCore/platform/graphics/qt/GraphicsContext3DQt.cpp
index d5e7b3f..7918378 100644
--- a/WebCore/platform/graphics/qt/GraphicsContext3DQt.cpp
+++ b/WebCore/platform/graphics/qt/GraphicsContext3DQt.cpp
@@ -20,18 +20,14 @@
#include "GraphicsContext3D.h"
-#include "ArrayBufferView.h"
#include "WebGLObject.h"
#include "CanvasRenderingContext.h"
-#include "Float32Array.h"
#include "GraphicsContext.h"
#include "HTMLCanvasElement.h"
#include "HostWindow.h"
#include "ImageBuffer.h"
-#include "Int32Array.h"
#include "NotImplemented.h"
#include "QWebPageClient.h"
-#include "Uint8Array.h"
#include <QAbstractScrollArea>
#include <QGLContext>
#include <wtf/UnusedParam.h>
@@ -89,6 +85,7 @@ typedef void (APIENTRY* glGenFramebuffersType) (GLsizei, GLuint*);
typedef void (APIENTRY* glGenRenderbuffersType) (GLsizei, GLuint*);
typedef void (APIENTRY* glGetActiveAttribType) (GLuint, GLuint, GLsizei, GLsizei*, GLint*, GLenum*, GLchar*);
typedef void (APIENTRY* glGetActiveUniformType) (GLuint, GLuint, GLsizei, GLsizei*, GLint*, GLenum*, GLchar*);
+typedef void (APIENTRY* glGetAttachedShadersType) (GLuint, GLsizei, GLsizei*, GLuint*);
typedef GLint (APIENTRY* glGetAttribLocationType) (GLuint, const char*);
typedef void (APIENTRY* glGetBufferParameterivType) (GLenum, GLenum, GLint*);
typedef void (APIENTRY* glGetFramebufferAttachmentParameterivType) (GLenum, GLenum, GLenum, GLint* params);
@@ -187,6 +184,7 @@ public:
glGenRenderbuffersType genRenderbuffers;
glGetActiveAttribType getActiveAttrib;
glGetActiveUniformType getActiveUniform;
+ glGetAttachedShadersType getAttachedShaders;
glGetAttribLocationType getAttribLocation;
glGetBufferParameterivType getBufferParameteriv;
glGetFramebufferAttachmentParameterivType getFramebufferAttachmentParameteriv;
@@ -276,6 +274,18 @@ bool GraphicsContext3D::isGLES2Compliant() const
#endif
}
+// Even with underlying GLES2 driver, the below flags should still be set to
+// false if extentions exist (and they almost always do).
+bool GraphicsContext3D::isGLES2NPOTStrict() const
+{
+ return false;
+}
+
+bool GraphicsContext3D::isErrorGeneratedOnOutOfBoundsAccesses() const
+{
+ return false;
+}
+
GraphicsContext3DInternal::GraphicsContext3DInternal(GraphicsContext3D::Attributes attrs, HostWindow* hostWindow)
: m_attrs(attrs)
@@ -349,6 +359,7 @@ GraphicsContext3DInternal::GraphicsContext3DInternal(GraphicsContext3D::Attribut
genRenderbuffers = GET_PROC_ADDRESS(glGenRenderbuffers);
getActiveAttrib = GET_PROC_ADDRESS(glGetActiveAttrib);
getActiveUniform = GET_PROC_ADDRESS(glGetActiveUniform);
+ getAttachedShaders = GET_PROC_ADDRESS(glGetAttachedShaders);
getAttribLocation = GET_PROC_ADDRESS(glGetAttribLocation);
getBufferParameteriv = GET_PROC_ADDRESS(glGetBufferParameteriv);
getFramebufferAttachmentParameteriv = GET_PROC_ADDRESS(glGetFramebufferAttachmentParameteriv);
@@ -582,7 +593,7 @@ void GraphicsContext3D::activeTexture(unsigned long texture)
m_internal->activeTexture(texture);
}
-void GraphicsContext3D::attachShader(PlatformGLObject program, PlatformGLObject shader)
+void GraphicsContext3D::attachShader(Platform3DObject program, Platform3DObject shader)
{
ASSERT(program);
ASSERT(shader);
@@ -590,33 +601,44 @@ void GraphicsContext3D::attachShader(PlatformGLObject program, PlatformGLObject
m_internal->attachShader((GLuint) program, (GLuint) shader);
}
-void GraphicsContext3D::bindAttribLocation(PlatformGLObject program, unsigned long index, const String& name)
+void GraphicsContext3D::getAttachedShaders(Platform3DObject program, int maxCount, int* count, unsigned int* shaders)
+{
+ if (!program) {
+ synthesizeGLError(INVALID_VALUE);
+ return;
+ }
+
+ m_internal->m_glWidget->makeCurrent();
+ getAttachedShaders((GLuint) program, maxCount, count, shaders);
+}
+
+void GraphicsContext3D::bindAttribLocation(Platform3DObject program, unsigned long index, const String& name)
{
ASSERT(program);
m_internal->m_glWidget->makeCurrent();
m_internal->bindAttribLocation((GLuint) program, index, name.utf8().data());
}
-void GraphicsContext3D::bindBuffer(unsigned long target, PlatformGLObject buffer)
+void GraphicsContext3D::bindBuffer(unsigned long target, Platform3DObject buffer)
{
m_internal->m_glWidget->makeCurrent();
- m_internal->bindBuffer(target, (GLuint) buffer->object());
+ m_internal->bindBuffer(target, (GLuint) buffer);
}
-void GraphicsContext3D::bindFramebuffer(unsigned long target, PlatformGLObject buffer)
+void GraphicsContext3D::bindFramebuffer(unsigned long target, Platform3DObject buffer)
{
m_internal->m_glWidget->makeCurrent();
m_internal->m_currentFbo = buffer ? (GLuint) buffer : m_internal->m_mainFbo;
m_internal->bindFramebuffer(target, m_internal->m_currentFbo);
}
-void GraphicsContext3D::bindRenderbuffer(unsigned long target, PlatformGLObject renderbuffer)
+void GraphicsContext3D::bindRenderbuffer(unsigned long target, Platform3DObject renderbuffer)
{
m_internal->m_glWidget->makeCurrent();
m_internal->bindRenderbuffer(target, (GLuint) renderbuffer);
}
-void GraphicsContext3D::bindTexture(unsigned long target, PlatformGLObject texture)
+void GraphicsContext3D::bindTexture(unsigned long target, Platform3DObject texture)
{
m_internal->m_glWidget->makeCurrent();
glBindTexture(target, (GLuint) texture);
@@ -658,22 +680,16 @@ void GraphicsContext3D::bufferData(unsigned long target, int size, unsigned long
m_internal->bufferData(target, size, /* data */ 0, usage);
}
-void GraphicsContext3D::bufferData(unsigned long target, ArrayBufferView* array, unsigned long usage)
+void GraphicsContext3D::bufferData(unsigned long target, int size, const void* data, unsigned long usage)
{
- if (!array || !array->length())
- return;
-
m_internal->m_glWidget->makeCurrent();
- m_internal->bufferData(target, array->byteLength(), array->baseAddress(), usage);
+ m_internal->bufferData(target, size, data, usage);
}
-void GraphicsContext3D::bufferSubData(unsigned long target, long offset, ArrayBufferView* array)
+void GraphicsContext3D::bufferSubData(unsigned long target, long offset, int size, const void* data)
{
- if (!array || !array->length())
- return;
-
m_internal->m_glWidget->makeCurrent();
- m_internal->bufferSubData(target, offset, array->byteLength(), array->baseAddress());
+ m_internal->bufferSubData(target, offset, size, data);
}
unsigned long GraphicsContext3D::checkFramebufferStatus(unsigned long target)
@@ -716,7 +732,7 @@ void GraphicsContext3D::colorMask(bool red, bool green, bool blue, bool alpha)
glColorMask(red, green, blue, alpha);
}
-void GraphicsContext3D::compileShader(PlatformGLObject shader)
+void GraphicsContext3D::compileShader(Platform3DObject shader)
{
ASSERT(shader);
m_internal->m_glWidget->makeCurrent();
@@ -763,7 +779,7 @@ void GraphicsContext3D::depthRange(double zNear, double zFar)
#endif
}
-void GraphicsContext3D::detachShader(PlatformGLObject program, PlatformGLObject shader)
+void GraphicsContext3D::detachShader(Platform3DObject program, Platform3DObject shader)
{
ASSERT(program);
ASSERT(shader);
@@ -819,13 +835,13 @@ void GraphicsContext3D::flush()
glFlush();
}
-void GraphicsContext3D::framebufferRenderbuffer(unsigned long target, unsigned long attachment, unsigned long renderbuffertarget, PlatformGLObject buffer)
+void GraphicsContext3D::framebufferRenderbuffer(unsigned long target, unsigned long attachment, unsigned long renderbuffertarget, Platform3DObject buffer)
{
m_internal->m_glWidget->makeCurrent();
m_internal->framebufferRenderbuffer(target, attachment, renderbuffertarget, (GLuint) buffer);
}
-void GraphicsContext3D::framebufferTexture2D(unsigned long target, unsigned long attachment, unsigned long textarget, PlatformGLObject texture, long level)
+void GraphicsContext3D::framebufferTexture2D(unsigned long target, unsigned long attachment, unsigned long textarget, Platform3DObject texture, long level)
{
m_internal->m_glWidget->makeCurrent();
m_internal->framebufferTexture2D(target, attachment, textarget, (GLuint) texture, level);
@@ -843,7 +859,7 @@ void GraphicsContext3D::generateMipmap(unsigned long target)
m_internal->generateMipmap(target);
}
-bool GraphicsContext3D::getActiveAttrib(PlatformGLObject program, unsigned long index, ActiveInfo& info)
+bool GraphicsContext3D::getActiveAttrib(Platform3DObject program, unsigned long index, ActiveInfo& info)
{
if (!program) {
synthesizeGLError(INVALID_VALUE);
@@ -875,7 +891,7 @@ bool GraphicsContext3D::getActiveAttrib(PlatformGLObject program, unsigned long
return true;
}
-bool GraphicsContext3D::getActiveUniform(PlatformGLObject program, unsigned long index, ActiveInfo& info)
+bool GraphicsContext3D::getActiveUniform(Platform3DObject program, unsigned long index, ActiveInfo& info)
{
if (!program) {
synthesizeGLError(INVALID_VALUE);
@@ -907,7 +923,7 @@ bool GraphicsContext3D::getActiveUniform(PlatformGLObject program, unsigned long
return true;
}
-int GraphicsContext3D::getAttribLocation(PlatformGLObject program, const String& name)
+int GraphicsContext3D::getAttribLocation(Platform3DObject program, const String& name)
{
if (!program)
return -1;
@@ -946,7 +962,7 @@ void GraphicsContext3D::hint(unsigned long target, unsigned long mode)
glHint(target, mode);
}
-bool GraphicsContext3D::isBuffer(PlatformGLObject buffer)
+bool GraphicsContext3D::isBuffer(Platform3DObject buffer)
{
if (!buffer)
return false;
@@ -961,7 +977,7 @@ bool GraphicsContext3D::isEnabled(unsigned long cap)
return glIsEnabled(cap);
}
-bool GraphicsContext3D::isFramebuffer(PlatformGLObject framebuffer)
+bool GraphicsContext3D::isFramebuffer(Platform3DObject framebuffer)
{
if (!framebuffer)
return false;
@@ -970,7 +986,7 @@ bool GraphicsContext3D::isFramebuffer(PlatformGLObject framebuffer)
return m_internal->isFramebuffer((GLuint) framebuffer);
}
-bool GraphicsContext3D::isProgram(PlatformGLObject program)
+bool GraphicsContext3D::isProgram(Platform3DObject program)
{
if (!program)
return false;
@@ -979,7 +995,7 @@ bool GraphicsContext3D::isProgram(PlatformGLObject program)
return m_internal->isProgram((GLuint) program);
}
-bool GraphicsContext3D::isRenderbuffer(PlatformGLObject renderbuffer)
+bool GraphicsContext3D::isRenderbuffer(Platform3DObject renderbuffer)
{
if (!renderbuffer)
return false;
@@ -988,7 +1004,7 @@ bool GraphicsContext3D::isRenderbuffer(PlatformGLObject renderbuffer)
return m_internal->isRenderbuffer((GLuint) renderbuffer);
}
-bool GraphicsContext3D::isShader(PlatformGLObject shader)
+bool GraphicsContext3D::isShader(Platform3DObject shader)
{
if (!shader)
return false;
@@ -997,7 +1013,7 @@ bool GraphicsContext3D::isShader(PlatformGLObject shader)
return m_internal->isShader((GLuint) shader);
}
-bool GraphicsContext3D::isTexture(PlatformGLObject texture)
+bool GraphicsContext3D::isTexture(Platform3DObject texture)
{
if (!texture)
return false;
@@ -1012,7 +1028,7 @@ void GraphicsContext3D::lineWidth(double width)
glLineWidth(static_cast<float>(width));
}
-void GraphicsContext3D::linkProgram(PlatformGLObject program)
+void GraphicsContext3D::linkProgram(Platform3DObject program)
{
ASSERT(program);
m_internal->m_glWidget->makeCurrent();
@@ -1065,7 +1081,7 @@ void GraphicsContext3D::scissor(long x, long y, unsigned long width, unsigned lo
glScissor(x, y, width, height);
}
-void GraphicsContext3D::shaderSource(PlatformGLObject shader, const String& source)
+void GraphicsContext3D::shaderSource(Platform3DObject shader, const String& source)
{
ASSERT(shader);
@@ -1247,7 +1263,7 @@ void GraphicsContext3D::uniformMatrix4fv(long location, bool transpose, float* a
m_internal->uniformMatrix4fv(location, size, transpose, array);
}
-void GraphicsContext3D::useProgram(PlatformGLObject program)
+void GraphicsContext3D::useProgram(Platform3DObject program)
{
ASSERT(program);
@@ -1255,7 +1271,7 @@ void GraphicsContext3D::useProgram(PlatformGLObject program)
m_internal->useProgram((GLuint) program);
}
-void GraphicsContext3D::validateProgram(PlatformGLObject program)
+void GraphicsContext3D::validateProgram(Platform3DObject program)
{
ASSERT(program);
@@ -1353,13 +1369,13 @@ void GraphicsContext3D::getIntegerv(unsigned long paramName, int* value)
glGetIntegerv(paramName, value);
}
-void GraphicsContext3D::getProgramiv(PlatformGLObject program, unsigned long paramName, int* value)
+void GraphicsContext3D::getProgramiv(Platform3DObject program, unsigned long paramName, int* value)
{
m_internal->m_glWidget->makeCurrent();
m_internal->getProgramiv((GLuint) program, paramName, value);
}
-String GraphicsContext3D::getProgramInfoLog(PlatformGLObject program)
+String GraphicsContext3D::getProgramInfoLog(Platform3DObject program)
{
m_internal->m_glWidget->makeCurrent();
@@ -1386,14 +1402,14 @@ void GraphicsContext3D::getRenderbufferParameteriv(unsigned long target, unsigne
m_internal->getRenderbufferParameteriv(target, paramName, value);
}
-void GraphicsContext3D::getShaderiv(PlatformGLObject shader, unsigned long paramName, int* value)
+void GraphicsContext3D::getShaderiv(Platform3DObject shader, unsigned long paramName, int* value)
{
ASSERT(shader);
m_internal->m_glWidget->makeCurrent();
m_internal->getShaderiv((GLuint) shader, paramName, value);
}
-String GraphicsContext3D::getShaderInfoLog(PlatformGLObject shader)
+String GraphicsContext3D::getShaderInfoLog(Platform3DObject shader)
{
m_internal->m_glWidget->makeCurrent();
@@ -1413,7 +1429,7 @@ String GraphicsContext3D::getShaderInfoLog(PlatformGLObject shader)
return result;
}
-String GraphicsContext3D::getShaderSource(PlatformGLObject shader)
+String GraphicsContext3D::getShaderSource(Platform3DObject shader)
{
m_internal->m_glWidget->makeCurrent();
@@ -1445,19 +1461,19 @@ void GraphicsContext3D::getTexParameteriv(unsigned long target, unsigned long pa
glGetTexParameteriv(target, paramName, value);
}
-void GraphicsContext3D::getUniformfv(PlatformGLObject program, long location, float* value)
+void GraphicsContext3D::getUniformfv(Platform3DObject program, long location, float* value)
{
m_internal->m_glWidget->makeCurrent();
m_internal->getUniformfv((GLuint) program, location, value);
}
-void GraphicsContext3D::getUniformiv(PlatformGLObject program, long location, int* value)
+void GraphicsContext3D::getUniformiv(Platform3DObject program, long location, int* value)
{
m_internal->m_glWidget->makeCurrent();
m_internal->getUniformiv((GLuint) program, location, value);
}
-long GraphicsContext3D::getUniformLocation(PlatformGLObject program, const String& name)
+long GraphicsContext3D::getUniformLocation(Platform3DObject program, const String& name)
{
ASSERT(program);
@@ -1621,7 +1637,7 @@ bool GraphicsContext3D::getImageData(Image* image,
return false;
AlphaOp neededAlphaOp = kAlphaDoNothing;
- if (!premultiplyAlpha && *hasAlphaChannel)
+ if (!premultiplyAlpha)
// FIXME: must fetch the image data before the premultiplication step
neededAlphaOp = kAlphaDoUnmultiply;
QImage nativeImage = nativePixmap->toImage().convertToFormat(QImage::Format_ARGB32);
diff --git a/WebCore/platform/graphics/qt/GraphicsContextQt.cpp b/WebCore/platform/graphics/qt/GraphicsContextQt.cpp
index 1632804..41c9759 100644
--- a/WebCore/platform/graphics/qt/GraphicsContextQt.cpp
+++ b/WebCore/platform/graphics/qt/GraphicsContextQt.cpp
@@ -209,6 +209,15 @@ public:
return shadow.type != ContextShadow::NoShadow;
}
+ QRectF clipBoundingRect() const
+ {
+#if QT_VERSION >= QT_VERSION_CHECK(4, 8, 0)
+ return painter->clipBoundingRect();
+#else
+ return painter->clipRegion().boundingRect();
+#endif
+ }
+
private:
QPainter* painter;
};
@@ -247,6 +256,9 @@ GraphicsContext::GraphicsContext(PlatformGraphicsContext* context)
// Make sure the context starts in sync with our state.
setPlatformFillColor(fillColor(), DeviceColorSpace);
setPlatformStrokeColor(strokeColor(), DeviceColorSpace);
+
+ // Make sure we start with the correct join mode.
+ setLineJoin(MiterJoin);
}
}
@@ -636,56 +648,50 @@ void GraphicsContext::fillRect(const FloatRect& rect)
return;
QPainter* p = m_data->p();
- FloatRect normalizedRect = rect.normalized();
-
- QRectF shadowDestRect;
- QImage* shadowImage = 0;
- QPainter* pShadow = 0;
-
- if (m_data->hasShadow()) {
- shadowImage = new QImage(roundedIntSize(normalizedRect.size()), QImage::Format_ARGB32_Premultiplied);
- pShadow = new QPainter(shadowImage);
- shadowDestRect = normalizedRect;
- shadowDestRect.translate(m_data->shadow.offset);
-
- pShadow->setCompositionMode(QPainter::CompositionMode_Source);
- pShadow->fillRect(shadowImage->rect(), m_data->shadow.color);
- pShadow->setCompositionMode(QPainter::CompositionMode_DestinationIn);
- }
+ QRectF normalizedRect = rect.normalized();
+ ContextShadow* shadow = contextShadow();
if (m_common->state.fillPattern) {
AffineTransform affine;
- FloatRect rectM(rect);
QBrush brush(m_common->state.fillPattern->createPlatformPattern(affine));
QPixmap* image = m_common->state.fillPattern->tileImage()->nativeImageForCurrentFrame();
-
- if (m_data->hasShadow()) {
- drawRepeatPattern(pShadow, image, FloatRect(static_cast<QRectF>(shadowImage->rect())), m_common->state.fillPattern->repeatX(), m_common->state.fillPattern->repeatY());
- pShadow->end();
- p->drawImage(shadowDestRect, *shadowImage, shadowImage->rect());
+ QPainter* shadowPainter = m_data->hasShadow() ? shadow->beginShadowLayer(p, normalizedRect) : 0;
+ if (shadowPainter) {
+ drawRepeatPattern(shadowPainter, image, normalizedRect, m_common->state.fillPattern->repeatX(), m_common->state.fillPattern->repeatY());
+ shadowPainter->setCompositionMode(QPainter::CompositionMode_SourceIn);
+ shadowPainter->fillRect(normalizedRect, shadow->color);
+ shadow->endShadowLayer(p);
}
drawRepeatPattern(p, image, normalizedRect, m_common->state.fillPattern->repeatX(), m_common->state.fillPattern->repeatY());
} else if (m_common->state.fillGradient) {
QBrush brush(*m_common->state.fillGradient->platformGradient());
brush.setTransform(m_common->state.fillGradient->gradientSpaceTransform());
-
- if (m_data->hasShadow()) {
- pShadow->fillRect(shadowImage->rect(), brush);
- pShadow->end();
- p->drawImage(shadowDestRect, *shadowImage, shadowImage->rect());
+ QPainter* shadowPainter = m_data->hasShadow() ? shadow->beginShadowLayer(p, normalizedRect) : 0;
+ if (shadowPainter) {
+ shadowPainter->fillRect(normalizedRect, brush);
+ shadowPainter->setCompositionMode(QPainter::CompositionMode_SourceIn);
+ shadowPainter->fillRect(normalizedRect, shadow->color);
+ shadow->endShadowLayer(p);
}
p->fillRect(normalizedRect, brush);
} else {
if (m_data->hasShadow()) {
- pShadow->fillRect(shadowImage->rect(), p->brush());
- pShadow->end();
- p->drawImage(shadowDestRect, *shadowImage, shadowImage->rect());
+ if (shadow->type == ContextShadow::BlurShadow) {
+ QPainter* shadowPainter = shadow->beginShadowLayer(p, normalizedRect);
+ if (shadowPainter) {
+ shadowPainter->fillRect(normalizedRect, p->brush());
+ shadow->endShadowLayer(p);
+ }
+ } else {
+ // Solid rectangle fill with no blur shadow can be done faster
+ // without using the shadow layer at all.
+ QColor shadowColor = shadow->color;
+ shadowColor.setAlphaF(shadowColor.alphaF() * p->brush().color().alphaF());
+ p->fillRect(normalizedRect.translated(shadow->offset), shadowColor);
+ }
}
p->fillRect(normalizedRect, p->brush());
}
-
- delete shadowImage;
- delete pShadow;
}
@@ -696,11 +702,25 @@ void GraphicsContext::fillRect(const FloatRect& rect, const Color& color, ColorS
m_data->solidColor.setColor(color);
QPainter* p = m_data->p();
+ QRectF normalizedRect = rect.normalized();
- if (m_data->hasShadow())
- m_data->shadow.drawShadowRect(p, rect);
+ if (m_data->hasShadow()) {
+ ContextShadow* shadow = contextShadow();
- p->fillRect(rect, m_data->solidColor);
+ if (shadow->type != ContextShadow::BlurShadow) {
+ // We do not need any layer for simple shadow.
+ p->fillRect(normalizedRect.translated(shadow->offset), shadow->color);
+ } else {
+ QPainter* shadowPainter = shadow->beginShadowLayer(p, normalizedRect);
+ if (shadowPainter) {
+ shadowPainter->setCompositionMode(QPainter::CompositionMode_Source);
+ shadowPainter->fillRect(normalizedRect, shadow->color);
+ shadow->endShadowLayer(p);
+ }
+ }
+ }
+
+ p->fillRect(normalizedRect, m_data->solidColor);
}
void GraphicsContext::fillRoundedRect(const IntRect& rect, const IntSize& topLeft, const IntSize& topRight, const IntSize& bottomLeft, const IntSize& bottomRight, const Color& color, ColorSpace colorSpace)
@@ -742,6 +762,11 @@ PlatformPath* GraphicsContext::currentPath()
return &m_data->currentPath;
}
+ContextShadow* GraphicsContext::contextShadow()
+{
+ return &m_data->shadow;
+}
+
void GraphicsContext::clip(const FloatRect& rect)
{
if (paintingDisabled())
@@ -893,7 +918,7 @@ void GraphicsContext::beginTransparencyLayer(float opacity)
w = device->width();
h = device->height();
- QRectF clip = p->clipPath().boundingRect();
+ QRectF clip = m_data->clipBoundingRect();
QRectF deviceClip = p->transform().mapRect(clip);
x = int(qBound(qreal(0), deviceClip.x(), (qreal)w));
y = int(qBound(qreal(0), deviceClip.y(), (qreal)h));
@@ -1056,7 +1081,7 @@ void GraphicsContext::clipOut(const Path& path)
QPainterPath newClip;
newClip.setFillRule(Qt::OddEvenFill);
if (p->hasClipping()) {
- newClip.addRect(p->clipRegion().boundingRect());
+ newClip.addRect(m_data->clipBoundingRect());
newClip.addPath(clippedOut);
p->setClipPath(newClip, Qt::IntersectClip);
} else {
@@ -1126,7 +1151,7 @@ void GraphicsContext::clipOut(const IntRect& rect)
QPainterPath newClip;
newClip.setFillRule(Qt::OddEvenFill);
if (p->hasClipping()) {
- newClip.addRect(p->clipRegion().boundingRect());
+ newClip.addRect(m_data->clipBoundingRect());
newClip.addRect(QRect(rect));
p->setClipPath(newClip, Qt::IntersectClip);
} else {
@@ -1148,7 +1173,7 @@ void GraphicsContext::clipOutEllipseInRect(const IntRect& rect)
QPainterPath newClip;
newClip.setFillRule(Qt::OddEvenFill);
if (p->hasClipping()) {
- newClip.addRect(p->clipRegion().boundingRect());
+ newClip.addRect(m_data->clipBoundingRect());
newClip.addEllipse(QRect(rect));
p->setClipPath(newClip, Qt::IntersectClip);
} else {
diff --git a/WebCore/platform/graphics/qt/GraphicsLayerQt.h b/WebCore/platform/graphics/qt/GraphicsLayerQt.h
index f81bd3d..4282e64 100644
--- a/WebCore/platform/graphics/qt/GraphicsLayerQt.h
+++ b/WebCore/platform/graphics/qt/GraphicsLayerQt.h
@@ -20,6 +20,9 @@
#ifndef GraphicsLayerQt_h
#define GraphicsLayerQt_h
+#if ENABLE(3D_CANVAS)
+#include "GraphicsContext3D.h"
+#endif
#include "GraphicsLayer.h"
#include "GraphicsLayerClient.h"
diff --git a/WebCore/platform/graphics/qt/ImageBufferQt.cpp b/WebCore/platform/graphics/qt/ImageBufferQt.cpp
index 11ca377..ee01222 100644
--- a/WebCore/platform/graphics/qt/ImageBufferQt.cpp
+++ b/WebCore/platform/graphics/qt/ImageBufferQt.cpp
@@ -216,11 +216,11 @@ PassRefPtr<ImageData> getImageData(const IntRect& rect, const ImageBufferData& i
const uchar* bits = image.bits();
#endif
- quint32* destRows = reinterpret_cast<quint32*>(&data[desty * rect.width() + destx]);
+ quint32* destRows = reinterpret_cast_ptr<quint32*>(&data[desty * rect.width() + destx]);
if (multiplied == Unmultiplied) {
for (int y = 0; y < numRows; ++y) {
- const quint32* scanLine = reinterpret_cast<const quint32*>(bits + (y + originy) * bytesPerLine);
+ const quint32* scanLine = reinterpret_cast_ptr<const quint32*>(bits + (y + originy) * bytesPerLine);
for (int x = 0; x < numColumns; x++) {
QRgb pixel = scanLine[x + originx];
int alpha = qAlpha(pixel);
@@ -242,7 +242,7 @@ PassRefPtr<ImageData> getImageData(const IntRect& rect, const ImageBufferData& i
}
} else {
for (int y = 0; y < numRows; ++y) {
- const quint32* scanLine = reinterpret_cast<const quint32*>(bits + (y + originy) * bytesPerLine);
+ const quint32* scanLine = reinterpret_cast_ptr<const quint32*>(bits + (y + originy) * bytesPerLine);
for (int x = 0; x < numColumns; x++) {
QRgb pixel = scanLine[x + originx];
// Convert RGB to BGR.
@@ -318,11 +318,11 @@ void putImageData(ImageData*& source, const IntRect& sourceRect, const IntPoint&
uchar* bits = image.bits();
const int bytesPerLine = image.bytesPerLine();
- const quint32* srcScanLine = reinterpret_cast<const quint32*>(source->data()->data()->data() + originy * srcBytesPerRow + originx * 4);
+ const quint32* srcScanLine = reinterpret_cast_ptr<const quint32*>(source->data()->data()->data() + originy * srcBytesPerRow + originx * 4);
if (multiplied == Unmultiplied) {
for (int y = 0; y < numRows; ++y) {
- quint32* destScanLine = reinterpret_cast<quint32*>(bits + y * bytesPerLine);
+ quint32* destScanLine = reinterpret_cast_ptr<quint32*>(bits + y * bytesPerLine);
for (int x = 0; x < numColumns; x++) {
// Premultiply and convert BGR to RGB.
quint32 pixel = srcScanLine[x];
@@ -332,7 +332,7 @@ void putImageData(ImageData*& source, const IntRect& sourceRect, const IntPoint&
}
} else {
for (int y = 0; y < numRows; ++y) {
- quint32* destScanLine = reinterpret_cast<quint32*>(bits + y * bytesPerLine);
+ quint32* destScanLine = reinterpret_cast_ptr<quint32*>(bits + y * bytesPerLine);
for (int x = 0; x < numColumns; x++) {
// Convert BGR to RGB.
quint32 pixel = srcScanLine[x];
diff --git a/WebCore/platform/graphics/qt/ImageDecoderQt.cpp b/WebCore/platform/graphics/qt/ImageDecoderQt.cpp
index 858cc44..02bb110 100644
--- a/WebCore/platform/graphics/qt/ImageDecoderQt.cpp
+++ b/WebCore/platform/graphics/qt/ImageDecoderQt.cpp
@@ -37,17 +37,18 @@
namespace WebCore {
-ImageDecoder* ImageDecoder::create(const SharedBuffer& data)
+ImageDecoder* ImageDecoder::create(const SharedBuffer& data, bool premultiplyAlpha)
{
// We need at least 4 bytes to figure out what kind of image we're dealing with.
if (data.size() < 4)
return 0;
- return new ImageDecoderQt;
+ return new ImageDecoderQt(premultiplyAlpha);
}
-ImageDecoderQt::ImageDecoderQt()
- : m_repetitionCount(cAnimationNone)
+ImageDecoderQt::ImageDecoderQt(bool premultiplyAlpha)
+ : ImageDecoder(premultiplyAlpha)
+ , m_repetitionCount(cAnimationNone)
{
}
@@ -104,10 +105,15 @@ size_t ImageDecoderQt::frameCount()
// we will have to parse everything...
if (!imageCount)
forceLoadEverything();
- else
+ else {
m_frameBufferCache.resize(imageCount);
- } else
+ for (size_t i = 0; i < m_frameBufferCache.size(); ++i)
+ m_frameBufferCache[i].setPremultiplyAlpha(m_premultiplyAlpha);
+ }
+ } else {
m_frameBufferCache.resize(1);
+ m_frameBufferCache[0].setPremultiplyAlpha(m_premultiplyAlpha);
+ }
}
return m_frameBufferCache.size();
@@ -236,6 +242,8 @@ void ImageDecoderQt::forceLoadEverything()
// Otherwise, we want to forget about
// the last attempt to decode a image.
m_frameBufferCache.resize(imageCount - 1);
+ for (size_t i = 0; i < m_frameBufferCache.size(); ++i)
+ m_frameBufferCache[i].setPremultiplyAlpha(m_premultiplyAlpha);
if (imageCount == 1)
setFailed();
}
diff --git a/WebCore/platform/graphics/qt/ImageDecoderQt.h b/WebCore/platform/graphics/qt/ImageDecoderQt.h
index ceef884..5014d53 100644
--- a/WebCore/platform/graphics/qt/ImageDecoderQt.h
+++ b/WebCore/platform/graphics/qt/ImageDecoderQt.h
@@ -41,7 +41,7 @@ namespace WebCore {
class ImageDecoderQt : public ImageDecoder
{
public:
- ImageDecoderQt();
+ ImageDecoderQt(bool premultiplyAlpha);
~ImageDecoderQt();
virtual void setData(SharedBuffer* data, bool allDataReceived);
diff --git a/WebCore/platform/graphics/qt/TransparencyLayer.h b/WebCore/platform/graphics/qt/TransparencyLayer.h
index 0d9c121..1a614ac 100644
--- a/WebCore/platform/graphics/qt/TransparencyLayer.h
+++ b/WebCore/platform/graphics/qt/TransparencyLayer.h
@@ -52,7 +52,7 @@ struct TransparencyLayer : FastAllocBase {
offset = rect.topLeft();
pixmap.fill(Qt::transparent);
painter.begin(&pixmap);
- painter.setRenderHint(QPainter::Antialiasing, p->testRenderHint(QPainter::Antialiasing));
+ painter.setRenderHints(QPainter::Antialiasing | QPainter::SmoothPixmapTransform);
painter.translate(-offset);
painter.setPen(p->pen());
painter.setBrush(p->brush());
diff --git a/WebCore/platform/graphics/skia/BitmapImageSingleFrameSkia.h b/WebCore/platform/graphics/skia/BitmapImageSingleFrameSkia.h
index 9fb6a8b..553f203 100644
--- a/WebCore/platform/graphics/skia/BitmapImageSingleFrameSkia.h
+++ b/WebCore/platform/graphics/skia/BitmapImageSingleFrameSkia.h
@@ -46,9 +46,10 @@ namespace WebCore {
// is that NativeImagePtr = NativeImageSkia, yet callers have SkBitmap.
class BitmapImageSingleFrameSkia : public Image {
public:
- // Creates a new Image, by copying the pixel values out of |bitmap|.
- // If creation failed, returns null.
- static PassRefPtr<BitmapImageSingleFrameSkia> create(const SkBitmap&);
+ // Creates a new Image from the given SkBitmap. If "copyPixels" is true, a
+ // deep copy is done. Otherwise, a shallow copy is done (pixel data is
+ // ref'ed).
+ static PassRefPtr<BitmapImageSingleFrameSkia> create(const SkBitmap&, bool copyPixels);
virtual bool isBitmapImage() const { return true; }
@@ -77,8 +78,8 @@ protected:
private:
NativeImageSkia m_nativeImage;
- // Use create().
- BitmapImageSingleFrameSkia() { }
+ // Creates a new Image from the given SkBitmap, using a shallow copy.
+ explicit BitmapImageSingleFrameSkia(const SkBitmap&);
};
} // namespace WebCore
diff --git a/WebCore/platform/graphics/skia/GraphicsContext3DSkia.cpp b/WebCore/platform/graphics/skia/GraphicsContext3DSkia.cpp
index ee0a874..61039f2 100644
--- a/WebCore/platform/graphics/skia/GraphicsContext3DSkia.cpp
+++ b/WebCore/platform/graphics/skia/GraphicsContext3DSkia.cpp
@@ -31,6 +31,7 @@
#include "GraphicsContext3D.h"
#include "Image.h"
+#include "ImageSource.h"
#include "NativeImageSkia.h"
#include <algorithm>
@@ -43,27 +44,28 @@ bool GraphicsContext3D::getImageData(Image* image,
bool premultiplyAlpha,
Vector<uint8_t>& outputVector)
{
- if (!image)
+ if (!image || !image->data())
return false;
- NativeImageSkia* skiaImage = image->nativeImageForCurrentFrame();
- if (!skiaImage)
+ ImageSource decoder(false);
+ decoder.setData(image->data(), true);
+ if (!decoder.frameCount() || !decoder.frameIsCompleteAtIndex(0))
return false;
- SkBitmap::Config skiaConfig = skiaImage->config();
- // FIXME: must support more image configurations.
+ bool hasAlpha = decoder.frameHasAlphaAtIndex(0);
+ OwnPtr<NativeImageSkia> pixels(decoder.createFrameAtIndex(0));
+ if (!pixels.get() || !pixels->isDataComplete() || !pixels->width() || !pixels->height())
+ return false;
+ SkBitmap::Config skiaConfig = pixels->config();
if (skiaConfig != SkBitmap::kARGB_8888_Config)
return false;
- SkBitmap& skiaImageRef = *skiaImage;
+ SkBitmap& skiaImageRef = *pixels;
SkAutoLockPixels lock(skiaImageRef);
- int height = skiaImage->height();
- int rowBytes = skiaImage->rowBytes();
- ASSERT(rowBytes == skiaImage->width() * 4);
- uint8_t* pixels = reinterpret_cast<uint8_t*>(skiaImage->getPixels());
- outputVector.resize(rowBytes * height);
+ ASSERT(pixels->rowBytes() == pixels->width() * 4);
+ outputVector.resize(pixels->rowBytes() * pixels->height());
AlphaOp neededAlphaOp = kAlphaDoNothing;
- if (!premultiplyAlpha)
- // FIXME: must fetch the image data before the premultiplication step
- neededAlphaOp = kAlphaDoUnmultiply;
- return packPixels(pixels, kSourceFormatBGRA8, skiaImage->width(), height, 0,
+ if (hasAlpha && premultiplyAlpha)
+ neededAlphaOp = kAlphaDoPremultiply;
+ return packPixels(reinterpret_cast<const uint8_t*>(pixels->getPixels()),
+ kSourceFormatBGRA8, pixels->width(), pixels->height(), 0,
format, type, neededAlphaOp, outputVector.data());
}
diff --git a/WebCore/platform/graphics/skia/GraphicsContextSkia.cpp b/WebCore/platform/graphics/skia/GraphicsContextSkia.cpp
index fe7f6ce..1b20e26 100644
--- a/WebCore/platform/graphics/skia/GraphicsContextSkia.cpp
+++ b/WebCore/platform/graphics/skia/GraphicsContextSkia.cpp
@@ -323,7 +323,6 @@ void GraphicsContext::addPath(const Path& path)
{
if (paintingDisabled())
return;
- platformContext()->prepareForSoftwareDraw();
platformContext()->addPath(*path.platformPath());
}
@@ -331,7 +330,6 @@ void GraphicsContext::beginPath()
{
if (paintingDisabled())
return;
- platformContext()->prepareForSoftwareDraw();
platformContext()->beginPath();
}
@@ -783,7 +781,7 @@ void GraphicsContext::fillRect(const FloatRect& rect)
}
#if USE(GLES2_RENDERING)
- if (platformContext()->useGPU() && !m_common->state.fillPattern && !m_common->state.fillGradient) {
+ if (platformContext()->useGPU() && !m_common->state.fillPattern && !m_common->state.fillGradient && !platformContext()->getDrawLooper()) {
platformContext()->prepareForHardwareDraw();
platformContext()->gpuCanvas()->fillRect(rect);
return;
diff --git a/WebCore/platform/graphics/skia/ImageBufferSkia.cpp b/WebCore/platform/graphics/skia/ImageBufferSkia.cpp
index a63eec5..9403406 100644
--- a/WebCore/platform/graphics/skia/ImageBufferSkia.cpp
+++ b/WebCore/platform/graphics/skia/ImageBufferSkia.cpp
@@ -89,12 +89,13 @@ GraphicsContext* ImageBuffer::context() const
bool ImageBuffer::drawsUsingCopy() const
{
- return true;
+ return false;
}
PassRefPtr<Image> ImageBuffer::copyImage() const
{
- return BitmapImageSingleFrameSkia::create(*m_data.m_platformContext.bitmap());
+ m_context->platformContext()->syncSoftwareCanvas();
+ return BitmapImageSingleFrameSkia::create(*m_data.m_platformContext.bitmap(), true);
}
void ImageBuffer::clip(GraphicsContext* context, const FloatRect& rect) const
@@ -107,15 +108,15 @@ void ImageBuffer::clip(GraphicsContext* context, const FloatRect& rect) const
void ImageBuffer::draw(GraphicsContext* context, ColorSpace styleColorSpace, const FloatRect& destRect, const FloatRect& srcRect,
CompositeOperator op, bool useLowQualityScale)
{
- RefPtr<Image> imageCopy = copyImage();
- context->drawImage(imageCopy.get(), styleColorSpace, destRect, srcRect, op, useLowQualityScale);
+ RefPtr<Image> image = BitmapImageSingleFrameSkia::create(*m_data.m_platformContext.bitmap(), context == m_context);
+ context->drawImage(image.get(), styleColorSpace, destRect, srcRect, op, useLowQualityScale);
}
void ImageBuffer::drawPattern(GraphicsContext* context, const FloatRect& srcRect, const AffineTransform& patternTransform,
const FloatPoint& phase, ColorSpace styleColorSpace, CompositeOperator op, const FloatRect& destRect)
{
- RefPtr<Image> imageCopy = copyImage();
- imageCopy->drawPattern(context, srcRect, patternTransform, phase, styleColorSpace, op, destRect);
+ RefPtr<Image> image = BitmapImageSingleFrameSkia::create(*m_data.m_platformContext.bitmap(), context == m_context);
+ image->drawPattern(context, srcRect, patternTransform, phase, styleColorSpace, op, destRect);
}
void ImageBuffer::platformTransformColorSpace(const Vector<int>& lookUpTable)
diff --git a/WebCore/platform/graphics/skia/ImageSkia.cpp b/WebCore/platform/graphics/skia/ImageSkia.cpp
index b514b1a..1ff87cc 100644
--- a/WebCore/platform/graphics/skia/ImageSkia.cpp
+++ b/WebCore/platform/graphics/skia/ImageSkia.cpp
@@ -419,8 +419,9 @@ static void drawBitmapGLES2(GraphicsContext* ctxt, NativeImageSkia* bitmap, cons
ASSERT(bitmap->config() == SkBitmap::kARGB_8888_Config);
ASSERT(bitmap->rowBytes() == bitmap->width() * 4);
texture = gpuCanvas->createTexture(bitmap, GLES2Texture::BGRA8, bitmap->width(), bitmap->height());
- ASSERT(bitmap->pixelRef());
- texture->load(bitmap->pixelRef()->pixels());
+ SkAutoLockPixels lock(*bitmap);
+ ASSERT(bitmap->getPixels());
+ texture->load(bitmap->getPixels());
}
gpuCanvas->drawTexturedRect(texture, srcRect, dstRect, styleColorSpace, compositeOp);
}
@@ -516,11 +517,19 @@ void BitmapImageSingleFrameSkia::draw(GraphicsContext* ctxt,
WebCoreCompositeToSkiaComposite(compositeOp));
}
-PassRefPtr<BitmapImageSingleFrameSkia> BitmapImageSingleFrameSkia::create(const SkBitmap& bitmap)
+BitmapImageSingleFrameSkia::BitmapImageSingleFrameSkia(const SkBitmap& bitmap)
+ : m_nativeImage(bitmap)
{
- RefPtr<BitmapImageSingleFrameSkia> image(adoptRef(new BitmapImageSingleFrameSkia()));
- bitmap.copyTo(&image->m_nativeImage, bitmap.config());
- return image.release();
+}
+
+PassRefPtr<BitmapImageSingleFrameSkia> BitmapImageSingleFrameSkia::create(const SkBitmap& bitmap, bool copyPixels)
+{
+ if (copyPixels) {
+ SkBitmap temp;
+ bitmap.copyTo(&temp, bitmap.config());
+ return adoptRef(new BitmapImageSingleFrameSkia(temp));
+ }
+ return adoptRef(new BitmapImageSingleFrameSkia(bitmap));
}
} // namespace WebCore
diff --git a/WebCore/platform/graphics/skia/NativeImageSkia.cpp b/WebCore/platform/graphics/skia/NativeImageSkia.cpp
index 007a32c..28e0758 100644
--- a/WebCore/platform/graphics/skia/NativeImageSkia.cpp
+++ b/WebCore/platform/graphics/skia/NativeImageSkia.cpp
@@ -46,6 +46,14 @@ NativeImageSkia::NativeImageSkia()
{
}
+NativeImageSkia::NativeImageSkia(const SkBitmap& other)
+ : SkBitmap(other),
+ m_isDataComplete(false),
+ m_lastRequestSize(0, 0),
+ m_resizeRequests(0)
+{
+}
+
int NativeImageSkia::decodedSize() const
{
return getSize() + m_resizedImage.getSize();
diff --git a/WebCore/platform/graphics/skia/NativeImageSkia.h b/WebCore/platform/graphics/skia/NativeImageSkia.h
index 0718836..e26a5ea 100644
--- a/WebCore/platform/graphics/skia/NativeImageSkia.h
+++ b/WebCore/platform/graphics/skia/NativeImageSkia.h
@@ -43,6 +43,11 @@ class NativeImageSkia : public SkBitmap {
public:
NativeImageSkia();
+ // This constructor does a shallow copy of the passed-in SkBitmap (ie., it
+ // references the same pixel data and bumps the refcount). Use only when
+ // you want sharing semantics.
+ explicit NativeImageSkia(const SkBitmap&);
+
// Returns the number of bytes of image data. This includes the cached
// resized version if there is one.
int decodedSize() const;
diff --git a/WebCore/platform/graphics/skia/PlatformContextSkia.cpp b/WebCore/platform/graphics/skia/PlatformContextSkia.cpp
index 1161224..b9de0a2 100644
--- a/WebCore/platform/graphics/skia/PlatformContextSkia.cpp
+++ b/WebCore/platform/graphics/skia/PlatformContextSkia.cpp
@@ -733,11 +733,7 @@ void PlatformContextSkia::prepareForSoftwareDraw() const
if (m_state->m_xferMode == SkXfermode::kSrcOver_Mode) {
// Last drawn on hardware; clear out the canvas.
- m_canvas->save();
- SkRect bounds = {0, 0, m_canvas->getDevice()->width(), m_canvas->getDevice()->height()};
- m_canvas->clipRect(bounds, SkRegion::kReplace_Op);
- m_canvas->drawARGB(0, 0, 0, 0, SkXfermode::kClear_Mode);
- m_canvas->restore();
+ m_canvas->getDevice()->eraseColor(0);
// Start compositing into the empty canvas.
m_backingStoreState = Mixed;
} else {
@@ -753,6 +749,8 @@ void PlatformContextSkia::prepareForSoftwareDraw() const
readbackHardwareToSoftware();
m_backingStoreState = Software;
}
+ } else if (m_backingStoreState == None) {
+ m_backingStoreState = Software;
}
}
diff --git a/WebCore/platform/graphics/win/FontCustomPlatformDataCairo.cpp b/WebCore/platform/graphics/win/FontCustomPlatformDataCairo.cpp
index 35839f5..02c5b99 100644
--- a/WebCore/platform/graphics/win/FontCustomPlatformDataCairo.cpp
+++ b/WebCore/platform/graphics/win/FontCustomPlatformDataCairo.cpp
@@ -27,12 +27,12 @@
namespace WebCore {
-FontCustomPlatformDataCairo::~FontCustomPlatformDataCairo()
+FontCustomPlatformData::~FontCustomPlatformData()
{
cairo_font_face_destroy(m_fontFace);
}
-FontPlatformData FontCustomPlatformDataCairo::fontPlatformData(int size, bool bold, bool italic)
+FontPlatformData FontCustomPlatformData::fontPlatformData(int size, bool bold, bool italic)
{
return FontPlatformData(m_fontFace, size, bold, italic);
}
@@ -42,7 +42,7 @@ static void releaseData(void* data)
static_cast<SharedBuffer*>(data)->deref();
}
-FontCustomPlatformDataCairo* createFontCustomPlatformData(SharedBuffer* buffer)
+FontCustomPlatformData* createFontCustomPlatformData(SharedBuffer* buffer)
{
ASSERT_ARG(buffer, buffer);
@@ -55,7 +55,7 @@ FontCustomPlatformDataCairo* createFontCustomPlatformData(SharedBuffer* buffer)
static cairo_user_data_key_t bufferKey;
cairo_font_face_set_user_data(fontFace, &bufferKey, buffer, releaseData);
- return new FontCustomPlatformDataCairo(fontFace);
+ return new FontCustomPlatformData(fontFace);
}
bool FontCustomPlatformData::supportsFormat(const String& format)
diff --git a/WebCore/platform/graphics/win/FontCustomPlatformDataCairo.h b/WebCore/platform/graphics/win/FontCustomPlatformDataCairo.h
index 2dbea51..525957f 100644
--- a/WebCore/platform/graphics/win/FontCustomPlatformDataCairo.h
+++ b/WebCore/platform/graphics/win/FontCustomPlatformDataCairo.h
@@ -1,5 +1,6 @@
/*
* Copyright (C) 2007 Apple Computer, Inc.
+ * Copyright (C) 2010 Brent Fulgham <bfulgham@webkit.org>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
@@ -31,12 +32,12 @@ namespace WebCore {
class FontPlatformData;
class SharedBuffer;
-struct FontCustomPlatformDataCairo : Noncopyable {
- FontCustomPlatformDataCairo(cairo_font_face_t* fontFace)
+struct FontCustomPlatformData : Noncopyable {
+ FontCustomPlatformData(cairo_font_face_t* fontFace)
: m_fontFace(fontFace)
{
}
- ~FontCustomPlatformDataCairo();
+ ~FontCustomPlatformData();
FontPlatformData fontPlatformData(int size, bool bold, bool italic);
@@ -45,7 +46,7 @@ struct FontCustomPlatformDataCairo : Noncopyable {
cairo_font_face_t* m_fontFace;
};
-FontCustomPlatformDataCairo* createFontCustomPlatformData(SharedBuffer*);
+FontCustomPlatformData* createFontCustomPlatformData(SharedBuffer*);
}
diff --git a/WebCore/platform/graphics/win/WKCACFLayer.cpp b/WebCore/platform/graphics/win/WKCACFLayer.cpp
index b5f3427..bbe5883 100644
--- a/WebCore/platform/graphics/win/WKCACFLayer.cpp
+++ b/WebCore/platform/graphics/win/WKCACFLayer.cpp
@@ -44,6 +44,24 @@ namespace WebCore {
using namespace std;
+#ifndef NDEBUG
+void WKCACFLayer::internalCheckLayerConsistency()
+{
+ ASSERT(layer());
+ size_t n = sublayerCount();
+ for (size_t i = 0; i < n; ++i) {
+ // This will ASSERT in internalSublayerAtIndex if this entry doesn't have proper user data
+ WKCACFLayer* sublayer = internalSublayerAtIndex(i);
+
+ // Make sure we don't have any null entries in the list
+ ASSERT(sublayer);
+
+ // Make sure the each layer has a corresponding CACFLayer
+ ASSERT(sublayer->layer());
+ }
+}
+#endif
+
static void displayCallback(CACFLayerRef layer, CGContextRef context)
{
ASSERT_ARG(layer, WKCACFLayer::layer(layer));
@@ -161,7 +179,14 @@ WKCACFLayer::~WKCACFLayer()
// Our superlayer should be holding a reference to us, so there should be no way for us to be destroyed while we still have a superlayer.
ASSERT(!superlayer());
+ // Get rid of the children so we don't have any dangling references around
+ removeAllSublayers();
+
+#ifndef NDEBUG
+ CACFLayerSetUserData(layer(), reinterpret_cast<void*>(0xDEADBEEF));
+#else
CACFLayerSetUserData(layer(), 0);
+#endif
CACFLayerSetDisplayCallback(layer(), 0);
}
@@ -192,10 +217,11 @@ void WKCACFLayer::addSublayer(PassRefPtr<WKCACFLayer> sublayer)
void WKCACFLayer::internalInsertSublayer(PassRefPtr<WKCACFLayer> sublayer, size_t index)
{
- index = min(index, sublayerCount());
+ index = min(index, sublayerCount() + 1);
sublayer->removeFromSuperlayer();
CACFLayerInsertSublayer(layer(), sublayer->layer(), index);
setNeedsCommit();
+ checkLayerConsistency();
}
void WKCACFLayer::insertSublayerAboveLayer(PassRefPtr<WKCACFLayer> sublayer, const WKCACFLayer* reference)
@@ -268,12 +294,14 @@ void WKCACFLayer::adoptSublayers(WKCACFLayer* source)
sublayers.append(source->internalSublayerAtIndex(i));
setSublayers(sublayers);
+ source->checkLayerConsistency();
}
void WKCACFLayer::removeFromSuperlayer()
{
WKCACFLayer* superlayer = this->superlayer();
CACFLayerRemoveFromSuperlayer(layer());
+ checkLayerConsistency();
if (superlayer)
superlayer->setNeedsCommit();
diff --git a/WebCore/platform/graphics/win/WKCACFLayer.h b/WebCore/platform/graphics/win/WKCACFLayer.h
index abc04c8..7243508 100644
--- a/WebCore/platform/graphics/win/WKCACFLayer.h
+++ b/WebCore/platform/graphics/win/WKCACFLayer.h
@@ -60,7 +60,11 @@ public:
BottomLeft, BottomRight, Resize, ResizeAspect, ResizeAspectFill };
static PassRefPtr<WKCACFLayer> create(LayerType);
- static WKCACFLayer* layer(CACFLayerRef layer) { return static_cast<WKCACFLayer*>(CACFLayerGetUserData(layer)); }
+ static WKCACFLayer* layer(CACFLayerRef layer)
+ {
+ ASSERT(CACFLayerGetUserData(layer) != reinterpret_cast<void*>(0xDEADBEEF));
+ return static_cast<WKCACFLayer*>(CACFLayerGetUserData(layer));
+ }
virtual ~WKCACFLayer();
@@ -133,7 +137,11 @@ public:
void adoptSublayers(WKCACFLayer* source);
void removeAllSublayers() { internalRemoveAllSublayers(); }
- void setSublayers(const Vector<RefPtr<WKCACFLayer> >& sublayers) { internalSetSublayers(sublayers); }
+ void setSublayers(const Vector<RefPtr<WKCACFLayer> >& sublayers)
+ {
+ internalSetSublayers(sublayers);
+ checkLayerConsistency();
+ }
void insertSublayer(PassRefPtr<WKCACFLayer> layer, size_t index) { internalInsertSublayer(layer, index); }
@@ -244,6 +252,13 @@ protected:
// This should only be called from removeFromSuperlayer.
void removeSublayer(const WKCACFLayer*);
+ void checkLayerConsistency()
+ {
+#ifndef NDEBUG
+ internalCheckLayerConsistency();
+#endif
+ }
+
// Methods to be overridden for sublayer and rendering management
virtual WKCACFLayer* internalSublayerAtIndex(int) const;
@@ -259,6 +274,10 @@ protected:
virtual void internalSetNeedsDisplay(const CGRect* dirtyRect);
#ifndef NDEBUG
+ virtual void internalCheckLayerConsistency();
+#endif
+
+#ifndef NDEBUG
// Print this layer and its children to the console
void printLayer(int indent) const;
#endif
diff --git a/WebCore/platform/graphics/win/WebTiledLayer.cpp b/WebCore/platform/graphics/win/WebTiledLayer.cpp
index d8c02d2..01dd6ae 100755
--- a/WebCore/platform/graphics/win/WebTiledLayer.cpp
+++ b/WebCore/platform/graphics/win/WebTiledLayer.cpp
@@ -36,6 +36,26 @@ namespace WebCore {
using namespace std;
+#ifndef NDEBUG
+void WebTiledLayer::internalCheckLayerConsistency()
+{
+ WKCACFLayer::internalCheckLayerConsistency();
+
+ // Additionally make sure the tiled parent is valid
+ CFArrayRef sublayers = CACFLayerGetSublayers(layer());
+
+ // Make sure there is a tile parent and it is the same as we remember
+ size_t n = CFArrayGetCount(sublayers);
+ ASSERT(n > 0);
+ const void* element = CFArrayGetValueAtIndex(sublayers, 0);
+ ASSERT(m_tileParent.get() == element);
+
+ // Make sure the tile parent doesn't have user data. If it does, it is probably
+ // a WKCACFLayer in the wrong place.
+ ASSERT(!layer(m_tileParent.get()));
+}
+#endif
+
void WebTiledLayer::tileDisplayCallback(CACFLayerRef layer, CGContextRef context)
{
static_cast<WebTiledLayer*>(CACFLayerGetUserData(layer))->drawTile(layer, context);
diff --git a/WebCore/platform/graphics/win/WebTiledLayer.h b/WebCore/platform/graphics/win/WebTiledLayer.h
index fdf0205..b8ae320 100644
--- a/WebCore/platform/graphics/win/WebTiledLayer.h
+++ b/WebCore/platform/graphics/win/WebTiledLayer.h
@@ -56,6 +56,10 @@ protected:
virtual void internalSetNeedsDisplay(const CGRect* dirtyRect);
+#ifndef NDEBUG
+ virtual void internalCheckLayerConsistency();
+#endif
+
private:
static void tileDisplayCallback(CACFLayerRef, CGContextRef);
void drawTile(CACFLayerRef, CGContextRef);
diff --git a/WebCore/platform/gtk/ClipboardGtk.cpp b/WebCore/platform/gtk/ClipboardGtk.cpp
index 21ebe4c..b2c32a4 100644
--- a/WebCore/platform/gtk/ClipboardGtk.cpp
+++ b/WebCore/platform/gtk/ClipboardGtk.cpp
@@ -330,7 +330,7 @@ void ClipboardGtk::declareAndWriteDragImage(Element* element, const KURL& url, c
if (!image || !image->isLoaded())
return;
- GRefPtr<GdkPixbuf> pixbuf = adoptGRef(image->image()->getGdkPixbuf());
+ PlatformRefPtr<GdkPixbuf> pixbuf = adoptPlatformRef(image->image()->getGdkPixbuf());
if (!pixbuf)
return;
diff --git a/WebCore/platform/gtk/CursorGtk.cpp b/WebCore/platform/gtk/CursorGtk.cpp
index 41b0800..d1f1293 100644
--- a/WebCore/platform/gtk/CursorGtk.cpp
+++ b/WebCore/platform/gtk/CursorGtk.cpp
@@ -37,25 +37,39 @@
namespace WebCore {
-static GRefPtr<GdkCursor> createNamedCursor(CustomCursorType cursorType)
+static GdkPixmap* createPixmapFromBits(const unsigned char* bits, const IntSize& size)
+{
+ cairo_surface_t* dataSurface = cairo_image_surface_create_for_data(const_cast<unsigned char*>(bits), CAIRO_FORMAT_A1, size.width(), size.height(), size.width() / 8);
+ GdkPixmap* pixmap = gdk_pixmap_new(0, size.width(), size.height(), 1);
+ cairo_t* cr = gdk_cairo_create(pixmap);
+ cairo_set_source_surface(cr, dataSurface, 0, 0);
+ cairo_set_operator(cr, CAIRO_OPERATOR_SOURCE);
+ cairo_paint(cr);
+ cairo_destroy(cr);
+ cairo_surface_destroy(dataSurface);
+ return pixmap;
+}
+
+static PlatformRefPtr<GdkCursor> createNamedCursor(CustomCursorType cursorType)
{
CustomCursor cursor = CustomCursors[cursorType];
- GRefPtr<GdkCursor> c = adoptGRef(gdk_cursor_new_from_name(gdk_display_get_default(), cursor.name));
+ PlatformRefPtr<GdkCursor> c = adoptPlatformRef(gdk_cursor_new_from_name(gdk_display_get_default(), cursor.name));
if (c)
return c;
const GdkColor fg = { 0, 0, 0, 0 };
const GdkColor bg = { 65535, 65535, 65535, 65535 };
- GRefPtr<GdkPixmap> source = adoptGRef(gdk_bitmap_create_from_data(0, cursor.bits, 32, 32));
- GRefPtr<GdkPixmap> mask = adoptGRef(gdk_bitmap_create_from_data(0, cursor.mask_bits, 32, 32));
- return adoptGRef(gdk_cursor_new_from_pixmap(source.get(), mask.get(), &fg, &bg, cursor.hot_x, cursor.hot_y));
+ IntSize cursorSize = IntSize(32, 32);
+ PlatformRefPtr<GdkPixmap> source = adoptPlatformRef(createPixmapFromBits(cursor.bits, cursorSize));
+ PlatformRefPtr<GdkPixmap> mask = adoptPlatformRef(createPixmapFromBits(cursor.mask_bits, cursorSize));
+ return adoptPlatformRef(gdk_cursor_new_from_pixmap(source.get(), mask.get(), &fg, &bg, cursor.hot_x, cursor.hot_y));
}
-static GRefPtr<GdkCursor> createCustomCursor(Image* image, const IntPoint& hotSpot)
+static PlatformRefPtr<GdkCursor> createCustomCursor(Image* image, const IntPoint& hotSpot)
{
IntPoint effectiveHotSpot = determineHotSpot(image, hotSpot);
- GRefPtr<GdkPixbuf> pixbuf = adoptGRef(image->getGdkPixbuf());
- return adoptGRef(gdk_cursor_new_from_pixbuf(gdk_display_get_default(), pixbuf.get(), effectiveHotSpot.x(), effectiveHotSpot.y()));
+ PlatformRefPtr<GdkPixbuf> pixbuf = adoptPlatformRef(image->getGdkPixbuf());
+ return adoptPlatformRef(gdk_cursor_new_from_pixbuf(gdk_display_get_default(), pixbuf.get(), effectiveHotSpot.x(), effectiveHotSpot.y()));
}
void Cursor::ensurePlatformCursor() const
@@ -69,77 +83,77 @@ void Cursor::ensurePlatformCursor() const
m_platformCursor = 0;
break;
case Cursor::Cross:
- m_platformCursor = adoptGRef(gdk_cursor_new(GDK_CROSS));
+ m_platformCursor = adoptPlatformRef(gdk_cursor_new(GDK_CROSS));
break;
case Cursor::Hand:
- m_platformCursor = adoptGRef(gdk_cursor_new(GDK_HAND2));
+ m_platformCursor = adoptPlatformRef(gdk_cursor_new(GDK_HAND2));
break;
case Cursor::IBeam:
- m_platformCursor = adoptGRef(gdk_cursor_new(GDK_XTERM));
+ m_platformCursor = adoptPlatformRef(gdk_cursor_new(GDK_XTERM));
break;
case Cursor::Wait:
- m_platformCursor = adoptGRef(gdk_cursor_new(GDK_WATCH));
+ m_platformCursor = adoptPlatformRef(gdk_cursor_new(GDK_WATCH));
break;
case Cursor::Help:
- m_platformCursor = adoptGRef(gdk_cursor_new(GDK_QUESTION_ARROW));
+ m_platformCursor = adoptPlatformRef(gdk_cursor_new(GDK_QUESTION_ARROW));
break;
case Cursor::Move:
case Cursor::MiddlePanning:
- m_platformCursor = adoptGRef(gdk_cursor_new(GDK_FLEUR));
+ m_platformCursor = adoptPlatformRef(gdk_cursor_new(GDK_FLEUR));
break;
case Cursor::EastResize:
case Cursor::EastPanning:
- m_platformCursor = adoptGRef(gdk_cursor_new(GDK_RIGHT_SIDE));
+ m_platformCursor = adoptPlatformRef(gdk_cursor_new(GDK_RIGHT_SIDE));
break;
case Cursor::NorthResize:
case Cursor::NorthPanning:
- m_platformCursor = adoptGRef(gdk_cursor_new(GDK_TOP_SIDE));
+ m_platformCursor = adoptPlatformRef(gdk_cursor_new(GDK_TOP_SIDE));
break;
case Cursor::NorthEastResize:
case Cursor::NorthEastPanning:
- m_platformCursor = adoptGRef(gdk_cursor_new(GDK_LEFT_SIDE));
+ m_platformCursor = adoptPlatformRef(gdk_cursor_new(GDK_LEFT_SIDE));
break;
case Cursor::NorthWestResize:
case Cursor::NorthWestPanning:
- m_platformCursor = adoptGRef(gdk_cursor_new(GDK_TOP_LEFT_CORNER));
+ m_platformCursor = adoptPlatformRef(gdk_cursor_new(GDK_TOP_LEFT_CORNER));
break;
case Cursor::SouthResize:
case Cursor::SouthPanning:
- m_platformCursor = adoptGRef(gdk_cursor_new(GDK_BOTTOM_SIDE));
+ m_platformCursor = adoptPlatformRef(gdk_cursor_new(GDK_BOTTOM_SIDE));
break;
case Cursor::SouthEastResize:
case Cursor::SouthEastPanning:
- m_platformCursor = adoptGRef(gdk_cursor_new(GDK_BOTTOM_RIGHT_CORNER));
+ m_platformCursor = adoptPlatformRef(gdk_cursor_new(GDK_BOTTOM_RIGHT_CORNER));
break;
case Cursor::SouthWestResize:
case Cursor::SouthWestPanning:
- m_platformCursor = adoptGRef(gdk_cursor_new(GDK_BOTTOM_LEFT_CORNER));
+ m_platformCursor = adoptPlatformRef(gdk_cursor_new(GDK_BOTTOM_LEFT_CORNER));
break;
case Cursor::WestResize:
- m_platformCursor = adoptGRef(gdk_cursor_new(GDK_LEFT_SIDE));
+ m_platformCursor = adoptPlatformRef(gdk_cursor_new(GDK_LEFT_SIDE));
break;
case Cursor::NorthSouthResize:
- m_platformCursor = adoptGRef(gdk_cursor_new(GDK_TOP_TEE));
+ m_platformCursor = adoptPlatformRef(gdk_cursor_new(GDK_TOP_TEE));
break;
case Cursor::EastWestResize:
case Cursor::WestPanning:
- m_platformCursor = adoptGRef(gdk_cursor_new(GDK_LEFT_SIDE));
+ m_platformCursor = adoptPlatformRef(gdk_cursor_new(GDK_LEFT_SIDE));
break;
case Cursor::NorthEastSouthWestResize:
case Cursor::NorthWestSouthEastResize:
- m_platformCursor = adoptGRef(gdk_cursor_new(GDK_SIZING));
+ m_platformCursor = adoptPlatformRef(gdk_cursor_new(GDK_SIZING));
break;
case Cursor::ColumnResize:
- m_platformCursor = adoptGRef(gdk_cursor_new(GDK_SB_H_DOUBLE_ARROW));
+ m_platformCursor = adoptPlatformRef(gdk_cursor_new(GDK_SB_H_DOUBLE_ARROW));
break;
case Cursor::RowResize:
- m_platformCursor = adoptGRef(gdk_cursor_new(GDK_SB_V_DOUBLE_ARROW));
+ m_platformCursor = adoptPlatformRef(gdk_cursor_new(GDK_SB_V_DOUBLE_ARROW));
break;
case Cursor::VerticalText:
m_platformCursor = createNamedCursor(CustomCursorVerticalText);
break;
case Cursor::Cell:
- m_platformCursor = adoptGRef(gdk_cursor_new(GDK_PLUS));
+ m_platformCursor = adoptPlatformRef(gdk_cursor_new(GDK_PLUS));
break;
case Cursor::ContextMenu:
m_platformCursor = createNamedCursor(CustomCursorContextMenu);
diff --git a/WebCore/platform/gtk/CursorGtk.h b/WebCore/platform/gtk/CursorGtk.h
index 85aaefa..568919b 100644
--- a/WebCore/platform/gtk/CursorGtk.h
+++ b/WebCore/platform/gtk/CursorGtk.h
@@ -47,7 +47,7 @@
*/
/* MOZ_CURSOR_VERTICAL_TEXT */
-static const char moz_vertical_text_bits[] = {
+static const unsigned char moz_vertical_text_bits[] = {
0x00, 0x00, 0x00, 0x00, 0x02, 0x40, 0x00, 0x00, 0x02, 0x40, 0x00, 0x00,
0x06, 0x60, 0x00, 0x00, 0xfc, 0x3f, 0x00, 0x00, 0x06, 0x60, 0x00, 0x00,
0x02, 0x40, 0x00, 0x00, 0x02, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
@@ -60,7 +60,7 @@ static const char moz_vertical_text_bits[] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
-static const char moz_vertical_text_mask_bits[] = {
+static const unsigned char moz_vertical_text_mask_bits[] = {
0x07, 0xe0, 0x00, 0x00, 0x07, 0xe0, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00,
0xff, 0xff, 0x00, 0x00, 0xfe, 0x7f, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00,
0x0f, 0xf0, 0x00, 0x00, 0x07, 0xe0, 0x00, 0x00, 0x07, 0xe0, 0x00, 0x00,
@@ -74,7 +74,7 @@ static const char moz_vertical_text_mask_bits[] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
/* MOZ_CURSOR_CONTEXT_MENU */
-static const char moz_menu_bits[] = {
+static const unsigned char moz_menu_bits[] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
0x0c, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x00,
0x7c, 0x00, 0x00, 0x00, 0xfc, 0x00, 0x00, 0x00, 0xfc, 0xfd, 0x00, 0x00,
@@ -87,7 +87,7 @@ static const char moz_menu_bits[] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
-static const char moz_menu_mask_bits[] = {
+static const unsigned char moz_menu_mask_bits[] = {
0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00,
0x1e, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x00, 0x00, 0x7e, 0x00, 0x00, 0x00,
0xfe, 0x00, 0x00, 0x00, 0xfe, 0xfd, 0x00, 0x00, 0xfe, 0xff, 0x01, 0x00,
@@ -101,7 +101,7 @@ static const char moz_menu_mask_bits[] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
/* MOZ_CURSOR_COPY */
-static const char moz_copy_bits[] = {
+static const unsigned char moz_copy_bits[] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
0x0c, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x00,
0x7c, 0x00, 0x00, 0x00, 0xfc, 0x00, 0x00, 0x00, 0xfc, 0x01, 0x00, 0x00,
@@ -114,7 +114,7 @@ static const char moz_copy_bits[] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
-static const char moz_copy_mask_bits[] = {
+static const unsigned char moz_copy_mask_bits[] = {
0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00,
0x1e, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x00, 0x00, 0x7e, 0x00, 0x00, 0x00,
0xfe, 0x00, 0x00, 0x00, 0xfe, 0x01, 0x00, 0x00, 0xfe, 0x03, 0x00, 0x00,
@@ -128,7 +128,7 @@ static const char moz_copy_mask_bits[] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
/* MOZ_CURSOR_ALIAS */
-static const char moz_alias_bits[] = {
+static const unsigned char moz_alias_bits[] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
0x0c, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x00,
0x7c, 0x00, 0x00, 0x00, 0xfc, 0x00, 0x00, 0x00, 0xfc, 0x01, 0x00, 0x00,
@@ -141,7 +141,7 @@ static const char moz_alias_bits[] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
-static const char moz_alias_mask_bits[] = {
+static const unsigned char moz_alias_mask_bits[] = {
0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00,
0x1e, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x00, 0x00, 0x7e, 0x00, 0x00, 0x00,
0xfe, 0x00, 0x00, 0x00, 0xfe, 0x01, 0x00, 0x00, 0xfe, 0x03, 0x00, 0x00,
@@ -155,7 +155,7 @@ static const char moz_alias_mask_bits[] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
/* MOZ_CURSOR_ZOOM_IN */
-static const char moz_zoom_in_bits[] = {
+static const unsigned char moz_zoom_in_bits[] = {
0xf0, 0x00, 0x00, 0x00, 0x0c, 0x03, 0x00, 0x00, 0x02, 0x04, 0x00, 0x00,
0x62, 0x04, 0x00, 0x00, 0x61, 0x08, 0x00, 0x00, 0xf9, 0x09, 0x00, 0x00,
0xf9, 0x09, 0x00, 0x00, 0x61, 0x08, 0x00, 0x00, 0x62, 0x04, 0x00, 0x00,
@@ -168,7 +168,7 @@ static const char moz_zoom_in_bits[] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
-static const char moz_zoom_in_mask_bits[] = {
+static const unsigned char moz_zoom_in_mask_bits[] = {
0xf0, 0x00, 0x00, 0x00, 0xfc, 0x03, 0x00, 0x00, 0xfe, 0x07, 0x00, 0x00,
0xfe, 0x07, 0x00, 0x00, 0xff, 0x0f, 0x00, 0x00, 0xff, 0x0f, 0x00, 0x00,
0xff, 0x0f, 0x00, 0x00, 0xff, 0x0f, 0x00, 0x00, 0xfe, 0x07, 0x00, 0x00,
@@ -182,7 +182,7 @@ static const char moz_zoom_in_mask_bits[] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
/* MOZ_CURSOR_ZOOM_OUT */
-static const char moz_zoom_out_bits[] = {
+static const unsigned char moz_zoom_out_bits[] = {
0xf0, 0x00, 0x00, 0x00, 0x0c, 0x03, 0x00, 0x00, 0x02, 0x04, 0x00, 0x00,
0x02, 0x04, 0x00, 0x00, 0x01, 0x08, 0x00, 0x00, 0xf9, 0x09, 0x00, 0x00,
0xf9, 0x09, 0x00, 0x00, 0x01, 0x08, 0x00, 0x00, 0x02, 0x04, 0x00, 0x00,
@@ -195,7 +195,7 @@ static const char moz_zoom_out_bits[] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
-static const char moz_zoom_out_mask_bits[] = {
+static const unsigned char moz_zoom_out_mask_bits[] = {
0xf0, 0x00, 0x00, 0x00, 0xfc, 0x03, 0x00, 0x00, 0xfe, 0x07, 0x00, 0x00,
0xfe, 0x07, 0x00, 0x00, 0xff, 0x0f, 0x00, 0x00, 0xff, 0x0f, 0x00, 0x00,
0xff, 0x0f, 0x00, 0x00, 0xff, 0x0f, 0x00, 0x00, 0xfe, 0x07, 0x00, 0x00,
@@ -209,7 +209,7 @@ static const char moz_zoom_out_mask_bits[] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
/* MOZ_CURSOR_NOT_ALLOWED */
-static const char moz_not_allowed_bits[] = {
+static const unsigned char moz_not_allowed_bits[] = {
0x00, 0x00, 0x00, 0x00, 0x80, 0x1f, 0x00, 0x00, 0xe0, 0x7f, 0x00, 0x00,
0xf0, 0xf0, 0x00, 0x00, 0x38, 0xc0, 0x01, 0x00, 0x7c, 0x80, 0x03, 0x00,
0xec, 0x00, 0x03, 0x00, 0xce, 0x01, 0x07, 0x00, 0x86, 0x03, 0x06, 0x00,
@@ -222,7 +222,7 @@ static const char moz_not_allowed_bits[] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
-static const char moz_not_allowed_mask_bits[] = {
+static const unsigned char moz_not_allowed_mask_bits[] = {
0x80, 0x1f, 0x00, 0x00, 0xe0, 0x7f, 0x00, 0x00, 0xf0, 0xff, 0x00, 0x00,
0xf8, 0xff, 0x01, 0x00, 0xfc, 0xf0, 0x03, 0x00, 0xfe, 0xc0, 0x07, 0x00,
0xfe, 0x81, 0x07, 0x00, 0xff, 0x83, 0x0f, 0x00, 0xcf, 0x07, 0x0f, 0x00,
@@ -236,7 +236,7 @@ static const char moz_not_allowed_mask_bits[] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
/* MOZ_CURSOR_SPINNING */
-static const char moz_spinning_bits[] = {
+static const unsigned char moz_spinning_bits[] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
0x0c, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x00,
0x7c, 0x00, 0x00, 0x00, 0xfc, 0x00, 0x00, 0x00, 0xfc, 0x01, 0x00, 0x00,
@@ -249,7 +249,7 @@ static const char moz_spinning_bits[] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
-static const char moz_spinning_mask_bits[] = {
+static const unsigned char moz_spinning_mask_bits[] = {
0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00,
0x1e, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x00, 0x00, 0x7e, 0x00, 0x00, 0x00,
0xfe, 0x00, 0x00, 0x00, 0xfe, 0x01, 0x00, 0x00, 0xfe, 0x3b, 0x00, 0x00,
@@ -263,7 +263,7 @@ static const char moz_spinning_mask_bits[] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
/* MOZ_CURSOR_NONE */
-static const char moz_none_bits[] = {
+static const unsigned char moz_none_bits[] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
@@ -276,7 +276,7 @@ static const char moz_none_bits[] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
-static const char moz_none_mask_bits[] = {
+static const unsigned char moz_none_mask_bits[] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
@@ -290,7 +290,7 @@ static const char moz_none_mask_bits[] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
/* MOZ_CURSOR_HAND_GRAB */
-static const char moz_hand_grab_bits[] = {
+static const unsigned char moz_hand_grab_bits[] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00,
0x60, 0x39, 0x00, 0x00, 0x90, 0x49, 0x00, 0x00, 0x90, 0x49, 0x01, 0x00,
0x20, 0xc9, 0x02, 0x00, 0x20, 0x49, 0x02, 0x00, 0x58, 0x40, 0x02, 0x00,
@@ -303,7 +303,7 @@ static const char moz_hand_grab_bits[] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
-static const char moz_hand_grab_mask_bits[] = {
+static const unsigned char moz_hand_grab_mask_bits[] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x60, 0x3f, 0x00, 0x00,
0xf0, 0x7f, 0x00, 0x00, 0xf8, 0xff, 0x01, 0x00, 0xf8, 0xff, 0x03, 0x00,
0xf0, 0xff, 0x07, 0x00, 0xf8, 0xff, 0x07, 0x00, 0xfc, 0xff, 0x07, 0x00,
@@ -317,7 +317,7 @@ static const char moz_hand_grab_mask_bits[] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
/* MOZ_CURSOR_HAND_GRABBING */
-static const char moz_hand_grabbing_bits[] = {
+static const unsigned char moz_hand_grabbing_bits[] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0xc0, 0x36, 0x00, 0x00, 0x20, 0xc9, 0x00, 0x00, 0x20, 0x40, 0x01, 0x00,
@@ -330,7 +330,7 @@ static const char moz_hand_grabbing_bits[] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
-static const char moz_hand_grabbing_mask_bits[] = {
+static const unsigned char moz_hand_grabbing_mask_bits[] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x36, 0x00, 0x00,
0xe0, 0xff, 0x00, 0x00, 0xf0, 0xff, 0x01, 0x00, 0xf0, 0xff, 0x03, 0x00,
@@ -359,8 +359,8 @@ enum CustomCursorType {
typedef struct {
const char* name;
- const char* bits;
- const char* mask_bits;
+ const unsigned char* bits;
+ const unsigned char* mask_bits;
int hot_x;
int hot_y;
} CustomCursor;
@@ -374,7 +374,7 @@ static const CustomCursor CustomCursors[] = {
{ "zoom-out", moz_zoom_out_bits, moz_zoom_out_mask_bits, 6, 6 },
{ "vertical-text", moz_vertical_text_bits, moz_vertical_text_mask_bits, 8, 4 },
{ "dnd-no-drop", moz_not_allowed_bits, moz_not_allowed_mask_bits, 9, 9 },
- { "progress", moz_spinning_bits, moz_spinning_mask_bits, 2, 2},
+ { "left_ptr_watch", moz_spinning_bits, moz_spinning_mask_bits, 2, 2},
{ "none", moz_none_bits, moz_none_mask_bits, 0, 0 },
{ "grab", moz_hand_grab_bits, moz_hand_grab_mask_bits, 10, 10 },
{ "grabbing", moz_hand_grabbing_bits, moz_hand_grabbing_mask_bits, 10, 10 }
diff --git a/WebCore/platform/gtk/DataObjectGtk.h b/WebCore/platform/gtk/DataObjectGtk.h
index a7d8baf..6f7149c 100644
--- a/WebCore/platform/gtk/DataObjectGtk.h
+++ b/WebCore/platform/gtk/DataObjectGtk.h
@@ -73,8 +73,8 @@ private:
String m_text;
String m_markup;
Vector<KURL> m_uriList;
- GRefPtr<GdkPixbuf> m_image;
- GRefPtr<GdkDragContext> m_dragContext;
+ PlatformRefPtr<GdkPixbuf> m_image;
+ PlatformRefPtr<GdkDragContext> m_dragContext;
RefPtr<Range> m_range;
};
diff --git a/WebCore/platform/gtk/GRefPtrGtk.cpp b/WebCore/platform/gtk/GRefPtrGtk.cpp
index 6647b99..83129cc 100644
--- a/WebCore/platform/gtk/GRefPtrGtk.cpp
+++ b/WebCore/platform/gtk/GRefPtrGtk.cpp
@@ -25,27 +25,27 @@
namespace WTF {
-template <> GtkTargetList* refGPtr(GtkTargetList* ptr)
+template <> GtkTargetList* refPlatformPtr(GtkTargetList* ptr)
{
if (ptr)
gtk_target_list_ref(ptr);
return ptr;
}
-template <> void derefGPtr(GtkTargetList* ptr)
+template <> void derefPlatformPtr(GtkTargetList* ptr)
{
if (ptr)
gtk_target_list_unref(ptr);
}
-template <> GdkCursor* refGPtr(GdkCursor* ptr)
+template <> GdkCursor* refPlatformPtr(GdkCursor* ptr)
{
if (ptr)
gdk_cursor_ref(ptr);
return ptr;
}
-template <> void derefGPtr(GdkCursor* ptr)
+template <> void derefPlatformPtr(GdkCursor* ptr)
{
if (ptr)
gdk_cursor_unref(ptr);
diff --git a/WebCore/platform/gtk/GRefPtrGtk.h b/WebCore/platform/gtk/GRefPtrGtk.h
index 77941f5..ea1b089 100644
--- a/WebCore/platform/gtk/GRefPtrGtk.h
+++ b/WebCore/platform/gtk/GRefPtrGtk.h
@@ -28,11 +28,11 @@ typedef struct _GdkCursor GdkCursor;
namespace WTF {
-template <> GtkTargetList* refGPtr(GtkTargetList* ptr);
-template <> void derefGPtr(GtkTargetList* ptr);
+template <> GtkTargetList* refPlatformPtr(GtkTargetList* ptr);
+template <> void derefPlatformPtr(GtkTargetList* ptr);
-template <> GdkCursor* refGPtr(GdkCursor* ptr);
-template <> void derefGPtr(GdkCursor* ptr);
+template <> GdkCursor* refPlatformPtr(GdkCursor* ptr);
+template <> void derefPlatformPtr(GdkCursor* ptr);
}
diff --git a/WebCore/platform/gtk/GtkVersioning.h b/WebCore/platform/gtk/GtkVersioning.h
index 6b45228..34e6081 100644
--- a/WebCore/platform/gtk/GtkVersioning.h
+++ b/WebCore/platform/gtk/GtkVersioning.h
@@ -47,6 +47,8 @@
#define gtk_widget_set_visible(widget, FALSE) GTK_WIDGET_UNSET_FLAGS((widget), GTK_VISIBLE)
#define gtk_widget_set_window(widget, new_window) (widget)->window = (new_window)
#define gtk_widget_set_can_focus(widget, TRUE) GTK_WIDGET_SET_FLAGS((widget), GTK_CAN_FOCUS)
+#define gtk_widget_get_allocation(widget, alloc) (*(alloc) = (widget)->allocation)
+#define gtk_widget_set_allocation(widget, alloc) ((widget)->allocation = *(alloc))
#endif // GTK_CHECK_VERSION(2, 18, 0)
#if !GTK_CHECK_VERSION(2, 14, 0)
diff --git a/WebCore/platform/gtk/PasteboardGtk.cpp b/WebCore/platform/gtk/PasteboardGtk.cpp
index a0069cf..ddb9768 100644
--- a/WebCore/platform/gtk/PasteboardGtk.cpp
+++ b/WebCore/platform/gtk/PasteboardGtk.cpp
@@ -103,7 +103,7 @@ void Pasteboard::writeImage(Node* node, const KURL&, const String&)
Image* image = cachedImage->image();
ASSERT(image);
- GRefPtr<GdkPixbuf> pixbuf = adoptGRef(image->getGdkPixbuf());
+ PlatformRefPtr<GdkPixbuf> pixbuf = adoptPlatformRef(image->getGdkPixbuf());
DataObjectGtk* dataObject = DataObjectGtk::forClipboard(clipboard);
dataObject->setImage(pixbuf.get());
m_helper->writeClipboardContents(clipboard);
diff --git a/WebCore/platform/gtk/PasteboardHelper.cpp b/WebCore/platform/gtk/PasteboardHelper.cpp
index 2babe91..95df25f 100644
--- a/WebCore/platform/gtk/PasteboardHelper.cpp
+++ b/WebCore/platform/gtk/PasteboardHelper.cpp
@@ -245,7 +245,7 @@ Vector<GdkAtom> PasteboardHelper::dropAtomsForContext(GtkWidget* widget, GdkDrag
dropAtoms.append(netscapeURLAtom);
// For images, try to find the most applicable image type.
- GRefPtr<GtkTargetList> list(gtk_target_list_new(0, 0));
+ PlatformRefPtr<GtkTargetList> list(gtk_target_list_new(0, 0));
gtk_target_list_add_image_targets(list.get(), getIdForTargetType(TargetTypeImage), TRUE);
GdkAtom atom = gtk_drag_dest_find_target(widget, context, list.get());
if (atom != GDK_NONE)
diff --git a/WebCore/platform/gtk/PopupMenuGtk.h b/WebCore/platform/gtk/PopupMenuGtk.h
index fb4e7dd..d63e6d9 100644
--- a/WebCore/platform/gtk/PopupMenuGtk.h
+++ b/WebCore/platform/gtk/PopupMenuGtk.h
@@ -58,7 +58,7 @@ private:
PopupMenuClient* m_popupClient;
IntPoint m_menuPosition;
- GRefPtr<GtkMenu> m_popup;
+ PlatformRefPtr<GtkMenu> m_popup;
HashMap<GtkWidget*, int> m_indexMap;
};
diff --git a/WebCore/platform/gtk/RenderThemeGtk.cpp b/WebCore/platform/gtk/RenderThemeGtk.cpp
index 36fccf0..5019f35 100644
--- a/WebCore/platform/gtk/RenderThemeGtk.cpp
+++ b/WebCore/platform/gtk/RenderThemeGtk.cpp
@@ -148,7 +148,7 @@ RenderThemeGtk::RenderThemeGtk()
, m_pauseButton(0)
, m_seekBackButton(0)
, m_seekForwardButton(0)
- , m_partsTable(adoptGRef(g_hash_table_new_full(0, 0, 0, g_free)))
+ , m_partsTable(adoptPlatformRef(g_hash_table_new_full(0, 0, 0, g_free)))
{
if (!mozGtkRefCount) {
moz_gtk_init();
@@ -317,7 +317,7 @@ static bool paintMozillaGtkWidget(const RenderThemeGtk* theme, GtkThemeWidgetTyp
else if (type == MOZ_GTK_CHECKBUTTON || type == MOZ_GTK_RADIOBUTTON)
flags = theme->isChecked(o);
- GRefPtr<GdkDrawable> drawable(i.context->gdkDrawable());
+ PlatformRefPtr<GdkDrawable> drawable(i.context->gdkDrawable());
GdkRectangle paintRect, clipRect;
if (drawable) {
AffineTransform ctm = i.context->getCTM();
@@ -342,7 +342,7 @@ static bool paintMozillaGtkWidget(const RenderThemeGtk* theme, GtkThemeWidgetTyp
// In some situations, like during print previews, this GraphicsContext is not
// backed by a GdkDrawable. In those situations, we render onto a pixmap and then
// copy the rendered data back to the GraphicsContext via Cairo.
- drawable = adoptGRef(gdk_pixmap_new(0, rect.width(), rect.height(), gdk_visual_get_depth(gdk_visual_get_system())));
+ drawable = adoptPlatformRef(gdk_pixmap_new(0, rect.width(), rect.height(), gdk_visual_get_depth(gdk_visual_get_system())));
paintRect = clipRect = IntRect(0, 0, rect.width(), rect.height());
}
diff --git a/WebCore/platform/gtk/RenderThemeGtk.h b/WebCore/platform/gtk/RenderThemeGtk.h
index 71338d4..b9c076d 100644
--- a/WebCore/platform/gtk/RenderThemeGtk.h
+++ b/WebCore/platform/gtk/RenderThemeGtk.h
@@ -190,7 +190,7 @@ private:
RefPtr<Image> m_seekBackButton;
RefPtr<Image> m_seekForwardButton;
Page* m_page;
- GRefPtr<GHashTable> m_partsTable;
+ PlatformRefPtr<GHashTable> m_partsTable;
};
diff --git a/WebCore/platform/gtk/ScrollViewGtk.cpp b/WebCore/platform/gtk/ScrollViewGtk.cpp
index 871a0bf..565123c 100644
--- a/WebCore/platform/gtk/ScrollViewGtk.cpp
+++ b/WebCore/platform/gtk/ScrollViewGtk.cpp
@@ -65,12 +65,20 @@ void ScrollView::platformDestroy()
PassRefPtr<Scrollbar> ScrollView::createScrollbar(ScrollbarOrientation orientation)
{
- if (orientation == HorizontalScrollbar && m_horizontalAdjustment)
- return ScrollbarGtk::createScrollbar(this, orientation, m_horizontalAdjustment);
- else if (orientation == VerticalScrollbar && m_verticalAdjustment)
- return ScrollbarGtk::createScrollbar(this, orientation, m_verticalAdjustment);
- else
+ // If this is an interior frame scrollbar, we want to create a scrollbar without
+ // passing a GtkAdjustment. This will cause the Scrollbar to create a native GTK+
+ // scrollbar.
+ if (parent())
return Scrollbar::createNativeScrollbar(this, orientation, RegularScrollbar);
+
+ // If this is the main frame, we want to create a Scrollbar that does no painting
+ // and defers to our GtkAdjustment for all of its state. Note that the GtkAdjustment
+ // may be null here.
+ if (orientation == HorizontalScrollbar)
+ return ScrollbarGtk::createScrollbar(this, orientation, m_horizontalAdjustment);
+
+ // VerticalScrollbar
+ return ScrollbarGtk::createScrollbar(this, orientation, m_verticalAdjustment);
}
/*
diff --git a/WebCore/platform/gtk/ScrollbarGtk.cpp b/WebCore/platform/gtk/ScrollbarGtk.cpp
index 3b86ec9..8a1c4fa 100644
--- a/WebCore/platform/gtk/ScrollbarGtk.cpp
+++ b/WebCore/platform/gtk/ScrollbarGtk.cpp
@@ -81,8 +81,10 @@ ScrollbarGtk::ScrollbarGtk(ScrollbarClient* client, ScrollbarOrientation orienta
: Scrollbar(client, orientation, RegularScrollbar)
, m_adjustment(adjustment)
{
- g_object_ref(m_adjustment);
- g_signal_connect(m_adjustment, "value-changed", G_CALLBACK(ScrollbarGtk::gtkValueChanged), this);
+ if (m_adjustment) {
+ g_object_ref(m_adjustment);
+ g_signal_connect(m_adjustment, "value-changed", G_CALLBACK(ScrollbarGtk::gtkValueChanged), this);
+ }
// We have nothing to show as we are solely operating on the GtkAdjustment
resize(0, 0);
@@ -104,8 +106,10 @@ void ScrollbarGtk::attachAdjustment(GtkAdjustment* adjustment)
m_adjustment = adjustment;
- g_object_ref(m_adjustment);
- g_signal_connect(m_adjustment, "value-changed", G_CALLBACK(ScrollbarGtk::gtkValueChanged), this);
+ if (m_adjustment) {
+ g_object_ref(m_adjustment);
+ g_signal_connect(m_adjustment, "value-changed", G_CALLBACK(ScrollbarGtk::gtkValueChanged), this);
+ }
updateThumbProportion();
updateThumbPosition();
@@ -156,12 +160,18 @@ void ScrollbarGtk::frameRectsChanged()
void ScrollbarGtk::updateThumbPosition()
{
+ if (!m_adjustment)
+ return;
+
if (gtk_adjustment_get_value(m_adjustment) != m_currentPos)
gtk_adjustment_set_value(m_adjustment, m_currentPos);
}
void ScrollbarGtk::updateThumbProportion()
{
+ if (!m_adjustment)
+ return;
+
gtk_adjustment_configure(m_adjustment,
gtk_adjustment_get_value(m_adjustment),
gtk_adjustment_get_lower(m_adjustment),
diff --git a/WebCore/platform/gtk/gtk2drawing.c b/WebCore/platform/gtk/gtk2drawing.c
index 80e2c2a..349bde0 100644
--- a/WebCore/platform/gtk/gtk2drawing.c
+++ b/WebCore/platform/gtk/gtk2drawing.c
@@ -732,6 +732,7 @@ ConvertGtkState(GtkWidgetState* state)
return GTK_STATE_NORMAL;
}
+#ifdef GTK_API_VERSION_2
static gint
TSOffsetStyleGCArray(GdkGC** gcs, gint xorigin, gint yorigin)
{
@@ -741,10 +742,12 @@ TSOffsetStyleGCArray(GdkGC** gcs, gint xorigin, gint yorigin)
gdk_gc_set_ts_origin(gcs[i], xorigin, yorigin);
return MOZ_GTK_SUCCESS;
}
+#endif
static gint
TSOffsetStyleGCs(GtkStyle* style, gint xorigin, gint yorigin)
{
+#ifdef GTK_API_VERSION_2
TSOffsetStyleGCArray(style->fg_gc, xorigin, yorigin);
TSOffsetStyleGCArray(style->bg_gc, xorigin, yorigin);
TSOffsetStyleGCArray(style->light_gc, xorigin, yorigin);
@@ -754,6 +757,7 @@ TSOffsetStyleGCs(GtkStyle* style, gint xorigin, gint yorigin)
TSOffsetStyleGCArray(style->base_gc, xorigin, yorigin);
gdk_gc_set_ts_origin(style->black_gc, xorigin, yorigin);
gdk_gc_set_ts_origin(style->white_gc, xorigin, yorigin);
+#endif
return MOZ_GTK_SUCCESS;
}
@@ -1094,6 +1098,34 @@ calculate_arrow_rect(GtkWidget* arrow, GdkRectangle* rect,
}
static gint
+moz_gtk_scrolled_window_paint(GdkDrawable* drawable, GdkRectangle* rect,
+ GdkRectangle* cliprect, GtkWidgetState* state)
+{
+ GtkStateType state_type = ConvertGtkState(state);
+ GtkShadowType shadow_type = (state->active) ? GTK_SHADOW_IN : GTK_SHADOW_OUT;
+ GtkStyle* style;
+ GtkAllocation allocation;
+ GtkWidget* widget;
+
+ ensure_scrolled_window_widget();
+ widget = gParts->scrolledWindowWidget;
+
+ gtk_widget_get_allocation(widget, &allocation);
+ allocation.x = rect->x;
+ allocation.y = rect->y;
+ allocation.width = rect->width;
+ allocation.height = rect->height;
+ gtk_widget_set_allocation(widget, &allocation);
+
+ style = gtk_widget_get_style(widget);
+ TSOffsetStyleGCs(style, rect->x - 1, rect->y - 1);
+ gtk_paint_box(style, drawable, state_type, shadow_type, cliprect,
+ widget, "scrolled_window", rect->x - 1, rect->y - 1,
+ rect->width + 2, rect->height + 2);
+ return MOZ_GTK_SUCCESS;
+}
+
+static gint
moz_gtk_scrollbar_button_paint(GdkDrawable* drawable, GdkRectangle* rect,
GdkRectangle* cliprect, GtkWidgetState* state,
GtkScrollbarButtonFlags flags,
@@ -1124,11 +1156,7 @@ moz_gtk_scrollbar_button_paint(GdkDrawable* drawable, GdkRectangle* rect,
to determine where it should paint rounded corners on the buttons.
We need to trick them into drawing the buttons the way we want them. */
-#if GTK_CHECK_VERSION(2, 18, 0)
gtk_widget_get_allocation(scrollbar, &allocation);
-#else
- allocation = scrollbar->allocation;
-#endif
allocation.x = rect->x;
allocation.y = rect->y;
allocation.width = rect->width;
@@ -1163,6 +1191,7 @@ moz_gtk_scrollbar_button_paint(GdkDrawable* drawable, GdkRectangle* rect,
}
}
+ gtk_widget_set_allocation(scrollbar, &allocation);
style = gtk_widget_get_style(scrollbar);
TSOffsetStyleGCs(style, rect->x, rect->y);
@@ -1214,10 +1243,6 @@ moz_gtk_scrollbar_trough_paint(GtkThemeWidgetType widget,
style = gtk_widget_get_style(GTK_WIDGET(scrollbar));
TSOffsetStyleGCs(style, rect->x, rect->y);
- gtk_style_apply_default_background(style, drawable, TRUE, GTK_STATE_ACTIVE,
- cliprect, rect->x, rect->y,
- rect->width, rect->height);
-
gtk_paint_box(style, drawable, GTK_STATE_ACTIVE, GTK_SHADOW_IN, cliprect,
GTK_WIDGET(scrollbar), "trough", rect->x, rect->y,
rect->width, rect->height);
@@ -1557,8 +1582,17 @@ moz_gtk_entry_paint(GdkDrawable* drawable, GdkRectangle* rect,
if (theme_honors_transparency) {
g_object_set_data(G_OBJECT(widget), "transparent-bg-hint", GINT_TO_POINTER(TRUE));
} else {
+#ifndef GTK_API_VERSION_2
+ cairo_t* cr = gdk_cairo_create(drawable);
+ gdk_cairo_set_source_color(cr, (const GdkColor*)&style->base[bg_state]);
+ cairo_pattern_set_extend (cairo_get_source(cr), CAIRO_EXTEND_REPEAT);
+ gdk_cairo_rectangle(cr, cliprect);
+ cairo_fill(cr);
+ cairo_destroy(cr);
+#else
gdk_draw_rectangle(drawable, style->base_gc[bg_state], TRUE,
cliprect->x, cliprect->y, cliprect->width, cliprect->height);
+#endif
g_object_set_data(G_OBJECT(widget), "transparent-bg-hint", GINT_TO_POINTER(FALSE));
}
@@ -3047,6 +3081,7 @@ moz_gtk_get_scrollbar_metrics(MozGtkScrollbarMetrics *metrics)
"trough_border", &metrics->trough_border,
"stepper_size", &metrics->stepper_size,
"stepper_spacing", &metrics->stepper_spacing,
+ "trough_under_steppers", &metrics->trough_under_steppers,
NULL);
metrics->min_slider_size = gtk_range_get_min_slider_size(GTK_RANGE(gParts->horizScrollbarWidget));
@@ -3109,6 +3144,9 @@ moz_gtk_widget_paint(GtkThemeWidgetType widget, GdkDrawable* drawable,
return moz_gtk_scrollbar_thumb_paint(widget, drawable, rect,
cliprect, state, direction);
break;
+ case MOZ_GTK_SCROLLED_WINDOW:
+ return moz_gtk_scrolled_window_paint(drawable, rect, cliprect, state);
+ break;
case MOZ_GTK_SCALE_HORIZONTAL:
case MOZ_GTK_SCALE_VERTICAL:
return moz_gtk_scale_paint(drawable, rect, cliprect, state,
diff --git a/WebCore/platform/gtk/gtkdrawing.h b/WebCore/platform/gtk/gtkdrawing.h
index b5a7feb..9d06d5d 100644
--- a/WebCore/platform/gtk/gtkdrawing.h
+++ b/WebCore/platform/gtk/gtkdrawing.h
@@ -75,6 +75,7 @@ typedef struct {
gint stepper_size;
gint stepper_spacing;
gint min_slider_size;
+ gboolean trough_under_steppers;
} MozGtkScrollbarMetrics;
typedef struct _GtkThemeParts {
@@ -180,6 +181,8 @@ typedef enum {
/* Paints the slider (thumb) of a GtkScrollbar. */
MOZ_GTK_SCROLLBAR_THUMB_HORIZONTAL,
MOZ_GTK_SCROLLBAR_THUMB_VERTICAL,
+ /* Paints the background of a scrolled window */
+ MOZ_GTK_SCROLLED_WINDOW,
/* Paints a GtkScale. */
MOZ_GTK_SCALE_HORIZONTAL,
MOZ_GTK_SCALE_VERTICAL,
diff --git a/WebCore/platform/image-decoders/ImageDecoder.cpp b/WebCore/platform/image-decoders/ImageDecoder.cpp
index 1946596..d4518fe 100644
--- a/WebCore/platform/image-decoders/ImageDecoder.cpp
+++ b/WebCore/platform/image-decoders/ImageDecoder.cpp
@@ -52,11 +52,15 @@ static unsigned copyFromSharedBuffer(char* buffer, unsigned bufferLength, const
return bytesExtracted;
}
+<<<<<<< HEAD
#if !OS(ANDROID)
// This method requires BMPImageDecoder, PNGImageDecoder, ICOImageDecoder and
// JPEGDecoder, which aren't used on Android, and which don't all compile.
// TODO: Find a better fix.
ImageDecoder* ImageDecoder::create(const SharedBuffer& data)
+=======
+ImageDecoder* ImageDecoder::create(const SharedBuffer& data, bool premultiplyAlpha)
+>>>>>>> webkit.org at r66079
{
// We need at least 4 bytes to figure out what kind of image we're dealing
// with.
@@ -68,24 +72,24 @@ ImageDecoder* ImageDecoder::create(const SharedBuffer& data)
// GIFs begin with GIF8(7 or 9).
if (strncmp(contents, "GIF8", 4) == 0)
- return new GIFImageDecoder();
+ return new GIFImageDecoder(premultiplyAlpha);
// Test for PNG.
if (!memcmp(contents, "\x89\x50\x4E\x47", 4))
- return new PNGImageDecoder();
+ return new PNGImageDecoder(premultiplyAlpha);
// JPEG
if (!memcmp(contents, "\xFF\xD8\xFF", 3))
- return new JPEGImageDecoder();
+ return new JPEGImageDecoder(premultiplyAlpha);
// BMP
if (strncmp(contents, "BM", 2) == 0)
- return new BMPImageDecoder();
+ return new BMPImageDecoder(premultiplyAlpha);
// ICOs always begin with a 2-byte 0 followed by a 2-byte 1.
// CURs begin with 2-byte 0 followed by 2-byte 2.
if (!memcmp(contents, "\x00\x00\x01\x00", 4) || !memcmp(contents, "\x00\x00\x02\x00", 4))
- return new ICOImageDecoder();
+ return new ICOImageDecoder(premultiplyAlpha);
// Give up. We don't know what the heck this is.
return 0;
@@ -99,6 +103,7 @@ RGBA32Buffer::RGBA32Buffer()
, m_status(FrameEmpty)
, m_duration(0)
, m_disposalMethod(DisposeNotSpecified)
+ , m_premultiplyAlpha(true)
{
}
@@ -112,6 +117,7 @@ RGBA32Buffer& RGBA32Buffer::operator=(const RGBA32Buffer& other)
setStatus(other.status());
setDuration(other.duration());
setDisposalMethod(other.disposalMethod());
+ setPremultiplyAlpha(other.premultiplyAlpha());
return *this;
}
diff --git a/WebCore/platform/image-decoders/ImageDecoder.h b/WebCore/platform/image-decoders/ImageDecoder.h
index f32536c..4012168 100644
--- a/WebCore/platform/image-decoders/ImageDecoder.h
+++ b/WebCore/platform/image-decoders/ImageDecoder.h
@@ -124,12 +124,14 @@ namespace WebCore {
FrameStatus status() const { return m_status; }
unsigned duration() const { return m_duration; }
FrameDisposalMethod disposalMethod() const { return m_disposalMethod; }
+ bool premultiplyAlpha() const { return m_premultiplyAlpha; }
void setHasAlpha(bool alpha);
void setRect(const IntRect& r) { m_rect = r; }
void setStatus(FrameStatus status);
void setDuration(unsigned duration) { m_duration = duration; }
void setDisposalMethod(FrameDisposalMethod method) { m_disposalMethod = method; }
+ void setPremultiplyAlpha(bool premultiplyAlpha) { m_premultiplyAlpha = premultiplyAlpha; }
inline void setRGBA(int x, int y, unsigned r, unsigned g, unsigned b, unsigned a)
{
@@ -151,7 +153,7 @@ namespace WebCore {
#elif PLATFORM(QT)
m_image = m_pixmap.toImage();
m_pixmap = QPixmap();
- return reinterpret_cast<QRgb*>(m_image.scanLine(y)) + x;
+ return reinterpret_cast_ptr<QRgb*>(m_image.scanLine(y)) + x;
#else
return m_bytes.data() + (y * width()) + x;
#endif
@@ -159,11 +161,10 @@ namespace WebCore {
inline void setRGBA(PixelData* dest, unsigned r, unsigned g, unsigned b, unsigned a)
{
- // We store this data pre-multiplied.
- if (a == 0)
+ if (m_premultiplyAlpha && !a)
*dest = 0;
else {
- if (a < 255) {
+ if (m_premultiplyAlpha && a < 255) {
float alphaPercent = a / 255.0f;
r = static_cast<unsigned>(r * alphaPercent);
g = static_cast<unsigned>(g * alphaPercent);
@@ -202,6 +203,9 @@ namespace WebCore {
FrameDisposalMethod m_disposalMethod;
// What to do with this frame's data when
// initializing the next frame.
+ bool m_premultiplyAlpha;
+ // Whether to premultiply alpha into R, G, B
+ // channels; by default it's true.
};
// The ImageDecoder class represents a base class for specific image format
@@ -215,8 +219,9 @@ namespace WebCore {
// m_maxNumPixels. (Not supported by all image decoders yet)
class ImageDecoder : public Noncopyable {
public:
- ImageDecoder()
+ ImageDecoder(bool premultiplyAlpha)
: m_scaled(false)
+ , m_premultiplyAlpha(premultiplyAlpha)
, m_sizeAvailable(false)
, m_maxNumPixels(-1)
, m_isAllDataReceived(false)
@@ -229,7 +234,7 @@ namespace WebCore {
// Factory function to create an ImageDecoder. Ports that subclass
// ImageDecoder can provide their own implementation of this to avoid
// needing to write a dedicated setData() implementation.
- static ImageDecoder* create(const SharedBuffer& data);
+ static ImageDecoder* create(const SharedBuffer& data, bool premultiplyAlpha);
// The the filename extension usually associated with an undecoded image
// of this type.
@@ -343,6 +348,7 @@ namespace WebCore {
bool m_scaled;
Vector<int> m_scaledColumns;
Vector<int> m_scaledRows;
+ bool m_premultiplyAlpha;
private:
// Some code paths compute the size of the image as "width * height * 4"
diff --git a/WebCore/platform/image-decoders/bmp/BMPImageDecoder.cpp b/WebCore/platform/image-decoders/bmp/BMPImageDecoder.cpp
index 901f60d..1c117a8 100644
--- a/WebCore/platform/image-decoders/bmp/BMPImageDecoder.cpp
+++ b/WebCore/platform/image-decoders/bmp/BMPImageDecoder.cpp
@@ -40,8 +40,9 @@ namespace WebCore {
// don't pack).
static const size_t sizeOfFileHeader = 14;
-BMPImageDecoder::BMPImageDecoder()
- : m_decodedOffset(0)
+BMPImageDecoder::BMPImageDecoder(bool premultiplyAlpha)
+ : ImageDecoder(premultiplyAlpha)
+ , m_decodedOffset(0)
{
}
@@ -68,8 +69,10 @@ RGBA32Buffer* BMPImageDecoder::frameBufferAtIndex(size_t index)
if (index)
return 0;
- if (m_frameBufferCache.isEmpty())
+ if (m_frameBufferCache.isEmpty()) {
m_frameBufferCache.resize(1);
+ m_frameBufferCache.first().setPremultiplyAlpha(m_premultiplyAlpha);
+ }
RGBA32Buffer* buffer = &m_frameBufferCache.first();
if (buffer->status() != RGBA32Buffer::FrameComplete)
diff --git a/WebCore/platform/image-decoders/bmp/BMPImageDecoder.h b/WebCore/platform/image-decoders/bmp/BMPImageDecoder.h
index b08b32b..3996bf9 100644
--- a/WebCore/platform/image-decoders/bmp/BMPImageDecoder.h
+++ b/WebCore/platform/image-decoders/bmp/BMPImageDecoder.h
@@ -39,7 +39,7 @@ namespace WebCore {
// This class decodes the BMP image format.
class BMPImageDecoder : public ImageDecoder {
public:
- BMPImageDecoder();
+ BMPImageDecoder(bool premultiplyAlpha);
// ImageDecoder
virtual String filenameExtension() const { return "bmp"; }
diff --git a/WebCore/platform/image-decoders/gif/GIFImageDecoder.cpp b/WebCore/platform/image-decoders/gif/GIFImageDecoder.cpp
index ec16da7..a2397ee 100644
--- a/WebCore/platform/image-decoders/gif/GIFImageDecoder.cpp
+++ b/WebCore/platform/image-decoders/gif/GIFImageDecoder.cpp
@@ -29,8 +29,9 @@
namespace WebCore {
-GIFImageDecoder::GIFImageDecoder()
- : m_alreadyScannedThisDataForFrameCount(true)
+GIFImageDecoder::GIFImageDecoder(bool premultiplyAlpha)
+ : ImageDecoder(premultiplyAlpha)
+ , m_alreadyScannedThisDataForFrameCount(true)
, m_repetitionCount(cAnimationLoopOnce)
, m_readOffset(0)
{
@@ -83,6 +84,8 @@ size_t GIFImageDecoder::frameCount()
reader.read((const unsigned char*)m_data->data(), m_data->size(), GIFFrameCountQuery, static_cast<unsigned>(-1));
m_alreadyScannedThisDataForFrameCount = true;
m_frameBufferCache.resize(reader.images_count);
+ for (int i = 0; i < reader.images_count; ++i)
+ m_frameBufferCache[i].setPremultiplyAlpha(m_premultiplyAlpha);
}
return m_frameBufferCache.size();
diff --git a/WebCore/platform/image-decoders/gif/GIFImageDecoder.h b/WebCore/platform/image-decoders/gif/GIFImageDecoder.h
index e0f8173..21c1c57 100644
--- a/WebCore/platform/image-decoders/gif/GIFImageDecoder.h
+++ b/WebCore/platform/image-decoders/gif/GIFImageDecoder.h
@@ -36,7 +36,7 @@ namespace WebCore {
// This class decodes the GIF image format.
class GIFImageDecoder : public ImageDecoder {
public:
- GIFImageDecoder();
+ GIFImageDecoder(bool premultiplyAlpha);
virtual ~GIFImageDecoder();
enum GIFQuery { GIFFullQuery, GIFSizeQuery, GIFFrameCountQuery };
diff --git a/WebCore/platform/image-decoders/ico/ICOImageDecoder.cpp b/WebCore/platform/image-decoders/ico/ICOImageDecoder.cpp
index d667795..453efd2 100644
--- a/WebCore/platform/image-decoders/ico/ICOImageDecoder.cpp
+++ b/WebCore/platform/image-decoders/ico/ICOImageDecoder.cpp
@@ -44,8 +44,9 @@ namespace WebCore {
static const size_t sizeOfDirectory = 6;
static const size_t sizeOfDirEntry = 16;
-ICOImageDecoder::ICOImageDecoder()
- : m_decodedOffset(0)
+ICOImageDecoder::ICOImageDecoder(bool premultiplyAlpha)
+ : ImageDecoder(premultiplyAlpha)
+ , m_decodedOffset(0)
{
}
@@ -96,8 +97,11 @@ bool ICOImageDecoder::setSize(unsigned width, unsigned height)
size_t ICOImageDecoder::frameCount()
{
decode(0, true);
- if (m_frameBufferCache.isEmpty())
+ if (m_frameBufferCache.isEmpty()) {
m_frameBufferCache.resize(m_dirEntries.size());
+ for (size_t i = 0; i < m_dirEntries.size(); ++i)
+ m_frameBufferCache[i].setPremultiplyAlpha(m_premultiplyAlpha);
+ }
// CAUTION: We must not resize m_frameBufferCache again after this, as
// decodeAtIndex() may give a BMPImageReader a pointer to one of the
// entries.
@@ -197,7 +201,7 @@ bool ICOImageDecoder::decodeAtIndex(size_t index)
}
if (!m_pngDecoders[index]) {
- m_pngDecoders[index].set(new PNGImageDecoder());
+ m_pngDecoders[index].set(new PNGImageDecoder(m_premultiplyAlpha));
setDataForPNGDecoderAtIndex(index);
}
// Fail if the size the PNGImageDecoder calculated does not match the size
diff --git a/WebCore/platform/image-decoders/ico/ICOImageDecoder.h b/WebCore/platform/image-decoders/ico/ICOImageDecoder.h
index 48024a2..e2ee9e3 100644
--- a/WebCore/platform/image-decoders/ico/ICOImageDecoder.h
+++ b/WebCore/platform/image-decoders/ico/ICOImageDecoder.h
@@ -40,7 +40,7 @@ namespace WebCore {
// This class decodes the ICO and CUR image formats.
class ICOImageDecoder : public ImageDecoder {
public:
- ICOImageDecoder();
+ ICOImageDecoder(bool premultiplyAlpha);
virtual ~ICOImageDecoder();
// ImageDecoder
diff --git a/WebCore/platform/image-decoders/jpeg/JPEGImageDecoder.cpp b/WebCore/platform/image-decoders/jpeg/JPEGImageDecoder.cpp
index 4911bc9..6c6c782 100644
--- a/WebCore/platform/image-decoders/jpeg/JPEGImageDecoder.cpp
+++ b/WebCore/platform/image-decoders/jpeg/JPEGImageDecoder.cpp
@@ -361,7 +361,8 @@ void term_source(j_decompress_ptr jd)
src->decoder->decoder()->jpegComplete();
}
-JPEGImageDecoder::JPEGImageDecoder()
+JPEGImageDecoder::JPEGImageDecoder(bool premultiplyAlpha)
+ : ImageDecoder(premultiplyAlpha)
{
}
@@ -391,8 +392,10 @@ RGBA32Buffer* JPEGImageDecoder::frameBufferAtIndex(size_t index)
if (index)
return 0;
- if (m_frameBufferCache.isEmpty())
+ if (m_frameBufferCache.isEmpty()) {
m_frameBufferCache.resize(1);
+ m_frameBufferCache[0].setPremultiplyAlpha(m_premultiplyAlpha);
+ }
RGBA32Buffer& frame = m_frameBufferCache[0];
if (frame.status() != RGBA32Buffer::FrameComplete)
diff --git a/WebCore/platform/image-decoders/jpeg/JPEGImageDecoder.h b/WebCore/platform/image-decoders/jpeg/JPEGImageDecoder.h
index 43b35fd..5047019 100644
--- a/WebCore/platform/image-decoders/jpeg/JPEGImageDecoder.h
+++ b/WebCore/platform/image-decoders/jpeg/JPEGImageDecoder.h
@@ -37,7 +37,7 @@ namespace WebCore {
// This class decodes the JPEG image format.
class JPEGImageDecoder : public ImageDecoder {
public:
- JPEGImageDecoder();
+ JPEGImageDecoder(bool premultiplyAlpha);
virtual ~JPEGImageDecoder();
// ImageDecoder
diff --git a/WebCore/platform/image-decoders/png/PNGImageDecoder.cpp b/WebCore/platform/image-decoders/png/PNGImageDecoder.cpp
index 8186f33..940e4c4 100644
--- a/WebCore/platform/image-decoders/png/PNGImageDecoder.cpp
+++ b/WebCore/platform/image-decoders/png/PNGImageDecoder.cpp
@@ -169,8 +169,9 @@ private:
unsigned m_currentBufferSize;
};
-PNGImageDecoder::PNGImageDecoder()
- : m_doNothingOnFailure(false)
+PNGImageDecoder::PNGImageDecoder(bool premultiplyAlpha)
+ : ImageDecoder(premultiplyAlpha)
+ , m_doNothingOnFailure(false)
{
}
@@ -200,8 +201,10 @@ RGBA32Buffer* PNGImageDecoder::frameBufferAtIndex(size_t index)
if (index)
return 0;
- if (m_frameBufferCache.isEmpty())
+ if (m_frameBufferCache.isEmpty()) {
m_frameBufferCache.resize(1);
+ m_frameBufferCache[0].setPremultiplyAlpha(m_premultiplyAlpha);
+ }
RGBA32Buffer& frame = m_frameBufferCache[0];
if (frame.status() != RGBA32Buffer::FrameComplete)
diff --git a/WebCore/platform/image-decoders/png/PNGImageDecoder.h b/WebCore/platform/image-decoders/png/PNGImageDecoder.h
index 145fc4d..763b88f 100644
--- a/WebCore/platform/image-decoders/png/PNGImageDecoder.h
+++ b/WebCore/platform/image-decoders/png/PNGImageDecoder.h
@@ -36,7 +36,7 @@ namespace WebCore {
// This class decodes the PNG image format.
class PNGImageDecoder : public ImageDecoder {
public:
- PNGImageDecoder();
+ PNGImageDecoder(bool premultiplyAlpha);
virtual ~PNGImageDecoder();
// ImageDecoder
diff --git a/WebCore/platform/image-decoders/skia/ImageDecoderSkia.cpp b/WebCore/platform/image-decoders/skia/ImageDecoderSkia.cpp
index 928524a..c7e2114 100644
--- a/WebCore/platform/image-decoders/skia/ImageDecoderSkia.cpp
+++ b/WebCore/platform/image-decoders/skia/ImageDecoderSkia.cpp
@@ -36,6 +36,7 @@ RGBA32Buffer::RGBA32Buffer()
: m_status(FrameEmpty)
, m_duration(0)
, m_disposalMethod(DisposeNotSpecified)
+ , m_premultiplyAlpha(true)
{
}
@@ -52,6 +53,7 @@ RGBA32Buffer& RGBA32Buffer::operator=(const RGBA32Buffer& other)
setStatus(other.status());
setDuration(other.duration());
setDisposalMethod(other.disposalMethod());
+ setPremultiplyAlpha(other.premultiplyAlpha());
return *this;
}
diff --git a/WebCore/platform/mock/SpeechInputClientMock.cpp b/WebCore/platform/mock/SpeechInputClientMock.cpp
index c3d74d1..6b64942 100644
--- a/WebCore/platform/mock/SpeechInputClientMock.cpp
+++ b/WebCore/platform/mock/SpeechInputClientMock.cpp
@@ -50,7 +50,7 @@ void SpeechInputClientMock::setListener(SpeechInputListener* listener)
m_listener = listener;
}
-bool SpeechInputClientMock::startRecognition(int requestId)
+bool SpeechInputClientMock::startRecognition(int requestId, const IntRect&)
{
if (m_timer.isActive())
return false;
diff --git a/WebCore/platform/mock/SpeechInputClientMock.h b/WebCore/platform/mock/SpeechInputClientMock.h
index 7d5fda2..ce83d3b 100644
--- a/WebCore/platform/mock/SpeechInputClientMock.h
+++ b/WebCore/platform/mock/SpeechInputClientMock.h
@@ -50,7 +50,7 @@ public:
// SpeechInputClient methods.
void setListener(SpeechInputListener*);
- bool startRecognition(int);
+ bool startRecognition(int, const IntRect&);
void stopRecording(int);
void cancelRecognition(int);
diff --git a/WebCore/platform/network/BlobData.cpp b/WebCore/platform/network/BlobData.cpp
index bb256d0..21e8917 100644
--- a/WebCore/platform/network/BlobData.cpp
+++ b/WebCore/platform/network/BlobData.cpp
@@ -64,6 +64,11 @@ void BlobData::appendData(const CString& data)
m_items.append(BlobDataItem(data));
}
+void BlobData::appendData(const CString& data, long long offset, long long length)
+{
+ m_items.append(BlobDataItem(data, offset, length));
+}
+
void BlobData::appendFile(const String& path)
{
m_items.append(BlobDataItem(path));
diff --git a/WebCore/platform/network/BlobData.h b/WebCore/platform/network/BlobData.h
index 17cdfdd..13e3b9c 100644
--- a/WebCore/platform/network/BlobData.h
+++ b/WebCore/platform/network/BlobData.h
@@ -45,14 +45,15 @@ struct BlobDataItem {
// Default constructor.
BlobDataItem()
- : offset(0)
+ : type(Data)
+ , offset(0)
, length(toEndOfFile)
, expectedModificationTime(doNotCheckFileChange)
{
}
- // Constructor for String type.
- BlobDataItem(const CString& data)
+ // Constructor for String type (complete string).
+ explicit BlobDataItem(const CString& data)
: type(Data)
, data(data)
, offset(0)
@@ -61,8 +62,18 @@ struct BlobDataItem {
{
}
+ // Constructor for String type (partial string).
+ BlobDataItem(const CString& data, long long offset, long long length)
+ : type(Data)
+ , data(data)
+ , offset(offset)
+ , length(length)
+ , expectedModificationTime(doNotCheckFileChange)
+ {
+ }
+
// Constructor for File type (complete file).
- BlobDataItem(const String& path)
+ explicit BlobDataItem(const String& path)
: type(File)
, path(path)
, offset(0)
@@ -105,11 +116,8 @@ struct BlobDataItem {
// For Blob type.
KURL url;
- // For File and Blob type.
long long offset;
long long length;
-
- // For File type only.
double expectedModificationTime;
};
@@ -140,8 +148,14 @@ public:
void appendBlob(const KURL&, long long offset, long long length);
private:
+ friend class BlobRegistryImpl;
+ friend class BlobStorageData;
+
BlobData() { }
+ // This is only exposed to BlobStorageData.
+ void appendData(const CString&, long long offset, long long length);
+
String m_contentType;
String m_contentDisposition;
BlobDataItemList m_items;
diff --git a/WebCore/platform/network/BlobRegistry.h b/WebCore/platform/network/BlobRegistry.h
index fcd7b1c..7e64233 100644
--- a/WebCore/platform/network/BlobRegistry.h
+++ b/WebCore/platform/network/BlobRegistry.h
@@ -38,6 +38,7 @@
namespace WebCore {
class BlobData;
+class BlobRegistry;
class KURL;
class ResourceError;
class ResourceHandle;
@@ -45,17 +46,23 @@ class ResourceHandleClient;
class ResourceRequest;
class ResourceResponse;
+// Returns a single instance of BlobRegistry.
+BlobRegistry& blobRegistry();
+
// BlobRegistry is not thread-safe. It should only be called from main thread.
class BlobRegistry {
public:
- static BlobRegistry& instance();
-
+ // Registers a blob URL referring to the specified blob data.
virtual void registerBlobURL(const KURL&, PassOwnPtr<BlobData>) = 0;
+
+ // Registers a blob URL referring to the blob data identified by the specified srcURL.
virtual void registerBlobURL(const KURL&, const KURL& srcURL) = 0;
+
virtual void unregisterBlobURL(const KURL&) = 0;
virtual PassRefPtr<ResourceHandle> createResourceHandle(const ResourceRequest&, ResourceHandleClient*) = 0;
virtual bool loadResourceSynchronously(const ResourceRequest&, ResourceError&, ResourceResponse&, Vector<char>& data) = 0;
+protected:
virtual ~BlobRegistry() { }
};
diff --git a/WebCore/platform/network/BlobRegistryImpl.cpp b/WebCore/platform/network/BlobRegistryImpl.cpp
index bbbb8f0..ee872e6 100644
--- a/WebCore/platform/network/BlobRegistryImpl.cpp
+++ b/WebCore/platform/network/BlobRegistryImpl.cpp
@@ -32,9 +32,6 @@
#include "BlobRegistryImpl.h"
-#include "FileStream.h"
-#include "FileStreamProxy.h"
-#include "FileSystem.h"
#include "ResourceError.h"
#include "ResourceHandle.h"
#include "ResourceLoader.h"
@@ -45,6 +42,15 @@
namespace WebCore {
+#if !PLATFORM(CHROMIUM)
+BlobRegistry& blobRegistry()
+{
+ ASSERT(isMainThread());
+ DEFINE_STATIC_LOCAL(BlobRegistryImpl, instance, ());
+ return instance;
+}
+#endif
+
bool BlobRegistryImpl::shouldLoadResource(const ResourceRequest& request) const
{
// If the resource is not fetched using the GET method, bail out.
@@ -72,30 +78,23 @@ bool BlobRegistryImpl::loadResourceSynchronously(const ResourceRequest& request,
return false;
}
-BlobRegistry& BlobRegistry::instance()
-{
- ASSERT(isMainThread());
- DEFINE_STATIC_LOCAL(BlobRegistryImpl, instance, ());
- return instance;
-}
-
-void BlobRegistryImpl::appendStorageItems(BlobStorageData* blobStorageData, const BlobStorageDataItemList& items)
+void BlobRegistryImpl::appendStorageItems(BlobStorageData* blobStorageData, const BlobDataItemList& items)
{
- for (BlobStorageDataItemList::const_iterator iter = items.begin(); iter != items.end(); ++iter) {
- if (iter->type == BlobStorageDataItem::Data)
- blobStorageData->appendData(iter->data, iter->offset, iter->length);
+ for (BlobDataItemList::const_iterator iter = items.begin(); iter != items.end(); ++iter) {
+ if (iter->type == BlobDataItem::Data)
+ blobStorageData->m_data.appendData(iter->data, iter->offset, iter->length);
else {
- ASSERT(iter->type == BlobStorageDataItem::File);
- blobStorageData->appendFile(iter->path, iter->offset, iter->length, iter->expectedModificationTime);
+ ASSERT(iter->type == BlobDataItem::File);
+ blobStorageData->m_data.appendFile(iter->path, iter->offset, iter->length, iter->expectedModificationTime);
}
}
}
-void BlobRegistryImpl::appendStorageItems(BlobStorageData* blobStorageData, const BlobStorageDataItemList& items, long long offset, long long length)
+void BlobRegistryImpl::appendStorageItems(BlobStorageData* blobStorageData, const BlobDataItemList& items, long long offset, long long length)
{
ASSERT(length != BlobDataItem::toEndOfFile);
- BlobStorageDataItemList::const_iterator iter = items.begin();
+ BlobDataItemList::const_iterator iter = items.begin();
if (offset) {
for (; iter != items.end(); ++iter) {
if (offset >= iter->length)
@@ -108,12 +107,13 @@ void BlobRegistryImpl::appendStorageItems(BlobStorageData* blobStorageData, cons
for (; iter != items.end() && length > 0; ++iter) {
long long currentLength = iter->length - offset;
long long newLength = currentLength > length ? length : currentLength;
- if (iter->type == BlobStorageDataItem::Data)
- blobStorageData->appendData(iter->data, iter->offset + offset, newLength);
+ if (iter->type == BlobDataItem::Data)
+ blobStorageData->m_data.appendData(iter->data, iter->offset + offset, newLength);
else {
- ASSERT(iter->type == BlobStorageDataItem::File);
- blobStorageData->appendFile(iter->path, iter->offset + offset, newLength, iter->expectedModificationTime);
+ ASSERT(iter->type == BlobDataItem::File);
+ blobStorageData->m_data.appendFile(iter->path, iter->offset + offset, newLength, iter->expectedModificationTime);
}
+ length -= newLength;
offset = 0;
}
}
@@ -122,17 +122,20 @@ void BlobRegistryImpl::registerBlobURL(const KURL& url, PassOwnPtr<BlobData> blo
{
ASSERT(isMainThread());
- RefPtr<BlobStorageData> blobStorageData = BlobStorageData::create();
- blobStorageData->setContentType(blobData->contentType());
- blobStorageData->setContentDisposition(blobData->contentDisposition());
+ RefPtr<BlobStorageData> blobStorageData = BlobStorageData::create(blobData->contentType(), blobData->contentDisposition());
+
+ // The blob data is stored in the "canonical" way. That is, it only contains a list of Data and File items.
+ // 1) The Data item is denoted by the raw data and the range.
+ // 2) The File item is denoted by the file path, the range and the expected modification time.
+ // All the Blob items in the passing blob data are resolved and expanded into a set of Data and File items.
for (BlobDataItemList::const_iterator iter = blobData->items().begin(); iter != blobData->items().end(); ++iter) {
switch (iter->type) {
case BlobDataItem::Data:
- blobStorageData->appendData(iter->data, 0, iter->data.length());
+ blobStorageData->m_data.appendData(iter->data, 0, iter->data.length());
break;
case BlobDataItem::File:
- blobStorageData->appendFile(iter->path, iter->offset, iter->length, iter->expectedModificationTime);
+ blobStorageData->m_data.appendFile(iter->path, iter->offset, iter->length, iter->expectedModificationTime);
break;
case BlobDataItem::Blob:
if (m_blobs.contains(iter->url.string()))
@@ -141,7 +144,6 @@ void BlobRegistryImpl::registerBlobURL(const KURL& url, PassOwnPtr<BlobData> blo
}
}
-
m_blobs.set(url.string(), blobStorageData);
}
@@ -154,9 +156,7 @@ void BlobRegistryImpl::registerBlobURL(const KURL& url, const KURL& srcURL)
if (!src)
return;
- RefPtr<BlobStorageData> blobStorageData = BlobStorageData::create();
- blobStorageData->setContentType(src->contentType());
- blobStorageData->setContentDisposition(src->contentDisposition());
+ RefPtr<BlobStorageData> blobStorageData = BlobStorageData::create(src->contentType(), src->contentDisposition());
appendStorageItems(blobStorageData.get(), src->items());
m_blobs.set(url.string(), blobStorageData);
diff --git a/WebCore/platform/network/BlobRegistryImpl.h b/WebCore/platform/network/BlobRegistryImpl.h
index 42693bc..f616664 100644
--- a/WebCore/platform/network/BlobRegistryImpl.h
+++ b/WebCore/platform/network/BlobRegistryImpl.h
@@ -63,8 +63,8 @@ public:
private:
bool shouldLoadResource(const ResourceRequest& request) const;
- void appendStorageItems(BlobStorageData*, const BlobStorageDataItemList&);
- void appendStorageItems(BlobStorageData*, const BlobStorageDataItemList&, long long offset, long long length);
+ void appendStorageItems(BlobStorageData*, const BlobDataItemList&);
+ void appendStorageItems(BlobStorageData*, const BlobDataItemList&, long long offset, long long length);
HashMap<String, RefPtr<BlobStorageData> > m_blobs;
};
diff --git a/WebCore/platform/network/BlobResourceHandle.cpp b/WebCore/platform/network/BlobResourceHandle.cpp
new file mode 100644
index 0000000..63335f6
--- /dev/null
+++ b/WebCore/platform/network/BlobResourceHandle.cpp
@@ -0,0 +1,589 @@
+/*
+ * Copyright (C) 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"
+
+#if ENABLE(BLOB)
+
+#include "BlobResourceHandle.h"
+
+#include "AsyncFileStream.h"
+#include "BlobRegistryImpl.h"
+#include "FileStream.h"
+#include "FileSystem.h"
+#include "HTTPParsers.h"
+#include "KURL.h"
+#include "ResourceError.h"
+#include "ResourceLoader.h"
+#include "ResourceRequest.h"
+#include "ResourceResponse.h"
+
+namespace WebCore {
+
+static const unsigned bufferSize = 1024;
+static const int maxVectorLength = 0x7fffffff;
+static const long long positionNotSpecified = -1;
+
+static const int httpOK = 200;
+static const int httpPartialContent = 206;
+static const int httpNotAllowed = 403;
+static const int httpNotFound = 404;
+static const int httpRequestedRangeNotSatisfiable = 416;
+static const int httpInternalError = 500;
+static const char* httpOKText = "OK";
+static const char* httpPartialContentText = "Partial Content";
+static const char* httpNotAllowedText = "Not Allowed";
+static const char* httpNotFoundText = "Not Found";
+static const char* httpRequestedRangeNotSatisfiableText = "Requested Range Not Satisfiable";
+static const char* httpInternalErrorText = "Internal Server Error";
+
+static const int notFoundError = 1;
+static const int securityError = 2;
+static const int rangeError = 3;
+static const int notReadableError = 4;
+
+///////////////////////////////////////////////////////////////////////////////
+// BlobResourceSynchronousLoader
+
+namespace {
+
+class BlobResourceSynchronousLoader : public ResourceHandleClient {
+public:
+ BlobResourceSynchronousLoader(ResourceError&, ResourceResponse&, Vector<char>&);
+
+ virtual void didReceiveResponse(ResourceHandle*, const ResourceResponse&);
+ virtual void didReceiveData(ResourceHandle*, const char*, int, int /*lengthReceived*/);
+ virtual void didFinishLoading(ResourceHandle*);
+ virtual void didFail(ResourceHandle*, const ResourceError&);
+
+private:
+ ResourceError& m_error;
+ ResourceResponse& m_response;
+ Vector<char>& m_data;
+};
+
+BlobResourceSynchronousLoader::BlobResourceSynchronousLoader(ResourceError& error, ResourceResponse& response, Vector<char>& data)
+ : m_error(error)
+ , m_response(response)
+ , m_data(data)
+{
+}
+
+void BlobResourceSynchronousLoader::didReceiveResponse(ResourceHandle* handle, const ResourceResponse& response)
+{
+ // We cannot handle the size that is more than maximum integer.
+ const int intMaxForLength = 0x7fffffff;
+ if (response.expectedContentLength() > intMaxForLength) {
+ m_error = ResourceError(String(), notReadableError, response.url(), String());
+ return;
+ }
+
+ m_response = response;
+
+ // Read all the data.
+ m_data.resize(static_cast<size_t>(response.expectedContentLength()));
+ static_cast<BlobResourceHandle*>(handle)->readSync(m_data.data(), static_cast<int>(m_data.size()));
+}
+
+void BlobResourceSynchronousLoader::didReceiveData(ResourceHandle*, const char*, int, int)
+{
+}
+
+void BlobResourceSynchronousLoader::didFinishLoading(ResourceHandle*)
+{
+}
+
+void BlobResourceSynchronousLoader::didFail(ResourceHandle*, const ResourceError& error)
+{
+ m_error = error;
+}
+
+}
+
+///////////////////////////////////////////////////////////////////////////////
+// BlobResourceHandle
+
+// static
+void BlobResourceHandle::loadResourceSynchronously(PassRefPtr<BlobStorageData> blobData, const ResourceRequest& request, ResourceError& error, ResourceResponse& response, Vector<char>& data)
+{
+ BlobResourceSynchronousLoader loader(error, response, data);
+ RefPtr<BlobResourceHandle> handle = BlobResourceHandle::create(blobData, request, &loader, false);
+ handle->start();
+}
+
+static void delayedStart(void* context)
+{
+ static_cast<BlobResourceHandle*>(context)->start();
+}
+
+BlobResourceHandle::BlobResourceHandle(PassRefPtr<BlobStorageData> blobData, const ResourceRequest& request, ResourceHandleClient* client, bool async)
+ : ResourceHandle(request, client, false, false)
+ , m_blobData(blobData)
+ , m_async(async)
+ , m_errorCode(0)
+ , m_aborted(false)
+ , m_rangeOffset(positionNotSpecified)
+ , m_rangeEnd(positionNotSpecified)
+ , m_rangeSuffixLength(positionNotSpecified)
+ , m_totalRemainingSize(0)
+ , m_currentItemReadSize(0)
+ , m_sizeItemCount(0)
+ , m_readItemCount(0)
+ , m_fileOpened(false)
+{
+ if (m_async) {
+ m_asyncStream = adoptRef(client->createAsyncFileStream(this));
+ callOnMainThread(delayedStart, this);
+ } else
+ m_stream = FileStream::create();
+}
+
+BlobResourceHandle::~BlobResourceHandle()
+{
+ if (m_async) {
+ if (m_asyncStream)
+ m_asyncStream->stop();
+ } else {
+ if (m_stream)
+ m_stream->stop();
+ }
+}
+
+void BlobResourceHandle::cancel()
+{
+ if (m_async) {
+ if (m_asyncStream) {
+ m_asyncStream->stop();
+ m_asyncStream = 0;
+ }
+ }
+
+ m_aborted = true;
+}
+
+void BlobResourceHandle::start()
+{
+ // Do not continue if the request is aborted or an error occurs.
+ if (m_aborted || m_errorCode)
+ return;
+
+ // If the blob data is not found, fail now.
+ if (!m_blobData) {
+ m_errorCode = notFoundError;
+ notifyResponse();
+ return;
+ }
+
+ // Parse the "Range" header we care about.
+ String range = firstRequest().httpHeaderField("Range");
+ if (!range.isEmpty() && !parseRange(range, m_rangeOffset, m_rangeEnd, m_rangeSuffixLength)) {
+ m_errorCode = rangeError;
+ notifyResponse();
+ return;
+ }
+
+ if (m_async)
+ getSizeForNext();
+ else {
+ for (size_t i = 0; i < m_blobData->items().size() && !m_aborted && !m_errorCode; ++i)
+ getSizeForNext();
+ notifyResponse();
+ }
+}
+
+void BlobResourceHandle::getSizeForNext()
+{
+ // Do we finish validating and counting size for all items?
+ if (m_sizeItemCount >= m_blobData->items().size()) {
+ seek();
+
+ // Start reading if in asynchronous mode.
+ if (m_async) {
+ notifyResponse();
+ m_buffer.resize(bufferSize);
+ readAsync();
+ }
+ return;
+ }
+
+ const BlobDataItem& item = m_blobData->items().at(m_sizeItemCount);
+ switch (item.type) {
+ case BlobDataItem::Data:
+ didGetSize(item.length);
+ break;
+ case BlobDataItem::File:
+ if (m_async)
+ m_asyncStream->getSize(item.path, item.expectedModificationTime);
+ else
+ didGetSize(m_stream->getSize(item.path, item.expectedModificationTime));
+ break;
+ default:
+ ASSERT_NOT_REACHED();
+ }
+}
+
+void BlobResourceHandle::didGetSize(long long size)
+{
+ // Do not continue if the request is aborted or an error occurs.
+ if (m_aborted || m_errorCode)
+ return;
+
+ // If the size is -1, it means the file has been moved or changed. Fail now.
+ if (size == -1) {
+ m_errorCode = notFoundError;
+ notifyResponse();
+ return;
+ }
+
+ // The size passed back is the size of the whole file. If the underlying item is a sliced file, we need to use the slice length.
+ const BlobDataItem& item = m_blobData->items().at(m_sizeItemCount);
+ if (item.type == BlobDataItem::File && item.length != BlobDataItem::toEndOfFile)
+ size = item.length;
+
+ // Cache the size.
+ m_itemLengthList.append(size);
+
+ // Count the size.
+ m_totalRemainingSize += size;
+ m_sizeItemCount++;
+
+ // Continue with the next item.
+ getSizeForNext();
+}
+
+void BlobResourceHandle::seek()
+{
+ // Convert from the suffix length to the range.
+ if (m_rangeSuffixLength != positionNotSpecified) {
+ m_rangeOffset = m_totalRemainingSize - m_rangeSuffixLength;
+ m_rangeEnd = m_rangeOffset + m_rangeSuffixLength - 1;
+ }
+
+ // Bail out if the range is not provided.
+ if (m_rangeOffset == positionNotSpecified)
+ return;
+
+ // Skip the initial items that are not in the range.
+ long long offset = m_rangeOffset;
+ for (m_readItemCount = 0; m_readItemCount < m_blobData->items().size() && offset >= m_itemLengthList[m_readItemCount]; ++m_readItemCount)
+ offset -= m_itemLengthList[m_readItemCount];
+
+ // Set the offset that need to jump to for the first item in the range.
+ m_currentItemReadSize = offset;
+
+ // Adjust the total remaining size in order not to go beyond the range.
+ if (m_rangeEnd != positionNotSpecified) {
+ long long rangeSize = m_rangeEnd - m_rangeOffset + 1;
+ if (m_totalRemainingSize > rangeSize)
+ m_totalRemainingSize = rangeSize;
+ } else
+ m_totalRemainingSize -= m_rangeOffset;
+}
+
+int BlobResourceHandle::readSync(char* buf, int length)
+{
+ ASSERT(!m_async);
+
+ int offset = 0;
+ int remaining = length;
+ while (remaining) {
+ // Do not continue if the request is aborted or an error occurs.
+ if (m_aborted || m_errorCode)
+ break;
+
+ // If there is no more remaining data to read, we are done.
+ if (!m_totalRemainingSize || m_readItemCount >= m_blobData->items().size())
+ break;
+
+ const BlobDataItem& item = m_blobData->items().at(m_readItemCount);
+ int bytesRead = 0;
+ if (item.type == BlobDataItem::Data)
+ bytesRead = readDataSync(item, buf + offset, remaining);
+ else if (item.type == BlobDataItem::File)
+ bytesRead = readFileSync(item, buf + offset, remaining);
+ else
+ ASSERT_NOT_REACHED();
+
+ if (bytesRead > 0) {
+ offset += bytesRead;
+ remaining -= bytesRead;
+ }
+ }
+
+ int result;
+ if (m_aborted || m_errorCode)
+ result = -1;
+ else
+ result = length - remaining;
+
+ notifyReceiveData(buf, result);
+ if (!result)
+ notifyFinish();
+
+ return result;
+}
+
+int BlobResourceHandle::readDataSync(const BlobDataItem& item, char* buf, int length)
+{
+ ASSERT(!m_async);
+
+ long long remaining = item.length - m_currentItemReadSize;
+ int bytesToRead = (length > remaining) ? static_cast<int>(remaining) : length;
+ if (bytesToRead > m_totalRemainingSize)
+ bytesToRead = static_cast<int>(m_totalRemainingSize);
+ memcpy(buf, item.data.data() + item.offset + m_currentItemReadSize, bytesToRead);
+ m_totalRemainingSize -= bytesToRead;
+
+ m_currentItemReadSize += bytesToRead;
+ if (m_currentItemReadSize == item.length) {
+ m_readItemCount++;
+ m_currentItemReadSize = 0;
+ }
+
+ return bytesToRead;
+}
+
+int BlobResourceHandle::readFileSync(const BlobDataItem& item, char* buf, int length)
+{
+ ASSERT(!m_async);
+
+ if (!m_fileOpened) {
+ long long bytesToRead = m_itemLengthList[m_readItemCount] - m_currentItemReadSize;
+ if (bytesToRead > m_totalRemainingSize)
+ bytesToRead = m_totalRemainingSize;
+ bool success = m_stream->openForRead(item.path, item.offset + m_currentItemReadSize, bytesToRead);
+ m_currentItemReadSize = 0;
+ if (!success) {
+ m_errorCode = notReadableError;
+ return 0;
+ }
+
+ m_fileOpened = true;
+ }
+
+ int bytesRead = m_stream->read(buf, length);
+ if (bytesRead < 0) {
+ m_errorCode = notReadableError;
+ return 0;
+ }
+ if (!bytesRead) {
+ m_stream->close();
+ m_fileOpened = false;
+ m_readItemCount++;
+ } else
+ m_totalRemainingSize -= bytesRead;
+
+ return bytesRead;
+}
+
+void BlobResourceHandle::readAsync()
+{
+ ASSERT(m_async);
+
+ // Do not continue if the request is aborted or an error occurs.
+ if (m_aborted || m_errorCode)
+ return;
+
+ // If there is no more remaining data to read, we are done.
+ if (!m_totalRemainingSize || m_readItemCount >= m_blobData->items().size()) {
+ notifyFinish();
+ return;
+ }
+
+ const BlobDataItem& item = m_blobData->items().at(m_readItemCount);
+ if (item.type == BlobDataItem::Data)
+ readDataAsync(item);
+ else if (item.type == BlobDataItem::File)
+ readFileAsync(item);
+ else
+ ASSERT_NOT_REACHED();
+}
+
+void BlobResourceHandle::readDataAsync(const BlobDataItem& item)
+{
+ ASSERT(m_async);
+
+ long long bytesToRead = item.length - m_currentItemReadSize;
+ if (bytesToRead > m_totalRemainingSize)
+ bytesToRead = m_totalRemainingSize;
+ consumeData(item.data.data() + item.offset + m_currentItemReadSize, static_cast<int>(bytesToRead));
+ m_currentItemReadSize = 0;
+}
+
+void BlobResourceHandle::readFileAsync(const BlobDataItem& item)
+{
+ ASSERT(m_async);
+
+ if (m_fileOpened) {
+ m_asyncStream->read(m_buffer.data(), m_buffer.size());
+ return;
+ }
+
+ long long bytesToRead = m_itemLengthList[m_readItemCount] - m_currentItemReadSize;
+ if (bytesToRead > m_totalRemainingSize)
+ bytesToRead = static_cast<int>(m_totalRemainingSize);
+ m_asyncStream->openForRead(item.path, item.offset + m_currentItemReadSize, bytesToRead);
+ m_fileOpened = true;
+ m_currentItemReadSize = 0;
+}
+
+void BlobResourceHandle::didOpen(bool success)
+{
+ ASSERT(m_async);
+
+ if (!success) {
+ failed(notReadableError);
+ return;
+ }
+
+ // Continue the reading.
+ readAsync();
+}
+
+void BlobResourceHandle::didRead(int bytesRead)
+{
+ consumeData(m_buffer.data(), bytesRead);
+}
+
+void BlobResourceHandle::consumeData(const char* data, int bytesRead)
+{
+ ASSERT(m_async);
+
+ m_totalRemainingSize -= bytesRead;
+
+ // Notify the client.
+ if (bytesRead)
+ notifyReceiveData(data, bytesRead);
+
+ if (m_fileOpened) {
+ // When the current item is a file item, the reading is completed only if bytesRead is 0.
+ if (!bytesRead) {
+ // Close the file.
+ m_fileOpened = false;
+ m_asyncStream->close();
+
+ // Move to the next item.
+ m_readItemCount++;
+ }
+ } else {
+ // Otherwise, we read the current text item as a whole and move to the next item.
+ m_readItemCount++;
+ }
+
+ // Continue the reading.
+ readAsync();
+}
+
+void BlobResourceHandle::failed(int errorCode)
+{
+ ASSERT(m_async);
+
+ // Notify the client.
+ notifyFail(errorCode);
+
+ // Close the file if needed.
+ if (m_fileOpened) {
+ m_fileOpened = false;
+ m_asyncStream->close();
+ }
+}
+
+void BlobResourceHandle::notifyResponse()
+{
+ if (!client())
+ return;
+
+ if (m_errorCode) {
+ notifyResponseOnError();
+ notifyFinish();
+ } else
+ notifyResponseOnSuccess();
+}
+
+void BlobResourceHandle::notifyResponseOnSuccess()
+{
+ bool isRangeRequest = m_rangeOffset != positionNotSpecified;
+ ResourceResponse response(firstRequest().url(), m_blobData->contentType(), m_totalRemainingSize, String(), String());
+ response.setExpectedContentLength(m_totalRemainingSize);
+ response.setHTTPStatusCode(isRangeRequest ? httpPartialContent : httpOK);
+ response.setHTTPStatusText(isRangeRequest ? httpPartialContentText : httpOKText);
+ if (!m_blobData->contentDisposition().isEmpty())
+ response.setHTTPHeaderField("Content-Disposition", m_blobData->contentDisposition());
+ client()->didReceiveResponse(this, response);
+}
+
+void BlobResourceHandle::notifyResponseOnError()
+{
+ ASSERT(m_errorCode);
+
+ ResourceResponse response(firstRequest().url(), String(), 0, String(), String());
+ switch (m_errorCode) {
+ case rangeError:
+ response.setHTTPStatusCode(httpRequestedRangeNotSatisfiable);
+ response.setHTTPStatusText(httpRequestedRangeNotSatisfiableText);
+ break;
+ case notFoundError:
+ response.setHTTPStatusCode(httpNotFound);
+ response.setHTTPStatusText(httpNotFoundText);
+ break;
+ case securityError:
+ response.setHTTPStatusCode(httpNotAllowed);
+ response.setHTTPStatusText(httpNotAllowedText);
+ break;
+ default:
+ response.setHTTPStatusCode(httpInternalError);
+ response.setHTTPStatusText(httpInternalErrorText);
+ break;
+ }
+ client()->didReceiveResponse(this, response);
+}
+
+void BlobResourceHandle::notifyReceiveData(const char* data, int bytesRead)
+{
+ if (client())
+ client()->didReceiveData(this, data, bytesRead, bytesRead);
+}
+
+void BlobResourceHandle::notifyFail(int errorCode)
+{
+ if (client())
+ client()->didFail(this, ResourceError(String(), errorCode, firstRequest().url(), String()));
+}
+
+void BlobResourceHandle::notifyFinish()
+{
+ if (client())
+ client()->didFinishLoading(this);
+}
+
+} // namespace WebCore
+
+#endif // ENABLE(BLOB)
+
diff --git a/WebCore/platform/network/BlobResourceHandle.h b/WebCore/platform/network/BlobResourceHandle.h
new file mode 100644
index 0000000..b2a0854
--- /dev/null
+++ b/WebCore/platform/network/BlobResourceHandle.h
@@ -0,0 +1,116 @@
+/*
+ * Copyright (C) 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 BlobResourceHandle_h
+#define BlobResourceHandle_h
+
+#if ENABLE(BLOB)
+
+#include "FileStreamClient.h"
+#include "PlatformString.h"
+#include "ResourceHandle.h"
+#include <wtf/PassRefPtr.h>
+#include <wtf/Vector.h>
+
+namespace WebCore {
+
+class AsyncFileStream;
+class BlobDataItem;
+class BlobStorageData;
+class FileStream;
+class ResourceHandleClient;
+class ResourceRequest;
+
+class BlobResourceHandle : public FileStreamClient, public ResourceHandle {
+public:
+ static PassRefPtr<BlobResourceHandle> create(PassRefPtr<BlobStorageData> blobData, const ResourceRequest& request, ResourceHandleClient* client, bool async = true)
+ {
+ return adoptRef(new BlobResourceHandle(blobData, request, client, async));
+ }
+
+ static void loadResourceSynchronously(PassRefPtr<BlobStorageData> blobData, const ResourceRequest& request, ResourceError& error, ResourceResponse& response, Vector<char>& data);
+
+ // FileStreamClient methods.
+ virtual void didGetSize(long long);
+ virtual void didOpen(bool);
+ virtual void didRead(int);
+
+ // ResourceHandle methods.
+ virtual void cancel();
+
+ void start();
+ int readSync(char*, int);
+
+private:
+ BlobResourceHandle(PassRefPtr<BlobStorageData>, const ResourceRequest&, ResourceHandleClient*, bool async);
+ virtual ~BlobResourceHandle();
+
+ void getSizeForNext();
+ void seek();
+ void consumeData(const char* data, int bytesRead);
+ void failed(int errorCode);
+
+ void readAsync();
+ void readDataAsync(const BlobDataItem&);
+ void readFileAsync(const BlobDataItem&);
+
+ int readDataSync(const BlobDataItem&, char*, int);
+ int readFileSync(const BlobDataItem&, char*, int);
+
+ void notifyResponse();
+ void notifyResponseOnSuccess();
+ void notifyResponseOnError();
+ void notifyReceiveData(const char*, int);
+ void notifyFail(int errorCode);
+ void notifyFinish();
+
+ RefPtr<BlobStorageData> m_blobData;
+ bool m_async;
+ RefPtr<AsyncFileStream> m_asyncStream; // For asynchronous loading.
+ RefPtr<FileStream> m_stream; // For synchronous loading.
+ Vector<char> m_buffer;
+ Vector<long long> m_itemLengthList;
+ int m_errorCode;
+ bool m_aborted;
+ long long m_rangeOffset;
+ long long m_rangeEnd;
+ long long m_rangeSuffixLength;
+ long long m_totalRemainingSize;
+ long long m_currentItemReadSize;
+ unsigned m_sizeItemCount;
+ unsigned m_readItemCount;
+ bool m_fileOpened;
+};
+
+} // namespace WebCore
+
+#endif // ENABLE(BLOB)
+
+#endif // BlobResourceHandle_h
diff --git a/WebCore/platform/network/BlobStorageData.h b/WebCore/platform/network/BlobStorageData.h
index f4125a4..6535e62 100644
--- a/WebCore/platform/network/BlobStorageData.h
+++ b/WebCore/platform/network/BlobStorageData.h
@@ -31,76 +31,33 @@
#ifndef BlobStorageData_h
#define BlobStorageData_h
-#include "PlatformString.h"
+#include "BlobData.h"
#include <wtf/PassRefPtr.h>
-#include <wtf/Vector.h>
-#include <wtf/text/CString.h>
+#include <wtf/RefCounted.h>
namespace WebCore {
-struct BlobStorageDataItem {
- enum BlobStoreDataItemType { Data, File };
- BlobStoreDataItemType type;
- long long offset;
- long long length;
-
- // For string data.
- CString data;
-
- // For file data.
- String path;
- double expectedModificationTime;
-
- BlobStorageDataItem(const CString& data, long long offset, long long length)
- : type(Data)
- , offset(offset)
- , length(length)
- , data(data)
- , expectedModificationTime(0)
- {
- }
-
- BlobStorageDataItem(const String& path, long long offset, long long length, double expectedModificationTime)
- : type(File)
- , offset(offset)
- , length(length)
- , path(path)
- , expectedModificationTime(expectedModificationTime)
- {
- }
-};
-
-typedef Vector<BlobStorageDataItem> BlobStorageDataItemList;
-
class BlobStorageData : public RefCounted<BlobStorageData> {
public:
- static PassRefPtr<BlobStorageData> create()
+ static PassRefPtr<BlobStorageData> create(const String& contentType, const String& contentDisposition)
{
- return adoptRef(new BlobStorageData());
+ return adoptRef(new BlobStorageData(contentType, contentDisposition));
}
- const String& contentType() const { return m_contentType; }
- void setContentType(const String& contentType) { m_contentType = contentType; }
-
- const String& contentDisposition() const { return m_contentDisposition; }
- void setContentDisposition(const String& contentDisposition) { m_contentDisposition = contentDisposition; }
-
- const BlobStorageDataItemList& items() const { return m_items; }
+ const String& contentType() const { return m_data.contentType(); }
+ const String& contentDisposition() const { return m_data.contentDisposition(); }
+ const BlobDataItemList& items() const { return m_data.items(); }
- void appendData(const CString& data, long long offset, long long length)
- {
- m_items.append(BlobStorageDataItem(data, offset, length));
- }
+private:
+ friend class BlobRegistryImpl;
- void appendFile(const String& path, long long offset, long long length, double expectedModificationTime)
+ BlobStorageData(const String& contentType, const String& contentDisposition)
{
- m_items.append(BlobStorageDataItem(path, offset, length, expectedModificationTime));
+ m_data.setContentType(contentType);
+ m_data.setContentDisposition(contentDisposition);
}
-private:
- String m_contentType;
- String m_contentDisposition;
- BlobStorageDataItemList m_items;
+ BlobData m_data;
};
} // namespace WebCore
diff --git a/WebCore/platform/network/CredentialStorage.cpp b/WebCore/platform/network/CredentialStorage.cpp
index 4fb7799..38f71a4 100644
--- a/WebCore/platform/network/CredentialStorage.cpp
+++ b/WebCore/platform/network/CredentialStorage.cpp
@@ -79,7 +79,6 @@ static String protectionSpaceMapKeyFromURL(const KURL& url)
ASSERT(index != notFound);
directoryURL = directoryURL.substring(0, (index != directoryURLPathStart) ? index : directoryURLPathStart + 1);
}
- ASSERT(directoryURL.length() == directoryURLPathStart + 1 || directoryURL[directoryURL.length() - 1] != '/');
return directoryURL;
}
diff --git a/WebCore/platform/network/FormData.cpp b/WebCore/platform/network/FormData.cpp
index 31506ea..4f2b365 100644
--- a/WebCore/platform/network/FormData.cpp
+++ b/WebCore/platform/network/FormData.cpp
@@ -139,6 +139,11 @@ PassRefPtr<FormData> FormData::deepCopy() const
formData->m_elements.append(FormDataElement(e.m_filename, e.m_shouldGenerateFile));
#endif
break;
+#if ENABLE(BLOB)
+ case FormDataElement::encodedBlob:
+ formData->m_elements.append(FormDataElement(e.m_blobURL));
+ break;
+#endif
}
}
return formData.release();
@@ -200,6 +205,11 @@ void FormData::appendFileRange(const String& filename, long long start, long lon
{
m_elements.append(FormDataElement(filename, start, length, expectedModificationTime, shouldGenerateFile));
}
+
+void FormData::appendBlob(const KURL& blobURL)
+{
+ m_elements.append(FormDataElement(blobURL));
+}
#endif
void FormData::appendKeyValuePairItems(const BlobItemList& items, const TextEncoding& encoding, bool isMultiPartForm, Document* document)
diff --git a/WebCore/platform/network/FormData.h b/WebCore/platform/network/FormData.h
index a1964e3..d7faa89 100644
--- a/WebCore/platform/network/FormData.h
+++ b/WebCore/platform/network/FormData.h
@@ -20,6 +20,7 @@
#ifndef FormData_h
#define FormData_h
+#include "KURL.h"
#include "PlatformString.h"
#include <wtf/Forward.h>
#include <wtf/RefCounted.h>
@@ -39,17 +40,25 @@ public:
#if ENABLE(BLOB)
FormDataElement(const String& filename, long long fileStart, long long fileLength, double expectedFileModificationTime, bool shouldGenerateFile) : m_type(encodedFile), m_filename(filename), m_fileStart(fileStart), m_fileLength(fileLength), m_expectedFileModificationTime(expectedFileModificationTime), m_shouldGenerateFile(shouldGenerateFile) { }
+ FormDataElement(const KURL& blobURL) : m_type(encodedBlob), m_blobURL(blobURL) { }
#else
FormDataElement(const String& filename, bool shouldGenerateFile) : m_type(encodedFile), m_filename(filename), m_shouldGenerateFile(shouldGenerateFile) { }
#endif
- enum { data, encodedFile } m_type;
+ enum {
+ data,
+ encodedFile
+#if ENABLE(BLOB)
+ , encodedBlob
+#endif
+ } m_type;
Vector<char> m_data;
String m_filename;
#if ENABLE(BLOB)
long long m_fileStart;
long long m_fileLength;
double m_expectedFileModificationTime;
+ KURL m_blobURL;
#endif
String m_generatedFilename;
bool m_shouldGenerateFile;
@@ -67,14 +76,16 @@ inline bool operator==(const FormDataElement& a, const FormDataElement& b)
if (a.m_type != b.m_type)
return false;
- if (a.m_data != b.m_data)
- return false;
+ if (a.m_type == FormDataElement::data)
+ return a.m_data == b.m_data;
+ if (a.m_type == FormDataElement::encodedFile)
#if ENABLE(BLOB)
- if (a.m_filename != b.m_filename || a.m_fileStart != b.m_fileStart || a.m_fileLength != b.m_fileLength || a.m_expectedFileModificationTime != b.m_expectedFileModificationTime)
+ return a.m_filename == b.m_filename && a.m_fileStart == b.m_fileStart && a.m_fileLength == b.m_fileLength && a.m_expectedFileModificationTime == b.m_expectedFileModificationTime;
+ if (a.m_type == FormDataElement::encodedBlob)
+ return a.m_blobURL == b.m_blobURL;
#else
- if (a.m_filename != b.m_filename)
+ return a.m_filename == b.m_filename;
#endif
- return false;
return true;
}
@@ -101,6 +112,7 @@ public:
void appendFile(const String& filename, bool shouldGenerateFile = false);
#if ENABLE(BLOB)
void appendFileRange(const String& filename, long long start, long long length, double expectedModificationTime, bool shouldGenerateFile = false);
+ void appendBlob(const KURL& blobURL);
#endif
void flatten(Vector<char>&) const; // omits files
diff --git a/WebCore/platform/network/HTTPParsers.cpp b/WebCore/platform/network/HTTPParsers.cpp
index b3f3d45..a1ba9d3 100644
--- a/WebCore/platform/network/HTTPParsers.cpp
+++ b/WebCore/platform/network/HTTPParsers.cpp
@@ -315,4 +315,61 @@ String extractReasonPhraseFromHTTPStatusLine(const String& statusLine)
return statusLine.substring(spacePos + 1);
}
+bool parseRange(const String& range, long long& rangeOffset, long long& rangeEnd, long long& rangeSuffixLength)
+{
+ // The format of "Range" header is defined in RFC 2616 Section 14.35.1.
+ // http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.35.1
+ // We don't support multiple range requests.
+
+ rangeOffset = rangeEnd = rangeSuffixLength = -1;
+
+ // The "bytes" unit identifier should be present.
+ static const char bytesStart[] = "bytes=";
+ if (!range.startsWith(bytesStart, false))
+ return false;
+ String byteRange = range.substring(sizeof(bytesStart) - 1);
+
+ // The '-' character needs to be present.
+ int index = byteRange.find('-');
+ if (index == -1)
+ return false;
+
+ // If the '-' character is at the beginning, the suffix length, which specifies the last N bytes, is provided.
+ // Example:
+ // -500
+ if (!index) {
+ String suffixLengthString = byteRange.substring(index + 1).stripWhiteSpace();
+ bool ok;
+ long long value = suffixLengthString.toInt64Strict(&ok);
+ if (ok)
+ rangeSuffixLength = value;
+ return true;
+ }
+
+ // Otherwise, the first-byte-position and the last-byte-position are provied.
+ // Examples:
+ // 0-499
+ // 500-
+ String firstBytePosStr = byteRange.left(index).stripWhiteSpace();
+ bool ok;
+ long long firstBytePos = firstBytePosStr.toInt64Strict(&ok);
+ if (!ok)
+ return false;
+
+ String lastBytePosStr = byteRange.substring(index + 1).stripWhiteSpace();
+ long long lastBytePos = -1;
+ if (!lastBytePosStr.isEmpty()) {
+ lastBytePos = lastBytePosStr.toInt64Strict(&ok);
+ if (!ok)
+ return false;
+ }
+
+ if (firstBytePos < 0 || !(lastBytePos == -1 || lastBytePos >= firstBytePos))
+ return false;
+
+ rangeOffset = firstBytePos;
+ rangeEnd = lastBytePos;
+ return true;
+}
+
}
diff --git a/WebCore/platform/network/HTTPParsers.h b/WebCore/platform/network/HTTPParsers.h
index 9d6971b..55b8c7b 100644
--- a/WebCore/platform/network/HTTPParsers.h
+++ b/WebCore/platform/network/HTTPParsers.h
@@ -59,6 +59,9 @@ void findCharsetInMediaType(const String& mediaType, unsigned int& charsetPos, u
XSSProtectionDisposition parseXSSProtectionHeader(const String&);
String extractReasonPhraseFromHTTPStatusLine(const String&);
+// -1 could be set to one of the return parameters to indicate the value is not specified.
+bool parseRange(const String&, long long& rangeOffset, long long& rangeEnd, long long& rangeSuffixLength);
+
}
#endif
diff --git a/WebCore/platform/network/ResourceHandle.cpp b/WebCore/platform/network/ResourceHandle.cpp
index 0575523..2da1d77 100644
--- a/WebCore/platform/network/ResourceHandle.cpp
+++ b/WebCore/platform/network/ResourceHandle.cpp
@@ -27,6 +27,7 @@
#include "ResourceHandle.h"
#include "ResourceHandleInternal.h"
+#include "BlobRegistry.h"
#include "DNS.h"
#include "Logging.h"
#include "ResourceHandleClient.h"
@@ -54,6 +55,14 @@ ResourceHandle::ResourceHandle(const ResourceRequest& request, ResourceHandleCli
PassRefPtr<ResourceHandle> ResourceHandle::create(const ResourceRequest& request, ResourceHandleClient* client,
Frame* frame, bool defersLoading, bool shouldContentSniff)
{
+#if ENABLE(BLOB)
+ if (request.url().protocolIs("blob")) {
+ PassRefPtr<ResourceHandle> handle = blobRegistry().createResourceHandle(request, client);
+ if (handle)
+ return handle;
+ }
+#endif
+
RefPtr<ResourceHandle> newHandle(adoptRef(new ResourceHandle(request, client, defersLoading, shouldContentSniff)));
if (newHandle->d->m_scheduledFailureType != NoFailure)
diff --git a/WebCore/platform/network/ResourceHandle.h b/WebCore/platform/network/ResourceHandle.h
index 3dc38f8..1167715 100644
--- a/WebCore/platform/network/ResourceHandle.h
+++ b/WebCore/platform/network/ResourceHandle.h
@@ -98,9 +98,10 @@ class ResourceHandle : public RefCounted<ResourceHandle>
, public AuthenticationClient
#endif
{
-private:
+protected:
ResourceHandle(const ResourceRequest&, ResourceHandleClient*, bool defersLoading, bool shouldContentSniff);
+private:
enum FailureType {
NoFailure,
BlockedFailure,
diff --git a/WebCore/platform/network/ResourceHandleClient.h b/WebCore/platform/network/ResourceHandleClient.h
index 0098010..97c0f54 100644
--- a/WebCore/platform/network/ResourceHandleClient.h
+++ b/WebCore/platform/network/ResourceHandleClient.h
@@ -44,8 +44,10 @@ class NSCachedURLResponse;
#endif
namespace WebCore {
+ class AsyncFileStream;
class AuthenticationChallenge;
class Credential;
+ class FileStreamClient;
class KURL;
class ProtectionSpace;
class ResourceHandle;
@@ -92,6 +94,9 @@ namespace WebCore {
#if USE(CFNETWORK)
virtual bool shouldCacheResponse(ResourceHandle*, CFCachedURLResponseRef response) { return true; }
#endif
+#if ENABLE(BLOB)
+ virtual AsyncFileStream* createAsyncFileStream(FileStreamClient*) { return 0; }
+#endif
};
}
diff --git a/WebCore/platform/network/ResourceHandleInternal.h b/WebCore/platform/network/ResourceHandleInternal.h
index 7b6e960..24b00bf 100644
--- a/WebCore/platform/network/ResourceHandleInternal.h
+++ b/WebCore/platform/network/ResourceHandleInternal.h
@@ -92,7 +92,6 @@ namespace WebCore {
, m_connection(0)
#endif
#if USE(WININET)
- , m_fileHandle(INVALID_HANDLE_VALUE)
, m_fileLoadTimer(loader, &ResourceHandle::fileLoadTimer)
, m_resourceHandle(0)
, m_secondaryHandle(0)
@@ -170,7 +169,6 @@ namespace WebCore {
bool m_needsSiteSpecificQuirks;
#endif
#if USE(WININET)
- HANDLE m_fileHandle;
Timer<ResourceHandle> m_fileLoadTimer;
HINTERNET m_resourceHandle;
HINTERNET m_secondaryHandle;
diff --git a/WebCore/platform/network/mac/ResourceHandleMac.mm b/WebCore/platform/network/mac/ResourceHandleMac.mm
index f7161ec..d014bb3 100644
--- a/WebCore/platform/network/mac/ResourceHandleMac.mm
+++ b/WebCore/platform/network/mac/ResourceHandleMac.mm
@@ -29,6 +29,7 @@
#import "AuthenticationChallenge.h"
#import "AuthenticationMac.h"
#import "Base64.h"
+#import "BlobRegistry.h"
#import "BlockExceptions.h"
#import "CredentialStorage.h"
#import "DocLoader.h"
@@ -464,6 +465,12 @@ void ResourceHandle::loadResourceSynchronously(const ResourceRequest& request, S
{
LOG(Network, "ResourceHandle::loadResourceSynchronously:%@ allowStoredCredentials:%u", request.nsURLRequest(), storedCredentials);
+#if ENABLE(BLOB)
+ if (request.url().protocolIs("blob"))
+ if (blobRegistry().loadResourceSynchronously(request, error, response, data))
+ return;
+#endif
+
NSError *nsError = nil;
NSURLResponse *nsURLResponse = nil;
NSData *result = nil;
diff --git a/WebCore/platform/network/win/ResourceHandleWin.cpp b/WebCore/platform/network/win/ResourceHandleWin.cpp
index 63c84a9..3dabd91 100644
--- a/WebCore/platform/network/win/ResourceHandleWin.cpp
+++ b/WebCore/platform/network/win/ResourceHandleWin.cpp
@@ -1,5 +1,6 @@
/*
* Copyright (C) 2004, 2006 Apple Computer, Inc. All rights reserved.
+ * Copyright (C) 2010 Patrick Gansterer <paroga@paroga.com>
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -63,6 +64,20 @@ static const ResourceHandleEventHandler messageHandlers[] = {
&ResourceHandle::onRequestComplete
};
+static String queryHTTPHeader(HINTERNET requestHandle, DWORD infoLevel)
+{
+ DWORD bufferSize = 0;
+ HttpQueryInfoW(requestHandle, infoLevel, 0, &bufferSize, 0);
+
+ Vector<UChar> characters(bufferSize / sizeof(UChar));
+
+ if (!HttpQueryInfoW(requestHandle, infoLevel, characters.data(), &bufferSize, 0))
+ return String();
+
+ characters.removeLast(); // Remove NullTermination.
+ return String::adopt(characters);
+}
+
static int addToOutstandingJobs(ResourceHandle* job)
{
if (!jobIdMap)
@@ -122,6 +137,49 @@ static void initializeOffScreenResourceHandleWindow()
HWND_MESSAGE, 0, WebCore::instanceHandle(), 0);
}
+
+class WebCoreSynchronousLoader : public ResourceHandleClient, public Noncopyable {
+public:
+ WebCoreSynchronousLoader(ResourceError&, ResourceResponse&, Vector<char>&, const String& userAgent);
+
+ virtual void didReceiveResponse(ResourceHandle*, const ResourceResponse&);
+ virtual void didReceiveData(ResourceHandle*, const char*, int, int lengthReceived);
+ virtual void didFinishLoading(ResourceHandle*);
+ virtual void didFail(ResourceHandle*, const ResourceError&);
+
+private:
+ ResourceError& m_error;
+ ResourceResponse& m_response;
+ Vector<char>& m_data;
+};
+
+WebCoreSynchronousLoader::WebCoreSynchronousLoader(ResourceError& error, ResourceResponse& response, Vector<char>& data, const String& userAgent)
+ : m_error(error)
+ , m_response(response)
+ , m_data(data)
+{
+}
+
+void WebCoreSynchronousLoader::didReceiveResponse(ResourceHandle*, const ResourceResponse& response)
+{
+ m_response = response;
+}
+
+void WebCoreSynchronousLoader::didReceiveData(ResourceHandle*, const char* data, int length, int)
+{
+ m_data.append(data, length);
+}
+
+void WebCoreSynchronousLoader::didFinishLoading(ResourceHandle*)
+{
+}
+
+void WebCoreSynchronousLoader::didFail(ResourceHandle*, const ResourceError& error)
+{
+ m_error = error;
+}
+
+
ResourceHandleInternal::~ResourceHandleInternal()
{
if (m_fileHandle != INVALID_HANDLE_VALUE)
@@ -225,7 +283,6 @@ void ResourceHandle::onRequestComplete(LPARAM lParam)
}
HINTERNET handle = (request().httpMethod() == "POST") ? d->m_secondaryHandle : d->m_resourceHandle;
- BOOL ok = FALSE;
static const int bufferSize = 32768;
char buffer[bufferSize];
@@ -234,11 +291,31 @@ void ResourceHandle::onRequestComplete(LPARAM lParam)
buffers.lpvBuffer = buffer;
buffers.dwBufferLength = bufferSize;
- bool receivedAnyData = false;
+ BOOL ok = FALSE;
while ((ok = InternetReadFileExA(handle, &buffers, IRF_NO_WAIT, (DWORD_PTR)this)) && buffers.dwBufferLength) {
if (!hasReceivedResponse()) {
setHasReceivedResponse();
ResourceResponse response;
+ response.setURL(firstRequest().url());
+
+ String httpStatusText = queryHTTPHeader(d->m_requestHandle, HTTP_QUERY_STATUS_TEXT);
+ if (!httpStatusText.isNull())
+ response.setHTTPStatusText(httpStatusText);
+
+ String httpStatusCode = queryHTTPHeader(d->m_requestHandle, HTTP_QUERY_STATUS_CODE);
+ if (!httpStatusCode.isNull())
+ response.setHTTPStatusCode(httpStatusCode.toInt());
+
+ String httpContentLength = queryHTTPHeader(d->m_requestHandle, HTTP_QUERY_CONTENT_LENGTH);
+ if (!httpContentLength.isNull())
+ response.setExpectedContentLength(httpContentLength.toInt());
+
+ String httpContentType = queryHTTPHeader(d->m_requestHandle, HTTP_QUERY_CONTENT_TYPE);
+ if (!httpContentType.isNull()) {
+ response.setMimeType(extractMIMETypeFromMediaType(httpContentType));
+ response.setTextEncodingName(extractCharsetFromMediaType(httpContentType));
+ }
+
client()->didReceiveResponse(this, response);
}
client()->didReceiveData(this, buffer, buffers.dwBufferLength, 0);
@@ -333,20 +410,6 @@ bool ResourceHandle::start(Frame* frame)
{
ref();
if (request().url().isLocalFile()) {
- String path = request().url().path();
- // windows does not enjoy a leading slash on paths
- if (path[0] == '/')
- path = path.substring(1);
- // FIXME: This is wrong. Need to use wide version of this call.
- d->m_fileHandle = CreateFileA(path.utf8().data(), GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
-
- // FIXME: perhaps this error should be reported asynchronously for
- // consistency.
- if (d->m_fileHandle == INVALID_HANDLE_VALUE) {
- delete this;
- return false;
- }
-
d->m_fileLoadTimer.startOneShot(0.0);
return true;
} else {
@@ -409,9 +472,29 @@ bool ResourceHandle::start(Frame* frame)
}
}
-void ResourceHandle::fileLoadTimer(Timer<ResourceHandle>* timer)
+void ResourceHandle::fileLoadTimer(Timer<ResourceHandle>*)
{
+ RefPtr<ResourceHandle> protector(this);
+ deref(); // balances ref in start
+
+ String fileName = firstRequest().url().fileSystemPath();
+ HANDLE fileHandle = CreateFileW(fileName.charactersWithNullTermination(), GENERIC_READ, 0, 0, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
+
+ if (fileHandle == INVALID_HANDLE_VALUE) {
+ client()->didFail(this, ResourceError());
+ return;
+ }
+
ResourceResponse response;
+
+ int dotPos = fileName.reverseFind('.');
+ int slashPos = fileName.reverseFind('/');
+
+ if (slashPos < dotPos && dotPos != -1) {
+ String ext = fileName.substring(dotPos + 1);
+ response.setMimeType(MIMETypeRegistry::getMIMETypeForExtension(ext));
+ }
+
client()->didReceiveResponse(this, response);
bool result = false;
@@ -420,16 +503,13 @@ void ResourceHandle::fileLoadTimer(Timer<ResourceHandle>* timer)
do {
const int bufferSize = 8192;
char buffer[bufferSize];
- result = ReadFile(d->m_fileHandle, &buffer, bufferSize, &bytesRead, NULL);
+ result = ReadFile(fileHandle, &buffer, bufferSize, &bytesRead, 0);
if (result && bytesRead)
client()->didReceiveData(this, buffer, bytesRead, 0);
- // Check for end of file.
+ // Check for end of file.
} while (result && bytesRead);
- // FIXME: handle errors better
-
- CloseHandle(d->m_fileHandle);
- d->m_fileHandle = INVALID_HANDLE_VALUE;
+ CloseHandle(fileHandle);
client()->didFinishLoading(this);
}
@@ -449,6 +529,16 @@ void ResourceHandle::cancel()
client()->didFail(this, ResourceError());
}
+void ResourceHandle::loadResourceSynchronously(const ResourceRequest& request, StoredCredentials storedCredentials, ResourceError& error, ResourceResponse& response, Vector<char>& data, Frame* frame)
+{
+ UNUSED_PARAM(storedCredentials);
+
+ WebCoreSynchronousLoader syncLoader(error, response, data, request.httpUserAgent());
+ ResourceHandle handle(request, &syncLoader, true, false);
+
+ handle.start(frame);
+}
+
void ResourceHandle::setHasReceivedResponse(bool b)
{
d->m_hasReceivedResponse = b;
@@ -459,4 +549,36 @@ bool ResourceHandle::hasReceivedResponse() const
return d->m_hasReceivedResponse;
}
+bool ResourceHandle::willLoadFromCache(ResourceRequest&, Frame*)
+{
+ notImplemented();
+ return false;
+}
+
+void prefetchDNS(const String&)
+{
+ notImplemented();
+}
+
+PassRefPtr<SharedBuffer> ResourceHandle::bufferedData()
+{
+ ASSERT_NOT_REACHED();
+ return 0;
+}
+
+bool ResourceHandle::supportsBufferedData()
+{
+ return false;
+}
+
+bool ResourceHandle::loadsBlocked()
+{
+ return false;
+}
+
+void ResourceHandle::platformSetDefersLoading(bool)
+{
+ notImplemented();
+}
+
} // namespace WebCore
diff --git a/WebCore/platform/qt/CursorQt.cpp b/WebCore/platform/qt/CursorQt.cpp
index 6017daa..227b80c 100644
--- a/WebCore/platform/qt/CursorQt.cpp
+++ b/WebCore/platform/qt/CursorQt.cpp
@@ -3,6 +3,7 @@
* Copyright (C) 2006 George Staikos <staikos@kde.org>
* Copyright (C) 2006 Charles Samuels <charles@kde.org>
* Copyright (C) 2008, 2009 Holger Hans Peter Freyther
+ * Copyright (C) 2010 University of Szeged
*
* All rights reserved.
*
@@ -43,329 +44,166 @@
namespace WebCore {
-Cursor::Cursor(PlatformCursor p)
- : m_platformCursor(p)
-{
-}
-
Cursor::Cursor(const Cursor& other)
- : m_platformCursor(other.m_platformCursor)
+ : m_type(other.m_type)
+ , m_image(other.m_image)
+ , m_hotSpot(other.m_hotSpot)
+#ifndef QT_NO_CURSOR
+ , m_platformCursor(other.m_platformCursor ? new QCursor(*other.m_platformCursor) : 0)
+#endif
{
}
Cursor::~Cursor()
{
-}
-
-Cursor::Cursor(Image* image, const IntPoint& hotSpot)
-{
#ifndef QT_NO_CURSOR
- IntPoint effectiveHotSpot = determineHotSpot(image, hotSpot);
- m_platformCursor = QCursor(*(image->nativeImageForCurrentFrame()), effectiveHotSpot.x(), effectiveHotSpot.y());
+ delete m_platformCursor;
#endif
}
Cursor& Cursor::operator=(const Cursor& other)
{
- m_platformCursor = other.m_platformCursor;
- return *this;
-}
-
-namespace {
-
-// FIXME: static deleter
-class Cursors : public Noncopyable {
-protected:
- Cursors()
+ m_type = other.m_type;
+ m_image = other.m_image;
+ m_hotSpot = other.m_hotSpot;
#ifndef QT_NO_CURSOR
- : CrossCursor(Qt::CrossCursor)
- , MoveCursor(Qt::SizeAllCursor)
- , PointerCursor(Qt::ArrowCursor)
- , PointingHandCursor(Qt::PointingHandCursor)
- , IBeamCursor(Qt::IBeamCursor)
- , WaitCursor(Qt::WaitCursor)
- , WhatsThisCursor(Qt::WhatsThisCursor)
- , SizeHorCursor(Qt::SizeHorCursor)
- , SizeVerCursor(Qt::SizeVerCursor)
- , SizeFDiagCursor(Qt::SizeFDiagCursor)
- , SizeBDiagCursor(Qt::SizeBDiagCursor)
- , SplitHCursor(Qt::SplitHCursor)
- , SplitVCursor(Qt::SplitVCursor)
- , NoDropCursor(Qt::ForbiddenCursor)
- , BlankCursor(Qt::BlankCursor)
- , ZoomInCursor(QCursor(QPixmap(QLatin1String(":/webkit/resources/zoomInCursor.png")), 7, 7))
- , ZoomOutCursor(QCursor(QPixmap(QLatin1String(":/webkit/resources/zoomOutCursor.png")), 7, 7))
- , VerticalTextCursor(QCursor(QPixmap(QLatin1String(":/webkit/resources/verticalTextCursor.png")), 7, 7))
- , CellCursor(QCursor(QPixmap(QLatin1String(":/webkit/resources/cellCursor.png")), 7, 7))
- , ContextMenuCursor(QCursor(QPixmap(QLatin1String(":/webkit/resources/contextMenuCursor.png")), 3, 2))
- , CopyCursor(QCursor(QPixmap(QLatin1String(":/webkit/resources/copyCursor.png")), 3, 2))
- , ProgressCursor(QCursor(QPixmap(QLatin1String(":/webkit/resources/progressCursor.png")), 3, 2))
- , AliasCursor(QCursor(QPixmap(QLatin1String(":/webkit/resources/aliasCursor.png")), 11, 3))
-
+ m_platformCursor = other.m_platformCursor ? new QCursor(*other.m_platformCursor) : 0;
#endif
- {
- }
-
- ~Cursors()
- {
- }
-
-public:
- static Cursors* self();
- static Cursors* s_self;
-
- Cursor CrossCursor;
- Cursor MoveCursor;
- Cursor PointerCursor;
- Cursor PointingHandCursor;
- Cursor IBeamCursor;
- Cursor WaitCursor;
- Cursor WhatsThisCursor;
- Cursor SizeHorCursor;
- Cursor SizeVerCursor;
- Cursor SizeFDiagCursor;
- Cursor SizeBDiagCursor;
- Cursor SplitHCursor;
- Cursor SplitVCursor;
- Cursor NoDropCursor;
- Cursor BlankCursor;
- Cursor ZoomInCursor;
- Cursor ZoomOutCursor;
- Cursor VerticalTextCursor;
- Cursor CellCursor;
- Cursor ContextMenuCursor;
- Cursor CopyCursor;
- Cursor ProgressCursor;
- Cursor AliasCursor;
-};
-
-Cursors* Cursors::s_self = 0;
-
-Cursors* Cursors::self()
-{
- if (!s_self)
- s_self = new Cursors();
-
- return s_self;
-}
-
-}
-
-const Cursor& pointerCursor()
-{
- return Cursors::self()->PointerCursor;
-}
-
-const Cursor& moveCursor()
-{
- return Cursors::self()->MoveCursor;
-}
-
-const Cursor& crossCursor()
-{
- return Cursors::self()->CrossCursor;
-}
-
-const Cursor& handCursor()
-{
- return Cursors::self()->PointingHandCursor;
-}
-
-const Cursor& iBeamCursor()
-{
- return Cursors::self()->IBeamCursor;
-}
-
-const Cursor& waitCursor()
-{
- return Cursors::self()->WaitCursor;
-}
-
-const Cursor& helpCursor()
-{
- return Cursors::self()->WhatsThisCursor;
-}
-
-const Cursor& eastResizeCursor()
-{
- return Cursors::self()->SizeHorCursor;
-}
-
-const Cursor& northResizeCursor()
-{
- return Cursors::self()->SizeVerCursor;
-}
-
-const Cursor& northEastResizeCursor()
-{
- return Cursors::self()->SizeBDiagCursor;
-}
-
-const Cursor& northWestResizeCursor()
-{
- return Cursors::self()->SizeFDiagCursor;
-}
-
-const Cursor& southResizeCursor()
-{
- return Cursors::self()->SizeVerCursor;
-}
-
-const Cursor& southEastResizeCursor()
-{
- return Cursors::self()->SizeFDiagCursor;
-}
-
-const Cursor& southWestResizeCursor()
-{
- return Cursors::self()->SizeBDiagCursor;
-}
-
-const Cursor& westResizeCursor()
-{
- return Cursors::self()->SizeHorCursor;
-}
-
-const Cursor& northSouthResizeCursor()
-{
- return Cursors::self()->SizeVerCursor;
-}
-
-const Cursor& eastWestResizeCursor()
-{
- return Cursors::self()->SizeHorCursor;
-}
-
-const Cursor& northEastSouthWestResizeCursor()
-{
- return Cursors::self()->SizeBDiagCursor;
-}
-
-const Cursor& northWestSouthEastResizeCursor()
-{
- return Cursors::self()->SizeFDiagCursor;
-}
-
-const Cursor& columnResizeCursor()
-{
- return Cursors::self()->SplitHCursor;
-}
-
-const Cursor& rowResizeCursor()
-{
- return Cursors::self()->SplitVCursor;
-}
-
-const Cursor& middlePanningCursor()
-{
- return moveCursor();
-}
-
-const Cursor& eastPanningCursor()
-{
- return eastResizeCursor();
-}
-
-const Cursor& northPanningCursor()
-{
- return northResizeCursor();
-}
-
-const Cursor& northEastPanningCursor()
-{
- return northEastResizeCursor();
-}
-
-const Cursor& northWestPanningCursor()
-{
- return northWestResizeCursor();
-}
-
-const Cursor& southPanningCursor()
-{
- return southResizeCursor();
-}
-
-const Cursor& southEastPanningCursor()
-{
- return southEastResizeCursor();
-}
-
-const Cursor& southWestPanningCursor()
-{
- return southWestResizeCursor();
-}
-
-const Cursor& westPanningCursor()
-{
- return westResizeCursor();
-}
-
-const Cursor& verticalTextCursor()
-{
- return Cursors::self()->VerticalTextCursor;
-}
-
-const Cursor& cellCursor()
-{
- return Cursors::self()->CellCursor;
-}
-
-const Cursor& contextMenuCursor()
-{
- return Cursors::self()->ContextMenuCursor;
-}
-
-const Cursor& noDropCursor()
-{
- return Cursors::self()->NoDropCursor;
-}
-
-const Cursor& copyCursor()
-{
- return Cursors::self()->CopyCursor;
-}
-
-const Cursor& progressCursor()
-{
- return Cursors::self()->ProgressCursor;
-}
-
-const Cursor& aliasCursor()
-{
- return Cursors::self()->AliasCursor;
-}
-
-const Cursor& noneCursor()
-{
- return Cursors::self()->BlankCursor;
-}
-
-const Cursor& notAllowedCursor()
-{
- return Cursors::self()->NoDropCursor;
-}
-
-const Cursor& zoomInCursor()
-{
- return Cursors::self()->ZoomInCursor;
-}
-
-const Cursor& zoomOutCursor()
-{
- return Cursors::self()->ZoomOutCursor;
+ return *this;
}
-const Cursor& grabCursor()
+static QCursor* createCustomCursor(Image* image, const IntPoint& hotSpot)
{
- notImplemented();
- return Cursors::self()->PointerCursor;
+#ifndef QT_NO_CURSOR
+ IntPoint effectiveHotSpot = determineHotSpot(image, hotSpot);
+ return new QCursor(*(image->nativeImageForCurrentFrame()), effectiveHotSpot.x(), effectiveHotSpot.y());
+#else
+ return 0;
+#endif
}
-const Cursor& grabbingCursor()
+void Cursor::ensurePlatformCursor() const
{
- notImplemented();
- return Cursors::self()->PointerCursor;
+#ifndef QT_NO_CURSOR
+ if (m_platformCursor)
+ return;
+
+ switch (m_type) {
+ case Pointer:
+ m_platformCursor = new QCursor(Qt::ArrowCursor);
+ break;
+ case Cross:
+ m_platformCursor = new QCursor(Qt::CrossCursor);
+ break;
+ case Hand:
+ m_platformCursor = new QCursor(Qt::PointingHandCursor);
+ break;
+ case IBeam:
+ m_platformCursor = new QCursor(Qt::IBeamCursor);
+ break;
+ case Wait:
+ m_platformCursor = new QCursor(Qt::WaitCursor);
+ break;
+ case Help:
+ m_platformCursor = new QCursor(Qt::WhatsThisCursor);
+ break;
+ case EastResize:
+ case EastPanning:
+ m_platformCursor = new QCursor(Qt::SizeHorCursor);
+ break;
+ case NorthResize:
+ case NorthPanning:
+ m_platformCursor = new QCursor(Qt::SizeVerCursor);
+ break;
+ case NorthEastResize:
+ case NorthEastPanning:
+ m_platformCursor = new QCursor(Qt::SizeBDiagCursor);
+ break;
+ case NorthWestResize:
+ case NorthWestPanning:
+ m_platformCursor = new QCursor(Qt::SizeFDiagCursor);
+ break;
+ case SouthResize:
+ case SouthPanning:
+ m_platformCursor = new QCursor(Qt::SizeVerCursor);
+ break;
+ case SouthEastResize:
+ case SouthEastPanning:
+ m_platformCursor = new QCursor(Qt::SizeFDiagCursor);
+ break;
+ case SouthWestResize:
+ case SouthWestPanning:
+ m_platformCursor = new QCursor(Qt::SizeBDiagCursor);
+ break;
+ case WestResize:
+ case WestPanning:
+ m_platformCursor = new QCursor(Qt::SizeHorCursor);
+ break;
+ case NorthSouthResize:
+ m_platformCursor = new QCursor(Qt::SizeVerCursor);
+ break;
+ case EastWestResize:
+ m_platformCursor = new QCursor(Qt::SizeHorCursor);
+ break;
+ case NorthEastSouthWestResize:
+ m_platformCursor = new QCursor(Qt::SizeBDiagCursor);
+ break;
+ case NorthWestSouthEastResize:
+ m_platformCursor = new QCursor(Qt::SizeFDiagCursor);
+ break;
+ case ColumnResize:
+ m_platformCursor = new QCursor(Qt::SplitHCursor);
+ break;
+ case RowResize:
+ m_platformCursor = new QCursor(Qt::SplitVCursor);
+ break;
+ case MiddlePanning:
+ case Move:
+ m_platformCursor = new QCursor(Qt::SizeAllCursor);
+ break;
+ case None:
+ m_platformCursor = new QCursor(Qt::BlankCursor);
+ break;
+ case NoDrop:
+ case NotAllowed:
+ m_platformCursor = new QCursor(Qt::ForbiddenCursor);
+ break;
+ case Grab:
+ case Grabbing:
+ notImplemented();
+ m_platformCursor = new QCursor(Qt::ArrowCursor);
+ break;
+ case VerticalText:
+ m_platformCursor = new QCursor(QPixmap(QLatin1String(":/webkit/resources/verticalTextCursor.png")), 7, 7);
+ break;
+ case Cell:
+ m_platformCursor = new QCursor(QPixmap(QLatin1String(":/webkit/resources/cellCursor.png")), 7, 7);
+ break;
+ case ContextMenu:
+ m_platformCursor = new QCursor(QPixmap(QLatin1String(":/webkit/resources/contextMenuCursor.png")), 3, 2);
+ break;
+ case Alias:
+ m_platformCursor = new QCursor(QPixmap(QLatin1String(":/webkit/resources/aliasCursor.png")), 11, 3);
+ break;
+ case Progress:
+ m_platformCursor = new QCursor(QPixmap(QLatin1String(":/webkit/resources/progressCursor.png")), 3, 2);
+ break;
+ case Copy:
+ m_platformCursor = new QCursor(QPixmap(QLatin1String(":/webkit/resources/copyCursor.png")), 3, 2);
+ break;
+ case ZoomIn:
+ m_platformCursor = new QCursor(QPixmap(QLatin1String(":/webkit/resources/zoomInCursor.png")), 7, 7);
+ break;
+ case ZoomOut:
+ m_platformCursor = new QCursor(QPixmap(QLatin1String(":/webkit/resources/zoomOutCursor.png")), 7, 7);
+ break;
+ case Custom:
+ m_platformCursor = createCustomCursor(m_image.get(), m_hotSpot);
+ break;
+ default:
+ ASSERT_NOT_REACHED();
+ }
+#endif
}
}
diff --git a/WebCore/platform/qt/PasteboardQt.cpp b/WebCore/platform/qt/PasteboardQt.cpp
index e1e6d84..fc53124 100644
--- a/WebCore/platform/qt/PasteboardQt.cpp
+++ b/WebCore/platform/qt/PasteboardQt.cpp
@@ -65,10 +65,7 @@ void Pasteboard::writeSelection(Range* selectedRange, bool canSmartCopyOrDelete,
text.replace(QChar(0xa0), QLatin1Char(' '));
md->setText(text);
- QString html = QLatin1String("<html><head><meta http-equiv=\"Content-Type\" content=\"text/html; charset=utf-8\" /></head><body>");
- html += createMarkup(selectedRange, 0, AnnotateForInterchange, false, AbsoluteURLs);
- html += QLatin1String("</body></html>");
- md->setHtml(html);
+ md->setHtml(createMarkup(selectedRange, 0, AnnotateForInterchange, false, AbsoluteURLs));
#ifndef QT_NO_CLIPBOARD
QApplication::clipboard()->setMimeData(md, m_selectionMode ?
diff --git a/WebCore/platform/qt/WidgetQt.cpp b/WebCore/platform/qt/WidgetQt.cpp
index 0903b6e..e64d655 100644
--- a/WebCore/platform/qt/WidgetQt.cpp
+++ b/WebCore/platform/qt/WidgetQt.cpp
@@ -78,10 +78,10 @@ void Widget::setFocus(bool focused)
void Widget::setCursor(const Cursor& cursor)
{
#ifndef QT_NO_CURSOR
- QWebPageClient* pageClient = root()->hostWindow()->platformPageClient();
-
- if (pageClient)
- pageClient->setCursor(cursor.impl());
+ ScrollView* view = root();
+ if (!view)
+ return;
+ view->hostWindow()->setCursor(cursor);
#endif
}
diff --git a/WebCore/platform/sql/SQLiteStatement.cpp b/WebCore/platform/sql/SQLiteStatement.cpp
index 4dc80fb..037ec79 100644
--- a/WebCore/platform/sql/SQLiteStatement.cpp
+++ b/WebCore/platform/sql/SQLiteStatement.cpp
@@ -192,6 +192,14 @@ int SQLiteStatement::bindText(int index, const String& text)
return sqlite3_bind_text16(m_statement, index, characters, sizeof(UChar) * text.length(), SQLITE_TRANSIENT);
}
+int SQLiteStatement::bindInt(int index, int integer)
+{
+ ASSERT(m_isPrepared);
+ ASSERT(index > 0);
+ ASSERT(static_cast<unsigned>(index) <= bindParameterCount());
+
+ return sqlite3_bind_int(m_statement, index, integer);
+}
int SQLiteStatement::bindInt64(int index, int64_t integer)
{
@@ -251,6 +259,18 @@ int SQLiteStatement::columnCount()
return sqlite3_data_count(m_statement);
}
+bool SQLiteStatement::isColumnNull(int col)
+{
+ ASSERT(col >= 0);
+ if (!m_statement)
+ if (prepareAndStep() != SQLITE_ROW)
+ return false;
+ if (columnCount() <= col)
+ return false;
+
+ return sqlite3_column_type(m_statement, col) == SQLITE_NULL;
+}
+
String SQLiteStatement::getColumnName(int col)
{
ASSERT(col >= 0);
diff --git a/WebCore/platform/sql/SQLiteStatement.h b/WebCore/platform/sql/SQLiteStatement.h
index e62b4f0..1444f0e 100644
--- a/WebCore/platform/sql/SQLiteStatement.h
+++ b/WebCore/platform/sql/SQLiteStatement.h
@@ -42,6 +42,7 @@ public:
int prepare();
int bindBlob(int index, const void* blob, int size);
int bindText(int index, const String&);
+ int bindInt(int index, int);
int bindInt64(int index, int64_t);
int bindDouble(int index, double);
int bindNull(int index);
@@ -70,6 +71,7 @@ public:
// returned in the last step()
int columnCount();
+ bool isColumnNull(int col);
String getColumnName(int col);
SQLValue getColumnValue(int col);
String getColumnText(int col);
diff --git a/WebCore/platform/text/TextCodecLatin1.cpp b/WebCore/platform/text/TextCodecLatin1.cpp
index 4f9cbe0..2a217c5 100644
--- a/WebCore/platform/text/TextCodecLatin1.cpp
+++ b/WebCore/platform/text/TextCodecLatin1.cpp
@@ -164,7 +164,7 @@ String TextCodecLatin1::decode(const char* bytes, size_t length, bool, bool, boo
// Wait until we're at a properly aligned address, then read full CPU words.
if (!(reinterpret_cast<ptrdiff_t>(src) & (sizeof(uintptr_t) - 1))) {
while (src < alignedEnd) {
- uintptr_t chunk = *reinterpret_cast<const uintptr_t*>(src);
+ uintptr_t chunk = *reinterpret_cast_ptr<const uintptr_t*>(src);
if (chunk & NonASCIIMask<sizeof(uintptr_t)>::value())
goto useLookupTable;
diff --git a/WebCore/platform/text/qt/TextCodecQt.cpp b/WebCore/platform/text/qt/TextCodecQt.cpp
index 735d773..94a2b7b 100644
--- a/WebCore/platform/text/qt/TextCodecQt.cpp
+++ b/WebCore/platform/text/qt/TextCodecQt.cpp
@@ -110,7 +110,7 @@ String TextCodecQt::decode(const char* bytes, size_t length, bool flush, bool /*
int size = end - buf;
size = qMin(size, MaxInputChunkSize);
QString decoded = m_codec->toUnicode(buf, size, &m_state);
- unicode.append(decoded);
+ unicode.append(reinterpret_cast_ptr<const UChar*>(decoded.unicode()), decoded.length());
buf += size;
}
diff --git a/WebCore/platform/win/BitmapInfo.cpp b/WebCore/platform/win/BitmapInfo.cpp
index 514f722..610a27e 100644
--- a/WebCore/platform/win/BitmapInfo.cpp
+++ b/WebCore/platform/win/BitmapInfo.cpp
@@ -33,21 +33,14 @@
namespace WebCore {
-BitmapInfo bitmapInfoForSize(int width, int height, WORD bitCount)
+BitmapInfo bitmapInfoForSize(int width, int height, BitmapInfo::BitCount bitCount)
{
- ASSERT_ARG(bitCount, bitCount == 16 || bitCount == 32);
-
BitmapInfo bitmapInfo;
bitmapInfo.bmiHeader.biWidth = width;
bitmapInfo.bmiHeader.biHeight = height;
bitmapInfo.bmiHeader.biPlanes = 1;
bitmapInfo.bmiHeader.biBitCount = bitCount;
bitmapInfo.bmiHeader.biCompression = BI_RGB;
- bitmapInfo.bmiHeader.biSizeImage = 0;
- bitmapInfo.bmiHeader.biXPelsPerMeter = 0;
- bitmapInfo.bmiHeader.biYPelsPerMeter = 0;
- bitmapInfo.bmiHeader.biClrUsed = 0;
- bitmapInfo.bmiHeader.biClrImportant = 0;
return bitmapInfo;
}
@@ -58,12 +51,12 @@ BitmapInfo::BitmapInfo()
bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
}
-BitmapInfo BitmapInfo::create(const IntSize& size, WORD bitCount)
+BitmapInfo BitmapInfo::create(const IntSize& size, BitCount bitCount)
{
return bitmapInfoForSize(size.width(), size.height(), bitCount);
}
-BitmapInfo BitmapInfo::createBottomUp(const IntSize& size, WORD bitCount)
+BitmapInfo BitmapInfo::createBottomUp(const IntSize& size, BitCount bitCount)
{
return bitmapInfoForSize(size.width(), -size.height(), bitCount);
}
diff --git a/WebCore/platform/win/BitmapInfo.h b/WebCore/platform/win/BitmapInfo.h
index d1c3319..caf1b31 100644
--- a/WebCore/platform/win/BitmapInfo.h
+++ b/WebCore/platform/win/BitmapInfo.h
@@ -35,19 +35,30 @@
namespace WebCore {
struct BitmapInfo : public BITMAPINFO {
+ enum BitCount {
+ BitCount1 = 1,
+ BitCount4 = 4,
+ BitCount8 = 8,
+ BitCount16 = 16,
+ BitCount24 = 24,
+ BitCount32 = 32
+ };
+
BitmapInfo();
- static BitmapInfo create(const IntSize&, WORD bitCount = 32);
- static BitmapInfo createBottomUp(const IntSize&, WORD bitCount = 32);
+ static BitmapInfo create(const IntSize&, BitCount bitCount = BitCount32);
+ static BitmapInfo createBottomUp(const IntSize&, BitCount bitCount = BitCount32);
bool is16bit() const { return bmiHeader.biBitCount == 16; }
bool is32bit() const { return bmiHeader.biBitCount == 32; }
unsigned width() const { return abs(bmiHeader.biWidth); }
unsigned height() const { return abs(bmiHeader.biHeight); }
IntSize size() const { return IntSize(width(), height()); }
- unsigned paddedWidth() const { return is16bit() ? (width() + 1) & ~0x1 : width(); }
+ unsigned bytesPerLine() const { return (width() * bmiHeader.biBitCount + 7) / 8; }
+ unsigned paddedBytesPerLine() const { return (bytesPerLine() + 3) & ~0x3; }
+ unsigned paddedWidth() const { return paddedBytesPerLine() * 8 / bmiHeader.biBitCount; }
unsigned numPixels() const { return paddedWidth() * height(); }
- unsigned paddedBytesPerLine() const { return is16bit() ? paddedWidth() * 2 : width() * 4; }
- unsigned bytesPerLine() const { return width() * bmiHeader.biBitCount / 8; }};
+};
+
} // namespace WebCore
#endif // BitmapInfo_h
diff --git a/WebCore/platform/win/PopupMenuWin.cpp b/WebCore/platform/win/PopupMenuWin.cpp
index aaadc53..6e22024 100644
--- a/WebCore/platform/win/PopupMenuWin.cpp
+++ b/WebCore/platform/win/PopupMenuWin.cpp
@@ -581,7 +581,7 @@ void PopupMenuWin::paint(const IntRect& damageRect, HDC hdc)
}
if (!m_bmp) {
#if OS(WINCE)
- BitmapInfo bitmapInfo = BitmapInfo::createBottomUp(clientRect().size(), 16);
+ BitmapInfo bitmapInfo = BitmapInfo::createBottomUp(clientRect().size(), BitmapInfo::BitCount16);
#else
BitmapInfo bitmapInfo = BitmapInfo::createBottomUp(clientRect().size());
#endif
diff --git a/WebCore/plugins/PluginView.cpp b/WebCore/plugins/PluginView.cpp
index 5a33b78..d410948 100644
--- a/WebCore/plugins/PluginView.cpp
+++ b/WebCore/plugins/PluginView.cpp
@@ -85,6 +85,8 @@ using JSC::JSValue;
using JSC::UString;
#endif
+#if ENABLE(NETSCAPE_PLUGIN_API)
+
using std::min;
using namespace WTF;
@@ -1486,3 +1488,5 @@ void PluginView::privateBrowsingStateChanged(bool privateBrowsingEnabled)
}
} // namespace WebCore
+
+#endif // ENABLE(NETSCAPE_PLUGIN_API)
diff --git a/WebCore/plugins/PluginView.h b/WebCore/plugins/PluginView.h
index 2b272ec..01797e5 100644
--- a/WebCore/plugins/PluginView.h
+++ b/WebCore/plugins/PluginView.h
@@ -32,11 +32,9 @@
#include "HaltablePlugin.h"
#include "IntRect.h"
#include "MediaCanStartListener.h"
-#include "PluginStream.h"
#include "ResourceRequest.h"
#include "Timer.h"
#include "Widget.h"
-#include "npruntime_internal.h"
#include <wtf/HashMap.h>
#include <wtf/HashSet.h>
#include <wtf/OwnPtr.h>
@@ -45,10 +43,16 @@
#include <wtf/Vector.h>
#include <wtf/text/CString.h>
+<<<<<<< HEAD
// ANDROID
// TODO: Upstream to webkit.org
#ifdef PLUGIN_SCHEDULE_TIMER
#include "PluginTimer.h"
+=======
+#if ENABLE(NETSCAPE_PLUGIN_API)
+#include "PluginStream.h"
+#include "npruntime_internal.h"
+>>>>>>> webkit.org at r66079
#endif
#if OS(WINDOWS) && (PLATFORM(QT) || PLATFORM(WX))
@@ -130,13 +134,21 @@ namespace WebCore {
virtual void didFail(const ResourceError&) = 0;
};
- class PluginView : public Widget, private PluginStreamClient, public PluginManualLoader, private HaltablePlugin, private MediaCanStartListener {
+ class PluginView : public Widget
+#if ENABLE(NETSCAPE_PLUGIN_API)
+ , private PluginStreamClient
+#endif
+ , public PluginManualLoader
+ , private HaltablePlugin
+ , private MediaCanStartListener {
public:
static PassRefPtr<PluginView> create(Frame* parentFrame, const IntSize&, Element*, const KURL&, const Vector<String>& paramNames, const Vector<String>& paramValues, const String& mimeType, bool loadManually);
virtual ~PluginView();
PluginPackage* plugin() const { return m_plugin.get(); }
+#if ENABLE(NETSCAPE_PLUGIN_API)
NPP instance() const { return m_instance; }
+#endif
void setNPWindowRect(const IntRect&);
static PluginView* currentPluginView();
@@ -147,6 +159,7 @@ namespace WebCore {
PluginStatus status() const { return m_status; }
+#if ENABLE(NETSCAPE_PLUGIN_API)
// NPN functions
NPError getURLNotify(const char* url, const char* target, void* notifyData);
NPError getURL(const char* url, const char* target);
@@ -155,6 +168,7 @@ namespace WebCore {
NPError newStream(NPMIMEType type, const char* target, NPStream** stream);
int32_t write(NPStream* stream, int32_t len, void* buffer);
NPError destroyStream(NPStream* stream, NPReason reason);
+#endif
const char* userAgent();
#if ENABLE(NETSCAPE_PLUGIN_API)
static const char* userAgentStatic();
@@ -164,10 +178,10 @@ namespace WebCore {
#if ENABLE(NETSCAPE_PLUGIN_API)
NPError getValue(NPNVariable variable, void* value);
static NPError getValueStatic(NPNVariable variable, void* value);
-#endif
NPError setValue(NPPVariable variable, void* value);
void invalidateRect(NPRect*);
void invalidateRegion(NPRegion);
+#endif
void forceRedraw();
void pushPopupsEnabledState(bool state);
void popPopupsEnabledState();
@@ -263,9 +277,11 @@ namespace WebCore {
void stop();
void platformDestroy();
static void setCurrentPluginView(PluginView*);
+#if ENABLE(NETSCAPE_PLUGIN_API)
NPError load(const FrameLoadRequest&, bool sendNotification, void* notifyData);
NPError handlePost(const char* url, const char* target, uint32_t len, const char* buf, bool file, void* notifyData, bool sendNotification, bool allowHeaders);
NPError handlePostReadFile(Vector<char>& buffer, uint32_t len, const char* buf);
+#endif
static void freeStringArray(char** stringArray, int length);
void setCallingPlugin(bool) const;
@@ -279,8 +295,10 @@ namespace WebCore {
static BOOL WINAPI hookedEndPaint(HWND, const PAINTSTRUCT*);
#endif
+#if ENABLE(NETSCAPE_PLUGIN_API)
static bool platformGetValueStatic(NPNVariable variable, void* value, NPError* result);
bool platformGetValue(NPNVariable variable, void* value, NPError* result);
+#endif
RefPtr<Frame> m_parentFrame;
RefPtr<PluginPackage> m_plugin;
@@ -305,7 +323,9 @@ namespace WebCore {
Timer<PluginView> m_lifeSupportTimer;
#ifndef NP_NO_CARBON
+#if ENABLE(NETSCAPE_PLUGIN_API)
bool dispatchNPEvent(NPEvent&);
+#endif // ENABLE(NETSCAPE_PLUGIN_API)
#endif
void updatePluginWidget();
void paintMissingPluginIcon(GraphicsContext*, const IntRect&);
@@ -342,9 +362,11 @@ namespace WebCore {
String m_mimeType;
WTF::CString m_userAgent;
+#if ENABLE(NETSCAPE_PLUGIN_API)
NPP m_instance;
NPP_t m_instanceStruct;
NPWindow m_npWindow;
+#endif
Vector<bool, 4> m_popupStateStack;
diff --git a/WebCore/plugins/PluginViewNone.cpp b/WebCore/plugins/PluginViewNone.cpp
index eb32cd1..ab8f620 100644
--- a/WebCore/plugins/PluginViewNone.cpp
+++ b/WebCore/plugins/PluginViewNone.cpp
@@ -66,12 +66,12 @@ void PluginView::setNPWindowRect(const IntRect&)
{
}
+#if ENABLE(NETSCAPE_PLUGIN_API)
NPError PluginView::handlePostReadFile(Vector<char>&, uint32_t, const char*)
{
return 0;
}
-#if ENABLE(NETSCAPE_PLUGIN_API)
bool PluginView::platformGetValue(NPNVariable, void*, NPError*)
{
return false;
@@ -81,19 +81,21 @@ bool PluginView::platformGetValueStatic(NPNVariable, void*, NPError*)
{
return false;
}
-#endif
void PluginView::invalidateRect(NPRect*)
{
}
+#endif
void PluginView::invalidateRect(const IntRect&)
{
}
+#if ENABLE(NETSCAPE_PLUGIN_API)
void PluginView::invalidateRegion(NPRegion)
{
}
+#endif
void PluginView::forceRedraw()
{
@@ -139,7 +141,7 @@ void PluginView::handleFocusOutEvent()
// ports using PluginView, but until then, if new functions like this are
// added, please make sure they have the proper platform #ifs so that changes
// do not break ports who compile both this file and PluginView.cpp.
-#if PLATFORM(MAC) || PLATFORM(CHROMIUM) || PLATFORM(EFL) || OS(WINCE) && !PLATFORM(QT)
+#if PLATFORM(MAC) || PLATFORM(CHROMIUM) || PLATFORM(EFL) || (OS(WINCE) && !PLATFORM(QT)) || (PLATFORM(QT) && !OS(WINCE))
#if ENABLE(NETSCAPE_PLUGIN_API)
void PluginView::keepAlive(NPP)
{
diff --git a/WebCore/plugins/gtk/gtk2xtbin.c b/WebCore/plugins/gtk/gtk2xtbin.c
index b7fd3f0..a0808d9 100644
--- a/WebCore/plugins/gtk/gtk2xtbin.c
+++ b/WebCore/plugins/gtk/gtk2xtbin.c
@@ -326,6 +326,8 @@ gtk_xtbin_new (GdkWindow *parent_window, String * f)
{
GtkXtBin *xtbin;
gpointer user_data;
+ GdkVisual* visual;
+ GdkColormap* colormap;
assert(parent_window != NULL);
xtbin = g_object_new (GTK_TYPE_XTBIN, NULL);
@@ -339,10 +341,13 @@ gtk_xtbin_new (GdkWindow *parent_window, String * f)
/* Initialize the Xt toolkit */
xtbin->parent_window = parent_window;
+ visual = gtk_widget_get_default_visual();
+ colormap = gtk_widget_get_default_colormap();
+
xt_client_init(&(xtbin->xtclient),
- GDK_VISUAL_XVISUAL(gdk_rgb_get_visual()),
- GDK_COLORMAP_XCOLORMAP(gdk_rgb_get_colormap()),
- gdk_visual_get_depth(gdk_rgb_get_visual()));
+ GDK_VISUAL_XVISUAL(visual),
+ GDK_COLORMAP_XCOLORMAP(colormap),
+ gdk_visual_get_depth(visual));
if (!xtbin->xtclient.xtdisplay) {
/* If XtOpenDisplay failed, we can't go any further.
diff --git a/WebCore/plugins/qt/PluginPackageQt.cpp b/WebCore/plugins/qt/PluginPackageQt.cpp
index 07149f3..d92fffe 100644
--- a/WebCore/plugins/qt/PluginPackageQt.cpp
+++ b/WebCore/plugins/qt/PluginPackageQt.cpp
@@ -35,8 +35,6 @@
namespace WebCore {
-typedef void gtkInitFunc(int *argc, char ***argv);
-
bool PluginPackage::fetchInfo()
{
if (!load())
@@ -92,6 +90,39 @@ static NPError staticPluginQuirkRequiresGtkToolKit_NPN_GetValue(NPP instance, NP
return NPN_GetValue(instance, variable, value);
}
+static void initializeGtk(QLibrary* module = 0)
+{
+ // Ensures missing Gtk initialization in some versions of Adobe's flash player
+ // plugin do not cause crashes. See BR# 40567, 44324, and 44405 for details.
+ if (module) {
+ typedef void *(*gtk_init_ptr)(int*, char***);
+ gtk_init_ptr gtkInit = (gtk_init_ptr)module->resolve("gtk_init");
+ if (gtkInit) {
+ // Prevent gtk_init() from replacing the X error handlers, since the Gtk
+ // handlers abort when they receive an X error, thus killing the viewer.
+#ifdef Q_WS_X11
+ int (*old_error_handler)(Display*, XErrorEvent*) = XSetErrorHandler(0);
+ int (*old_io_error_handler)(Display*) = XSetIOErrorHandler(0);
+#endif
+ gtkInit(0, 0);
+#ifdef Q_WS_X11
+ XSetErrorHandler(old_error_handler);
+ XSetIOErrorHandler(old_io_error_handler);
+#endif
+ return;
+ }
+ }
+
+ QLibrary library("libgtk-x11-2.0.so.0");
+ if (library.load()) {
+ typedef void *(*gtk_init_check_ptr)(int*, char***);
+ gtk_init_check_ptr gtkInitCheck = (gtk_init_check_ptr)library.resolve("gtk_init_check");
+ // NOTE: We're using gtk_init_check() since gtk_init() calls exit() on failure.
+ if (gtkInitCheck)
+ (void) gtkInitCheck(0, 0);
+ }
+}
+
bool PluginPackage::load()
{
if (m_isLoaded) {
@@ -111,7 +142,6 @@ bool PluginPackage::load()
NP_InitializeFuncPtr NP_Initialize;
NPError npErr;
- gtkInitFunc* gtkInit;
NP_Initialize = (NP_InitializeFuncPtr)m_module->resolve("NP_Initialize");
m_NPP_Shutdown = (NPP_ShutdownProcPtr)m_module->resolve("NP_Shutdown");
@@ -128,26 +158,13 @@ bool PluginPackage::load()
// nspluginwrapper relies on the toolkit value to know if glib is available
// It does so in NP_Initialize with a null instance, therefore it is done this way:
m_browserFuncs.getvalue = staticPluginQuirkRequiresGtkToolKit_NPN_GetValue;
- }
-
- // WORKAROUND: Prevent gtk based plugin crashes such as BR# 40567 by
- // explicitly forcing the initializing of Gtk, i.e. calling gtk_init,
- // whenver the symbol is present in the plugin library loaded above.
- // Note that this workaround is based on code from the NSPluginClass ctor
- // in KDE's kdebase/apps/nsplugins/viewer/nsplugin.cpp file.
- gtkInit = (gtkInitFunc*)m_module->resolve("gtk_init");
- if (gtkInit) {
- // Prevent gtk_init() from replacing the X error handlers, since the Gtk
- // handlers abort when they receive an X error, thus killing the viewer.
-#ifdef Q_WS_X11
- int (*old_error_handler)(Display*, XErrorEvent*) = XSetErrorHandler(0);
- int (*old_io_error_handler)(Display*) = XSetIOErrorHandler(0);
-#endif
- gtkInit(0, 0);
-#ifdef Q_WS_X11
- XSetErrorHandler(old_error_handler);
- XSetIOErrorHandler(old_io_error_handler);
-#endif
+ // Workaround Adobe's failure to properly initialize Gtk in some versions
+ // of their flash player plugin.
+ initializeGtk();
+ } else if (m_path.contains("flashplayer")) {
+ // Workaround Adobe's failure to properly initialize Gtk in some versions
+ // of their flash player plugin.
+ initializeGtk(m_module);
}
#if defined(XP_UNIX)
diff --git a/WebCore/plugins/qt/PluginViewQt.cpp b/WebCore/plugins/qt/PluginViewQt.cpp
index 3b41072..5c681b8 100644
--- a/WebCore/plugins/qt/PluginViewQt.cpp
+++ b/WebCore/plugins/qt/PluginViewQt.cpp
@@ -171,27 +171,49 @@ void PluginView::hide()
#if defined(MOZ_PLATFORM_MAEMO) && (MOZ_PLATFORM_MAEMO == 5)
void PluginView::paintUsingImageSurfaceExtension(QPainter* painter, const IntRect& exposedRect)
{
- if (m_isTransparent) {
- // On Maemo5, Flash expects the buffer to contain the contents that are below it.
- // We don't support transparency, so clean the image before giving to Flash.
- QPainter imagePainter(&m_image);
- imagePainter.fillRect(exposedRect, Qt::white);
- }
-
NPImageExpose imageExpose;
- imageExpose.data = reinterpret_cast<char*>(m_image.bits());
- imageExpose.stride = m_image.bytesPerLine();
- imageExpose.depth = m_image.depth();
+ QPoint offset;
+ QWebPageClient* client = m_parentFrame->view()->hostWindow()->platformPageClient();
+ const bool surfaceHasUntransformedContents = client && qobject_cast<QWidget*>(client->pluginParent());
+
+ QPaintDevice* surface = QPainter::redirected(painter->device(), &offset);
+
+ // If the surface is a QImage, we can render directly into it
+ if (surfaceHasUntransformedContents && surface && surface->devType() == QInternal::Image) {
+ QImage* image = static_cast<QImage*>(surface);
+ offset = -offset; // negating the offset gives us the offset of the view within the surface
+ imageExpose.data = reinterpret_cast<char*>(image->bits());
+ imageExpose.dataSize.width = image->width();
+ imageExpose.dataSize.height = image->height();
+ imageExpose.stride = image->bytesPerLine();
+ imageExpose.depth = image->depth(); // this is guaranteed to be 16 on Maemo5
+ imageExpose.translateX = offset.x() + m_windowRect.x();
+ imageExpose.translateY = offset.y() + m_windowRect.y();
+ imageExpose.scaleX = 1;
+ imageExpose.scaleY = 1;
+ } else {
+ if (m_isTransparent) {
+ // On Maemo5, Flash expects the buffer to contain the contents that are below it.
+ // We don't support transparency for non-raster graphicssystem, so clean the image
+ // before giving to Flash.
+ QPainter imagePainter(&m_image);
+ imagePainter.fillRect(exposedRect, Qt::white);
+ }
+
+ imageExpose.data = reinterpret_cast<char*>(m_image.bits());
+ imageExpose.dataSize.width = m_image.width();
+ imageExpose.dataSize.height = m_image.height();
+ imageExpose.stride = m_image.bytesPerLine();
+ imageExpose.depth = m_image.depth();
+ imageExpose.translateX = 0;
+ imageExpose.translateY = 0;
+ imageExpose.scaleX = 1;
+ imageExpose.scaleY = 1;
+ }
imageExpose.x = exposedRect.x();
imageExpose.y = exposedRect.y();
imageExpose.width = exposedRect.width();
imageExpose.height = exposedRect.height();
- imageExpose.dataSize.width = m_image.width();
- imageExpose.dataSize.height = m_image.height();
- imageExpose.translateX = 0;
- imageExpose.translateY = 0;
- imageExpose.scaleX = 1;
- imageExpose.scaleY = 1;
XEvent xevent;
memset(&xevent, 0, sizeof(XEvent));
@@ -206,7 +228,8 @@ void PluginView::paintUsingImageSurfaceExtension(QPainter* painter, const IntRec
dispatchNPEvent(xevent);
- painter->drawImage(QPoint(frameRect().x() + exposedRect.x(), frameRect().y() + exposedRect.y()), m_image, exposedRect);
+ if (!surfaceHasUntransformedContents || !surface || surface->devType() != QInternal::Image)
+ painter->drawImage(QPoint(frameRect().x() + exposedRect.x(), frameRect().y() + exposedRect.y()), m_image, exposedRect);
}
#endif
diff --git a/WebCore/rendering/HitTestResult.cpp b/WebCore/rendering/HitTestResult.cpp
index dd96e0e..496c4ba 100644
--- a/WebCore/rendering/HitTestResult.cpp
+++ b/WebCore/rendering/HitTestResult.cpp
@@ -166,7 +166,7 @@ String HitTestResult::spellingToolTip(TextDirection& dir) const
if (!m_innerNonSharedNode)
return String();
- DocumentMarker* marker = m_innerNonSharedNode->document()->markerContainingPoint(m_point, DocumentMarker::Grammar);
+ DocumentMarker* marker = m_innerNonSharedNode->document()->markers()->markerContainingPoint(m_point, DocumentMarker::Grammar);
if (!marker)
return String();
@@ -182,7 +182,7 @@ String HitTestResult::replacedString() const
if (!m_innerNonSharedNode)
return String();
- DocumentMarker* marker = m_innerNonSharedNode->document()->markerContainingPoint(m_point, DocumentMarker::Replacement);
+ DocumentMarker* marker = m_innerNonSharedNode->document()->markers()->markerContainingPoint(m_point, DocumentMarker::Replacement);
if (!marker)
return String();
diff --git a/WebCore/rendering/InlineTextBox.cpp b/WebCore/rendering/InlineTextBox.cpp
index 50f6cfa..cb4fdb8 100644
--- a/WebCore/rendering/InlineTextBox.cpp
+++ b/WebCore/rendering/InlineTextBox.cpp
@@ -810,7 +810,7 @@ void InlineTextBox::paintSpellingOrGrammarMarker(GraphicsContext* pt, int tx, in
if (grammar) {
markerRect.move(-tx, -ty);
markerRect = renderer()->localToAbsoluteQuad(FloatRect(markerRect)).enclosingBoundingBox();
- renderer()->document()->setRenderedRectForMarker(renderer()->node(), marker, markerRect);
+ renderer()->document()->markers()->setRenderedRectForMarker(renderer()->node(), marker, markerRect);
}
}
@@ -848,7 +848,7 @@ void InlineTextBox::paintTextMatchMarker(GraphicsContext* pt, int tx, int ty, co
// Always compute and store the rect associated with this marker. The computed rect is in absolute coordinates.
IntRect markerRect = enclosingIntRect(font.selectionRectForText(run, IntPoint(m_x, y), h, sPos, ePos));
markerRect = renderer()->localToAbsoluteQuad(FloatRect(markerRect)).enclosingBoundingBox();
- renderer()->document()->setRenderedRectForMarker(renderer()->node(), marker, markerRect);
+ renderer()->document()->markers()->setRenderedRectForMarker(renderer()->node(), marker, markerRect);
// Optionally highlight the text
if (renderer()->frame()->markedTextMatchesAreHighlighted()) {
@@ -877,7 +877,7 @@ void InlineTextBox::computeRectForReplacementMarker(int /*tx*/, int /*ty*/, cons
// Compute and store the rect associated with this marker.
IntRect markerRect = enclosingIntRect(font.selectionRectForText(run, startPoint, h, sPos, ePos));
markerRect = renderer()->localToAbsoluteQuad(FloatRect(markerRect)).enclosingBoundingBox();
- renderer()->document()->setRenderedRectForMarker(renderer()->node(), marker, markerRect);
+ renderer()->document()->markers()->setRenderedRectForMarker(renderer()->node(), marker, markerRect);
}
void InlineTextBox::paintDocumentMarkers(GraphicsContext* pt, int tx, int ty, RenderStyle* style, const Font& font, bool background)
@@ -885,7 +885,7 @@ void InlineTextBox::paintDocumentMarkers(GraphicsContext* pt, int tx, int ty, Re
if (!renderer()->node())
return;
- Vector<DocumentMarker> markers = renderer()->document()->markersForNode(renderer()->node());
+ Vector<DocumentMarker> markers = renderer()->document()->markers()->markersForNode(renderer()->node());
Vector<DocumentMarker>::iterator markerIt = markers.begin();
// Give any document markers that touch this run a chance to draw before the text has been drawn.
diff --git a/WebCore/rendering/MediaControlElements.cpp b/WebCore/rendering/MediaControlElements.cpp
index d4eb9a9..3fb712f 100644
--- a/WebCore/rendering/MediaControlElements.cpp
+++ b/WebCore/rendering/MediaControlElements.cpp
@@ -135,7 +135,9 @@ PassRefPtr<MediaControlElement> MediaControlElement::create(HTMLMediaElement* me
void MediaControlElement::attachToParent(Element* parent)
{
- parent->legacyParserAddChild(this);
+ // FIXME: This code seems very wrong. Why are we magically adding |this| to the DOM here?
+ // We shouldn't be calling parser API methods outside of the parser!
+ parent->parserAddChild(this);
}
void MediaControlElement::update()
@@ -392,7 +394,9 @@ MediaControlInputElement::MediaControlInputElement(HTMLMediaElement* mediaElemen
void MediaControlInputElement::attachToParent(Element* parent)
{
- parent->legacyParserAddChild(this);
+ // FIXME: This code seems very wrong. Why are we magically adding |this| to the DOM here?
+ // We shouldn't be calling parser API methods outside of the parser!
+ parent->parserAddChild(this);
}
void MediaControlInputElement::update()
diff --git a/WebCore/rendering/MediaControlElements.h b/WebCore/rendering/MediaControlElements.h
index ceb0255..1dcf6be 100644
--- a/WebCore/rendering/MediaControlElements.h
+++ b/WebCore/rendering/MediaControlElements.h
@@ -81,7 +81,7 @@ private:
MediaControlShadowRootElement(HTMLMediaElement*);
virtual bool isShadowNode() const { return true; }
- virtual Node* shadowParentNode() { return m_mediaElement; }
+ virtual ContainerNode* shadowParentNode() { return m_mediaElement; }
HTMLMediaElement* m_mediaElement;
};
diff --git a/WebCore/rendering/PaintInfo.h b/WebCore/rendering/PaintInfo.h
index 213eb30..3598807 100644
--- a/WebCore/rendering/PaintInfo.h
+++ b/WebCore/rendering/PaintInfo.h
@@ -86,10 +86,16 @@ struct PaintInfo {
return;
context->concatCTM(localToAncestorTransform);
+
+ if (rect == infiniteRect())
+ return;
+
rect = localToAncestorTransform.inverse().mapRect(rect);
}
#endif
+ static IntRect infiniteRect() { return IntRect(INT_MIN / 2, INT_MIN / 2, INT_MAX, INT_MAX); }
+
// FIXME: Introduce setters/getters at some point. Requires a lot of changes throughout rendering/.
GraphicsContext* context;
IntRect rect;
diff --git a/WebCore/rendering/RenderBlock.cpp b/WebCore/rendering/RenderBlock.cpp
index 02b0079..28d7914 100644
--- a/WebCore/rendering/RenderBlock.cpp
+++ b/WebCore/rendering/RenderBlock.cpp
@@ -1265,8 +1265,8 @@ void RenderBlock::layoutBlock(bool relayoutChildren)
int repaintRight = max(rightVisualOverflow(), rightLayoutOverflow());
IntRect repaintRect(repaintLeft, repaintTop, repaintRight - repaintLeft, repaintBottom - repaintTop);
- // FIXME: Deal with multiple column repainting. We have to split the repaint
- // rect up into multiple rects if it spans columns.
+ // The repaint rect may be split across columns, in which case adjustRectForColumns() will return the union.
+ adjustRectForColumns(repaintRect);
repaintRect.inflate(maximalOutlineSize(PaintPhaseOutline));
diff --git a/WebCore/rendering/RenderCounter.cpp b/WebCore/rendering/RenderCounter.cpp
index 3cb9a07..6e678e8 100644
--- a/WebCore/rendering/RenderCounter.cpp
+++ b/WebCore/rendering/RenderCounter.cpp
@@ -136,6 +136,11 @@ static bool findPlaceForCounter(RenderObject* counterOwner, const AtomicString&
RenderObject* currentRenderer = counterOwner->previousInPreOrder();
previousSibling = 0;
while (currentRenderer) {
+ // A sibling without a parent means that the counter node tree was not constructed correctly so we stop
+ // traversing. In the future RenderCounter should handle RenderObjects that are not connected to the
+ // render tree at counter node creation. See bug 43812.
+ if (previousSibling && !previousSibling->parent())
+ return false;
CounterNode* currentCounter = makeCounterNode(currentRenderer, identifier, false);
if (searchEndRenderer == currentRenderer) {
// We may be at the end of our search.
diff --git a/WebCore/rendering/RenderLayer.cpp b/WebCore/rendering/RenderLayer.cpp
index df80a7c..347fa32 100644
--- a/WebCore/rendering/RenderLayer.cpp
+++ b/WebCore/rendering/RenderLayer.cpp
@@ -1359,7 +1359,7 @@ void RenderLayer::scrollToOffset(int x, int y, bool updateScrollbars, bool repai
Frame* frame = renderer()->frame();
if (frame) {
// The caret rect needs to be invalidated after scrolling
- frame->selection()->setNeedsLayout();
+ frame->selection()->setCaretRectNeedsUpdate();
FloatQuad quadForFakeMouseMoveEvent = FloatQuad(rectForRepaint);
if (repaintContainer)
@@ -3128,7 +3128,7 @@ void RenderLayer::calculateClipRects(const RenderLayer* rootLayer, ClipRects& cl
{
if (!parent()) {
// The root layer's clip rect is always infinite.
- clipRects.reset(ClipRects::infiniteRect());
+ clipRects.reset(PaintInfo::infiniteRect());
return;
}
@@ -3144,7 +3144,7 @@ void RenderLayer::calculateClipRects(const RenderLayer* rootLayer, ClipRects& cl
parentLayer->calculateClipRects(rootLayer, clipRects);
}
else
- clipRects.reset(ClipRects::infiniteRect());
+ clipRects.reset(PaintInfo::infiniteRect());
// A fixed object is essentially the root of its containing block hierarchy, so when
// we encounter such an object, we reset our clip rects to the fixedClipRect.
diff --git a/WebCore/rendering/RenderLayer.h b/WebCore/rendering/RenderLayer.h
index ba79292..17521ad 100644
--- a/WebCore/rendering/RenderLayer.h
+++ b/WebCore/rendering/RenderLayer.h
@@ -145,8 +145,6 @@ public:
m_fixed = other.fixed();
return *this;
}
-
- static IntRect infiniteRect() { return IntRect(INT_MIN/2, INT_MIN/2, INT_MAX, INT_MAX); }
private:
// The normal operator new is disallowed on all render objects.
diff --git a/WebCore/rendering/RenderLayerBacking.cpp b/WebCore/rendering/RenderLayerBacking.cpp
index 0db94dc..23645d5 100644
--- a/WebCore/rendering/RenderLayerBacking.cpp
+++ b/WebCore/rendering/RenderLayerBacking.cpp
@@ -276,7 +276,7 @@ bool RenderLayerBacking::updateGraphicsLayerConfiguration()
static IntRect clipBox(RenderBox* renderer)
{
- IntRect result = ClipRects::infiniteRect();
+ IntRect result = PaintInfo::infiniteRect();
if (renderer->hasOverflowClip())
result = renderer->overflowClipRect(0, 0);
diff --git a/WebCore/rendering/RenderLayerCompositor.cpp b/WebCore/rendering/RenderLayerCompositor.cpp
index 72a2d32..d125a24 100644
--- a/WebCore/rendering/RenderLayerCompositor.cpp
+++ b/WebCore/rendering/RenderLayerCompositor.cpp
@@ -97,6 +97,7 @@ struct CompositingState {
RenderLayerCompositor::RenderLayerCompositor(RenderView* renderView)
: m_renderView(renderView)
, m_rootPlatformLayer(0)
+ , m_updateCompositingLayersTimer(this, &RenderLayerCompositor::updateCompositingLayersTimerFired)
, m_hasAcceleratedCompositing(true)
, m_showDebugBorders(false)
, m_showRepaintCounter(false)
@@ -174,8 +175,26 @@ void RenderLayerCompositor::scheduleSync()
page->chrome()->client()->scheduleCompositingLayerSync();
}
+void RenderLayerCompositor::scheduleCompositingLayerUpdate()
+{
+ if (!m_updateCompositingLayersTimer.isActive())
+ m_updateCompositingLayersTimer.startOneShot(0);
+}
+
+bool RenderLayerCompositor::compositingLayerUpdatePending() const
+{
+ return m_updateCompositingLayersTimer.isActive();
+}
+
+void RenderLayerCompositor::updateCompositingLayersTimerFired(Timer<RenderLayerCompositor>*)
+{
+ updateCompositingLayers();
+}
+
void RenderLayerCompositor::updateCompositingLayers(CompositingUpdateType updateType, RenderLayer* updateRoot)
{
+ m_updateCompositingLayersTimer.stop();
+
if (!m_compositingDependsOnGeometry && !m_compositing)
return;
@@ -1225,7 +1244,7 @@ bool RenderLayerCompositor::clippedByAncestor(RenderLayer* layer) const
return false;
IntRect backgroundRect = layer->backgroundClipRect(computeClipRoot, true);
- return backgroundRect != ClipRects::infiniteRect();
+ return backgroundRect != PaintInfo::infiniteRect();
}
// Return true if the given layer is a stacking context and has compositing child
@@ -1483,7 +1502,7 @@ void RenderLayerCompositor::detachRootPlatformLayer()
else
m_rootPlatformLayer->removeFromParent();
- if (Element* ownerElement = m_renderView->document()->ownerElement())
+ if (HTMLFrameOwnerElement* ownerElement = m_renderView->document()->ownerElement())
scheduleNeedsStyleRecalc(ownerElement);
break;
}
@@ -1544,6 +1563,11 @@ void RenderLayerCompositor::notifyIFramesOfCompositingChange()
if (child->document() && child->document()->ownerElement())
scheduleNeedsStyleRecalc(child->document()->ownerElement());
}
+
+ // Compositing also affects the answer to RenderIFrame::requiresAcceleratedCompositing(), so
+ // we need to schedule a style recalc in our parent document.
+ if (HTMLFrameOwnerElement* ownerElement = m_renderView->document()->ownerElement())
+ scheduleNeedsStyleRecalc(ownerElement);
}
bool RenderLayerCompositor::layerHas3DContent(const RenderLayer* layer) const
diff --git a/WebCore/rendering/RenderLayerCompositor.h b/WebCore/rendering/RenderLayerCompositor.h
index 67623d4..917d610 100644
--- a/WebCore/rendering/RenderLayerCompositor.h
+++ b/WebCore/rendering/RenderLayerCompositor.h
@@ -88,7 +88,11 @@ public:
// Rebuild the tree of compositing layers
void updateCompositingLayers(CompositingUpdateType = CompositingUpdateAfterLayoutOrStyleChange, RenderLayer* updateRoot = 0);
-
+ // This is only used when state changes and we do not exepect a style update or layout to happen soon (e.g. when
+ // we discover that an iframe is overlapped during painting).
+ void scheduleCompositingLayerUpdate();
+ bool compositingLayerUpdatePending() const;
+
// Update the compositing state of the given layer. Returns true if that state changed.
enum CompositingChangeRepaint { CompositingChangeRepaintNow, CompositingChangeWillRepaintLater };
bool updateLayerCompositingState(RenderLayer*, CompositingChangeRepaint = CompositingChangeRepaintNow);
@@ -179,6 +183,8 @@ private:
static void addToOverlapMap(OverlapMap&, RenderLayer*, IntRect& layerBounds, bool& boundsComputed);
static bool overlapsCompositedLayers(OverlapMap&, const IntRect& layerBounds);
+ void updateCompositingLayersTimerFired(Timer<RenderLayerCompositor>*);
+
// Returns true if any layer's compositing changed
void computeCompositingRequirements(RenderLayer*, OverlapMap*, struct CompositingState&, bool& layersChanged);
@@ -224,6 +230,8 @@ private:
private:
RenderView* m_renderView;
OwnPtr<GraphicsLayer> m_rootPlatformLayer;
+ Timer<RenderLayerCompositor> m_updateCompositingLayersTimer;
+
bool m_hasAcceleratedCompositing;
bool m_showDebugBorders;
bool m_showRepaintCounter;
diff --git a/WebCore/rendering/RenderListMarker.cpp b/WebCore/rendering/RenderListMarker.cpp
index e148c81..6ff1709 100644
--- a/WebCore/rendering/RenderListMarker.cpp
+++ b/WebCore/rendering/RenderListMarker.cpp
@@ -48,8 +48,7 @@ static String toRoman(int number, bool upper)
// FIXME: CSS3 describes how to make this work for much larger numbers,
// using overbars and special characters. It also specifies the characters
// in the range U+2160 to U+217F instead of standard ASCII ones.
- if (number < 1 || number > 3999)
- return String::number(number);
+ ASSERT(number >= 1 && number <= 3999);
// Big enough to store largest roman number less than 3999 which
// is 3888 (MMMDCCCLXXXVIII)
@@ -118,9 +117,6 @@ static inline String toAlphabeticOrNumeric(int number, const UChar* sequence, in
static String toAlphabetic(int number, const UChar* alphabet, int alphabetSize)
{
- if (number < 1)
- return String::number(number);
-
return toAlphabeticOrNumeric(number, alphabet, alphabetSize, AlphabeticSequence);
}
@@ -170,8 +166,7 @@ static int toHebrewUnder1000(int number, UChar letters[5])
static String toHebrew(int number)
{
// FIXME: CSS3 mentions ways to make this work for much larger numbers.
- if (number < 0 || number > 999999)
- return String::number(number);
+ ASSERT(number >= 0 && number <= 999999);
if (number == 0) {
static const UChar hebrewZero[3] = { 0x05D0, 0x05E4, 0x05E1 };
@@ -238,8 +233,7 @@ static int toArmenianUnder10000(int number, bool upper, bool addCircumflex, UCha
static String toArmenian(int number, bool upper)
{
- if (number < 1 || number > 99999999)
- return String::number(number);
+ ASSERT(number >= 1 && number <= 99999999);
const int lettersSize = 18; // twice what toArmenianUnder10000 needs
UChar letters[lettersSize];
@@ -253,8 +247,7 @@ static String toArmenian(int number, bool upper)
static String toGeorgian(int number)
{
- if (number < 1 || number > 19999)
- return String::number(number);
+ ASSERT(number >= 1 && number <= 19999);
const int lettersSize = 5;
UChar letters[lettersSize];
@@ -300,8 +293,7 @@ static String toGeorgian(int number)
// first 3 group markers, then 3 digit markers, then ten digits.
static String toCJKIdeographic(int number, const UChar table[16])
{
- if (number < 0)
- return String::number(number);
+ ASSERT(number >= 0);
enum AbstractCJKChar {
noChar,
@@ -379,11 +371,110 @@ static String toCJKIdeographic(int number, const UChar table[16])
return String(characters, length);
}
-static UChar listMarkerSuffix(EListStyleType type)
+static EListStyleType effectiveListMarkerType(EListStyleType type, int value)
+{
+ // Note, the following switch statement has been explicitly grouped
+ // by list-style-type ordinal range.
+ switch (type) {
+ case ArabicIndic:
+ case Bengali:
+ case BinaryListStyle:
+ case Cambodian:
+ case Circle:
+ case DecimalLeadingZero:
+ case DecimalListStyle:
+ case Devanagari:
+ case Disc:
+ case Gujarati:
+ case Gurmukhi:
+ case Kannada:
+ case Khmer:
+ case Lao:
+ case LowerHexadecimal:
+ case Malayalam:
+ case Mongolian:
+ case Myanmar:
+ case NoneListStyle:
+ case Octal:
+ case Oriya:
+ case Persian:
+ case Square:
+ case Telugu:
+ case Thai:
+ case Tibetan:
+ case UpperHexadecimal:
+ case Urdu:
+ return type; // Can represent all ordinals.
+ case Armenian:
+ return (value < 1 || value > 99999999) ? DecimalListStyle : type;
+ case CJKIdeographic:
+ return (value < 0) ? DecimalListStyle : type;
+ case Georgian:
+ return (value < 1 || value > 19999) ? DecimalListStyle : type;
+ case Hebrew:
+ return (value < 0 || value > 999999) ? DecimalListStyle : type;
+ case LowerRoman:
+ case UpperRoman:
+ return (value < 1 || value > 3999) ? DecimalListStyle : type;
+ case Afar:
+ case Amharic:
+ case AmharicAbegede:
+ case CjkEarthlyBranch:
+ case CjkHeavenlyStem:
+ case Ethiopic:
+ case EthiopicAbegede:
+ case EthiopicAbegedeAmEt:
+ case EthiopicAbegedeGez:
+ case EthiopicAbegedeTiEr:
+ case EthiopicAbegedeTiEt:
+ case EthiopicHalehameAaEr:
+ case EthiopicHalehameAaEt:
+ case EthiopicHalehameAmEt:
+ case EthiopicHalehameGez:
+ case EthiopicHalehameOmEt:
+ case EthiopicHalehameSidEt:
+ case EthiopicHalehameSoEt:
+ case EthiopicHalehameTiEr:
+ case EthiopicHalehameTiEt:
+ case EthiopicHalehameTig:
+ case Hangul:
+ case HangulConsonant:
+ case Hiragana:
+ case HiraganaIroha:
+ case Katakana:
+ case KatakanaIroha:
+ case LowerAlpha:
+ case LowerGreek:
+ case LowerLatin:
+ case LowerNorwegian:
+ case Oromo:
+ case Sidama:
+ case Somali:
+ case Tigre:
+ case TigrinyaEr:
+ case TigrinyaErAbegede:
+ case TigrinyaEt:
+ case TigrinyaEtAbegede:
+ case UpperAlpha:
+ case UpperGreek:
+ case UpperLatin:
+ case UpperNorwegian:
+ return (value < 1) ? DecimalListStyle : type;
+ }
+
+ ASSERT_NOT_REACHED();
+ return type;
+}
+
+static UChar listMarkerSuffix(EListStyleType type, int value)
{
+ // If the list-style-type cannot represent |value| because it's outside its
+ // ordinal range then we fall back to some list style that can represent |value|.
+ EListStyleType effectiveType = effectiveListMarkerType(type, value);
+
// Note, the following switch statement has been explicitly
// grouped by list-style-type suffix.
- switch (type) {
+ switch (effectiveType) {
case NoneListStyle:
case Disc:
case Circle:
@@ -473,7 +564,9 @@ static UChar listMarkerSuffix(EListStyleType type)
String listMarkerText(EListStyleType type, int value)
{
- switch (type) {
+ // If the list-style-type, say hebrew, cannot represent |value| because it's outside
+ // its ordinal range then we fallback to some list style that can represent |value|.
+ switch (effectiveListMarkerType(type, value)) {
case NoneListStyle:
return "";
@@ -1122,7 +1215,7 @@ void RenderListMarker::paint(PaintInfo& paintInfo, int tx, int ty)
}
const Font& font = style()->font();
- const UChar suffix = listMarkerSuffix(type);
+ const UChar suffix = listMarkerSuffix(type, m_listItem->value());
if (style()->direction() == LTR) {
int width = font.width(textRun);
context->drawText(style()->font(), textRun, marker.location());
@@ -1282,7 +1375,7 @@ void RenderListMarker::calcPrefWidths()
width = 0;
else {
int itemWidth = font.width(m_text);
- UChar suffixSpace[2] = { listMarkerSuffix(type), ' ' };
+ UChar suffixSpace[2] = { listMarkerSuffix(type, m_listItem->value()), ' ' };
int suffixSpaceWidth = font.width(TextRun(suffixSpace, 2));
width = itemWidth + suffixSpaceWidth;
}
@@ -1484,7 +1577,7 @@ IntRect RenderListMarker::getRelativeMarkerRect()
return IntRect();
const Font& font = style()->font();
int itemWidth = font.width(m_text);
- UChar suffixSpace[2] = { listMarkerSuffix(type), ' ' };
+ UChar suffixSpace[2] = { listMarkerSuffix(type, m_listItem->value()), ' ' };
int suffixSpaceWidth = font.width(TextRun(suffixSpace, 2));
return IntRect(x(), y() + font.ascent(), itemWidth + suffixSpaceWidth, font.height());
}
diff --git a/WebCore/rendering/RenderMeter.cpp b/WebCore/rendering/RenderMeter.cpp
index cfa7cba..1a99976 100644
--- a/WebCore/rendering/RenderMeter.cpp
+++ b/WebCore/rendering/RenderMeter.cpp
@@ -162,9 +162,9 @@ void RenderMeter::updatePartsState()
{
if (shouldHaveParts() && !m_barPart) {
ASSERT(!m_valuePart);
- m_barPart = ShadowBlockElement::createForPart(this->node(), barPseudoId());
+ m_barPart = ShadowBlockElement::createForPart(static_cast<HTMLElement*>(node()), barPseudoId());
addChild(m_barPart->renderer());
- m_valuePart = ShadowBlockElement::createForPart(this->node(), valuePseudoId());
+ m_valuePart = ShadowBlockElement::createForPart(static_cast<HTMLElement*>(node()), valuePseudoId());
addChild(m_valuePart->renderer());
} else if (!shouldHaveParts() && m_barPart) {
ASSERT(m_valuePart);
diff --git a/WebCore/rendering/RenderObject.cpp b/WebCore/rendering/RenderObject.cpp
index 783ed63..78da758 100644
--- a/WebCore/rendering/RenderObject.cpp
+++ b/WebCore/rendering/RenderObject.cpp
@@ -1594,7 +1594,10 @@ Color RenderObject::selectionBackgroundColor() const
Color RenderObject::selectionForegroundColor() const
{
Color color;
- if (style()->userSelect() == SELECT_NONE)
+ // If the element is unselectable, or we are only painting the selection,
+ // don't override the foreground color with the selection foreground color.
+ if (style()->userSelect() == SELECT_NONE
+ || (frame()->view()->paintBehavior() & PaintBehaviorSelectionOnly))
return color;
if (RefPtr<RenderStyle> pseudoStyle = getUncachedPseudoStyle(SELECTION)) {
diff --git a/WebCore/rendering/RenderPath.cpp b/WebCore/rendering/RenderPath.cpp
index ddc2c45..86a12c8 100644
--- a/WebCore/rendering/RenderPath.cpp
+++ b/WebCore/rendering/RenderPath.cpp
@@ -127,33 +127,43 @@ void RenderPath::layout()
setNeedsLayout(false);
}
-static inline void fillAndStrokePath(const Path& path, GraphicsContext* context, RenderPath* object)
+void RenderPath::fillAndStrokePath(GraphicsContext* context)
{
context->beginPath();
- RenderStyle* style = object->style();
+ RenderStyle* style = this->style();
- if (RenderSVGResource* fillPaintingResource = RenderSVGResource::fillPaintingResource(object, style)) {
- context->addPath(path);
- if (fillPaintingResource->applyResource(object, style, context, ApplyToFillMode))
- fillPaintingResource->postApplyResource(object, context, ApplyToFillMode);
+ if (RenderSVGResource* fillPaintingResource = RenderSVGResource::fillPaintingResource(this, style)) {
+ context->addPath(m_path);
+ if (fillPaintingResource->applyResource(this, style, context, ApplyToFillMode))
+ fillPaintingResource->postApplyResource(this, context, ApplyToFillMode);
}
- if (RenderSVGResource* strokePaintingResource = RenderSVGResource::strokePaintingResource(object, style)) {
- if (style->svgStyle()->vectorEffect() == VE_NON_SCALING_STROKE) {
- SVGStyledTransformableElement* element = static_cast<SVGStyledTransformableElement*>(object->node());
- AffineTransform transform = element->getScreenCTM();
- if (!transform.isInvertible())
- return;
-
- Path transformedPath = path;
- context->concatCTM(transform.inverse());
- transformedPath.transform(transform);
- context->addPath(transformedPath);
- } else
- context->addPath(path);
- if (strokePaintingResource->applyResource(object, style, context, ApplyToStrokeMode))
- strokePaintingResource->postApplyResource(object, context, ApplyToStrokeMode);
- }
+ RenderSVGResource* strokePaintingResource = RenderSVGResource::strokePaintingResource(this, style);
+ if (!strokePaintingResource)
+ return;
+
+ bool restoreContext = false;
+ if (style->svgStyle()->vectorEffect() == VE_NON_SCALING_STROKE) {
+ SVGStyledTransformableElement* element = static_cast<SVGStyledTransformableElement*>(node());
+ AffineTransform nonScalingStrokeTransform = element->getScreenCTM(SVGLocatable::DisallowStyleUpdate);
+ if (!nonScalingStrokeTransform.isInvertible())
+ return;
+
+ Path transformedPath = m_path;
+ transformedPath.transform(nonScalingStrokeTransform);
+
+ context->save();
+ context->concatCTM(nonScalingStrokeTransform.inverse());
+ context->addPath(transformedPath);
+ restoreContext = true;
+ } else
+ context->addPath(m_path);
+
+ if (strokePaintingResource->applyResource(this, style, context, ApplyToStrokeMode))
+ strokePaintingResource->postApplyResource(this, context, ApplyToStrokeMode);
+
+ if (restoreContext)
+ context->restore();
}
void RenderPath::paint(PaintInfo& paintInfo, int, int)
@@ -180,7 +190,7 @@ void RenderPath::paint(PaintInfo& paintInfo, int, int)
if (svgStyle->shapeRendering() == SR_CRISPEDGES)
childPaintInfo.context->setShouldAntialias(false);
- fillAndStrokePath(m_path, childPaintInfo.context, this);
+ fillAndStrokePath(childPaintInfo.context);
if (svgStyle->hasMarkers())
m_markerLayoutInfo.drawMarkers(childPaintInfo);
diff --git a/WebCore/rendering/RenderPath.h b/WebCore/rendering/RenderPath.h
index 57900ad..1bdac07 100644
--- a/WebCore/rendering/RenderPath.h
+++ b/WebCore/rendering/RenderPath.h
@@ -70,6 +70,7 @@ private:
private:
virtual AffineTransform localTransform() const { return m_localTransform; }
+ void fillAndStrokePath(GraphicsContext*);
bool m_needsBoundariesUpdate : 1;
bool m_needsPathUpdate : 1;
diff --git a/WebCore/rendering/RenderProgress.cpp b/WebCore/rendering/RenderProgress.cpp
index 6072e1e..d6e2dc7 100644
--- a/WebCore/rendering/RenderProgress.cpp
+++ b/WebCore/rendering/RenderProgress.cpp
@@ -109,7 +109,7 @@ void RenderProgress::updatePartsState()
{
if (shouldHaveParts() && !m_valuePart) {
style()->setAppearance(NoControlPart);
- m_valuePart = ShadowBlockElement::createForPart(this->node(), PROGRESS_BAR_VALUE);
+ m_valuePart = ShadowBlockElement::createForPart(static_cast<HTMLElement*>(node()), PROGRESS_BAR_VALUE);
addChild(m_valuePart->renderer());
} else if (!shouldHaveParts() && m_valuePart) {
m_valuePart->detach();
diff --git a/WebCore/rendering/RenderSVGResourceClipper.cpp b/WebCore/rendering/RenderSVGResourceClipper.cpp
index 626a880..ef44a79 100644
--- a/WebCore/rendering/RenderSVGResourceClipper.cpp
+++ b/WebCore/rendering/RenderSVGResourceClipper.cpp
@@ -37,6 +37,7 @@
#include "RenderStyle.h"
#include "SVGClipPathElement.h"
#include "SVGElement.h"
+#include "SVGImageBufferTools.h"
#include "SVGRenderSupport.h"
#include "SVGResources.h"
#include "SVGStyledElement.h"
@@ -100,8 +101,7 @@ bool RenderSVGResourceClipper::applyResource(RenderObject* object, RenderStyle*,
UNUSED_PARAM(resourceMode);
#endif
- applyClippingToContext(object, object->objectBoundingBox(), object->repaintRectInLocalCoordinates(), context);
- return true;
+ return applyClippingToContext(object, object->objectBoundingBox(), object->repaintRectInLocalCoordinates(), context);
}
bool RenderSVGResourceClipper::pathOnlyClipping(GraphicsContext* context, const FloatRect& objectBoundingBox)
@@ -163,47 +163,67 @@ bool RenderSVGResourceClipper::applyClippingToContext(RenderObject* object, cons
if (!m_clipper.contains(object))
m_clipper.set(object, new ClipperData);
+ bool shouldCreateClipData = false;
ClipperData* clipperData = m_clipper.get(object);
if (!clipperData->clipMaskImage) {
if (pathOnlyClipping(context, objectBoundingBox))
return true;
- createClipData(clipperData, objectBoundingBox, repaintRect);
+ shouldCreateClipData = true;
+ }
+
+ AffineTransform absoluteTransform;
+ SVGImageBufferTools::calculateTransformationToOutermostSVGCoordinateSystem(object, absoluteTransform);
+
+ FloatRect absoluteTargetRect = absoluteTransform.mapRect(repaintRect);
+ FloatRect clampedAbsoluteTargetRect = SVGImageBufferTools::clampedAbsoluteTargetRectForRenderer(object, absoluteTargetRect);
+
+ if (shouldCreateClipData && !clampedAbsoluteTargetRect.isEmpty()) {
+ if (!SVGImageBufferTools::createImageBuffer(absoluteTargetRect, clampedAbsoluteTargetRect, clipperData->clipMaskImage, DeviceRGB))
+ return false;
+
+ GraphicsContext* maskContext = clipperData->clipMaskImage->context();
+ ASSERT(maskContext);
+
+ // The save/restore pair is needed for clipToImageBuffer - it doesn't work without it on non-Cg platforms.
+ maskContext->save();
+ maskContext->translate(-clampedAbsoluteTargetRect.x(), -clampedAbsoluteTargetRect.y());
+ maskContext->concatCTM(absoluteTransform);
+
+ // clipPath can also be clipped by another clipPath.
+ if (SVGResources* resources = SVGResourcesCache::cachedResourcesForRenderObject(this)) {
+ if (RenderSVGResourceClipper* clipper = resources->clipper()) {
+ if (!clipper->applyClippingToContext(this, objectBoundingBox, repaintRect, maskContext)) {
+ maskContext->restore();
+ return false;
+ }
+ }
+ }
+
+ drawContentIntoMaskImage(clipperData, objectBoundingBox);
+ maskContext->restore();
}
if (!clipperData->clipMaskImage)
return false;
- context->clipToImageBuffer(clipperData->clipMaskImage.get(), repaintRect);
+ SVGImageBufferTools::clipToImageBuffer(context, absoluteTransform, clampedAbsoluteTargetRect, clipperData->clipMaskImage);
return true;
}
-bool RenderSVGResourceClipper::createClipData(ClipperData* clipperData, const FloatRect& objectBoundingBox, const FloatRect& repaintRect)
+bool RenderSVGResourceClipper::drawContentIntoMaskImage(ClipperData* clipperData, const FloatRect& objectBoundingBox)
{
- IntRect clipMaskRect = enclosingIntRect(repaintRect);
- clipperData->clipMaskImage = ImageBuffer::create(clipMaskRect.size());
- if (!clipperData->clipMaskImage)
- return false;
+ ASSERT(clipperData);
+ ASSERT(clipperData->clipMaskImage);
GraphicsContext* maskContext = clipperData->clipMaskImage->context();
ASSERT(maskContext);
- maskContext->save();
- maskContext->translate(-repaintRect.x(), -repaintRect.y());
-
- // clipPath can also be clipped by another clipPath.
- if (SVGResources* resources = SVGResourcesCache::cachedResourcesForRenderObject(this)) {
- if (RenderSVGResourceClipper* clipper = resources->clipper()) {
- if (!clipper->applyClippingToContext(this, objectBoundingBox, repaintRect, maskContext)) {
- maskContext->restore();
- return false;
- }
- }
- }
-
+ AffineTransform maskContentTransformation;
SVGClipPathElement* clipPath = static_cast<SVGClipPathElement*>(node());
if (clipPath->clipPathUnits() == SVGUnitTypes::SVG_UNIT_TYPE_OBJECTBOUNDINGBOX) {
- maskContext->translate(objectBoundingBox.x(), objectBoundingBox.y());
- maskContext->scale(objectBoundingBox.size());
+ maskContentTransformation.translate(objectBoundingBox.x(), objectBoundingBox.y());
+ maskContentTransformation.scaleNonUniform(objectBoundingBox.width(), objectBoundingBox.height());
+ maskContext->concatCTM(maskContentTransformation);
}
// Draw all clipPath children into a global mask.
@@ -251,16 +271,14 @@ bool RenderSVGResourceClipper::createClipData(ClipperData* clipperData, const Fl
renderer->setStyle(newRenderStyle.release());
// In the case of a <use> element, we obtained its renderere above, to retrieve its clipRule.
- // We hsve to pass the <use> renderer itself to renderSubtreeToImage() to apply it's x/y/transform/etc. values when rendering.
+ // We have to pass the <use> renderer itself to renderSubtreeToImageBuffer() to apply it's x/y/transform/etc. values when rendering.
// So if isUseElement is true, refetch the childNode->renderer(), as renderer got overriden above.
- SVGRenderSupport::renderSubtreeToImage(clipperData->clipMaskImage.get(), isUseElement ? childNode->renderer() : renderer);
+ SVGImageBufferTools::renderSubtreeToImageBuffer(clipperData->clipMaskImage.get(), isUseElement ? childNode->renderer() : renderer, maskContentTransformation);
renderer->setStyle(oldRenderStyle.release());
m_invalidationBlocked = false;
}
- maskContext->restore();
-
return true;
}
diff --git a/WebCore/rendering/RenderSVGResourceClipper.h b/WebCore/rendering/RenderSVGResourceClipper.h
index 0f68c67..20153e9 100644
--- a/WebCore/rendering/RenderSVGResourceClipper.h
+++ b/WebCore/rendering/RenderSVGResourceClipper.h
@@ -65,7 +65,7 @@ private:
// applyResource directly and use the rects from the object, since they are empty for RenderSVGResources
bool applyClippingToContext(RenderObject*, const FloatRect&, const FloatRect&, GraphicsContext*);
bool pathOnlyClipping(GraphicsContext*, const FloatRect&);
- bool createClipData(ClipperData*, const FloatRect&, const FloatRect&);
+ bool drawContentIntoMaskImage(ClipperData*, const FloatRect& objectBoundingBox);
void calculateClipContentRepaintRect();
bool m_invalidationBlocked;
diff --git a/WebCore/rendering/RenderSVGResourceContainer.cpp b/WebCore/rendering/RenderSVGResourceContainer.cpp
index 5652dcc..f33eb85 100644
--- a/WebCore/rendering/RenderSVGResourceContainer.cpp
+++ b/WebCore/rendering/RenderSVGResourceContainer.cpp
@@ -184,7 +184,7 @@ AffineTransform RenderSVGResourceContainer::transformOnNonScalingStroke(RenderOb
SVGStyledTransformableElement* element = static_cast<SVGStyledTransformableElement*>(object->node());
AffineTransform transform = resourceTransform;
- transform.multiply(element->getScreenCTM());
+ transform.multiply(element->getScreenCTM(SVGLocatable::DisallowStyleUpdate));
return transform;
}
diff --git a/WebCore/rendering/RenderSVGResourceGradient.cpp b/WebCore/rendering/RenderSVGResourceGradient.cpp
index d29192a..1c33de4 100644
--- a/WebCore/rendering/RenderSVGResourceGradient.cpp
+++ b/WebCore/rendering/RenderSVGResourceGradient.cpp
@@ -80,35 +80,49 @@ static inline bool createMaskAndSwapContextForTextGradient(GraphicsContext*& con
const RenderObject* textRootBlock = SVGRenderSupport::findTextRootObject(object);
ASSERT(textRootBlock);
- AffineTransform absoluteTransform(SVGImageBufferTools::absoluteTransformFromContext(context));
+ AffineTransform absoluteTransform;
+ SVGImageBufferTools::calculateTransformationToOutermostSVGCoordinateSystem(textRootBlock, absoluteTransform);
+
FloatRect absoluteTargetRect = absoluteTransform.mapRect(textRootBlock->repaintRectInLocalCoordinates());
+ FloatRect clampedAbsoluteTargetRect = SVGImageBufferTools::clampedAbsoluteTargetRectForRenderer(textRootBlock, absoluteTargetRect);
+ if (clampedAbsoluteTargetRect.isEmpty())
+ return false;
OwnPtr<ImageBuffer> maskImage;
- if (!SVGImageBufferTools::createImageBuffer(absoluteTransform, absoluteTargetRect, maskImage, DeviceRGB))
+ if (!SVGImageBufferTools::createImageBuffer(absoluteTargetRect, clampedAbsoluteTargetRect, maskImage, DeviceRGB))
return false;
+ GraphicsContext* maskImageContext = maskImage->context();
+ ASSERT(maskImageContext);
+
+ maskImageContext->translate(-clampedAbsoluteTargetRect.x(), -clampedAbsoluteTargetRect.y());
+ maskImageContext->concatCTM(absoluteTransform);
+
ASSERT(maskImage);
savedContext = context;
- context = maskImage->context();
+ context = maskImageContext;
imageBuffer = maskImage.release();
return true;
}
static inline AffineTransform clipToTextMask(GraphicsContext* context,
OwnPtr<ImageBuffer>& imageBuffer,
- FloatRect& repaintRect,
+ FloatRect& targetRect,
const RenderObject* object,
GradientData* gradientData)
{
const RenderObject* textRootBlock = SVGRenderSupport::findTextRootObject(object);
ASSERT(textRootBlock);
- repaintRect = textRootBlock->repaintRectInLocalCoordinates();
+ targetRect = textRootBlock->repaintRectInLocalCoordinates();
+
+ AffineTransform absoluteTransform;
+ SVGImageBufferTools::calculateTransformationToOutermostSVGCoordinateSystem(textRootBlock, absoluteTransform);
- AffineTransform absoluteTransform(SVGImageBufferTools::absoluteTransformFromContext(context));
- FloatRect absoluteTargetRect = absoluteTransform.mapRect(repaintRect);
+ FloatRect absoluteTargetRect = absoluteTransform.mapRect(targetRect);
+ FloatRect clampedAbsoluteTargetRect = SVGImageBufferTools::clampedAbsoluteTargetRectForRenderer(textRootBlock, absoluteTargetRect);
- SVGImageBufferTools::clipToImageBuffer(context, absoluteTransform, absoluteTargetRect, imageBuffer.get());
+ SVGImageBufferTools::clipToImageBuffer(context, absoluteTransform, clampedAbsoluteTargetRect, imageBuffer);
AffineTransform matrix;
if (gradientData->boundingBoxMode) {
@@ -216,11 +230,11 @@ void RenderSVGResourceGradient::postApplyResource(RenderObject* object, Graphics
context = m_savedContext;
m_savedContext = 0;
- FloatRect repaintRect;
- gradientData->gradient->setGradientSpaceTransform(clipToTextMask(context, m_imageBuffer, repaintRect, object, gradientData));
+ FloatRect targetRect;
+ gradientData->gradient->setGradientSpaceTransform(clipToTextMask(context, m_imageBuffer, targetRect, object, gradientData));
context->setFillGradient(gradientData->gradient);
- context->fillRect(repaintRect);
+ context->fillRect(targetRect);
m_imageBuffer.clear();
}
#else
diff --git a/WebCore/rendering/RenderSVGResourceMasker.cpp b/WebCore/rendering/RenderSVGResourceMasker.cpp
index 9713dd6..3e81929 100644
--- a/WebCore/rendering/RenderSVGResourceMasker.cpp
+++ b/WebCore/rendering/RenderSVGResourceMasker.cpp
@@ -96,43 +96,50 @@ bool RenderSVGResourceMasker::applyResource(RenderObject* object, RenderStyle*,
MaskerData* maskerData = m_masker.get(object);
- AffineTransform absoluteTransform(SVGImageBufferTools::absoluteTransformFromContext(context));
- FloatRect maskRect = absoluteTransform.mapRect(object->repaintRectInLocalCoordinates());
+ AffineTransform absoluteTransform;
+ SVGImageBufferTools::calculateTransformationToOutermostSVGCoordinateSystem(object, absoluteTransform);
- if (!maskerData->maskImage && !maskRect.isEmpty()) {
+ FloatRect absoluteTargetRect = absoluteTransform.mapRect(object->repaintRectInLocalCoordinates());
+ FloatRect clampedAbsoluteTargetRect = SVGImageBufferTools::clampedAbsoluteTargetRectForRenderer(object, absoluteTargetRect);
+
+ if (!maskerData->maskImage && !clampedAbsoluteTargetRect.isEmpty()) {
SVGMaskElement* maskElement = static_cast<SVGMaskElement*>(node());
if (!maskElement)
return false;
- if (!SVGImageBufferTools::createImageBuffer(absoluteTransform, maskRect, maskerData->maskImage, LinearRGB))
+ if (!SVGImageBufferTools::createImageBuffer(absoluteTargetRect, clampedAbsoluteTargetRect, maskerData->maskImage, LinearRGB))
return false;
- ASSERT(maskerData->maskImage);
- drawContentIntoMaskImage(maskRect, maskerData, maskElement, object);
+ GraphicsContext* maskImageContext = maskerData->maskImage->context();
+ ASSERT(maskImageContext);
+
+ // The save/restore pair is needed for clipToImageBuffer - it doesn't work without it on non-Cg platforms.
+ maskImageContext->save();
+ maskImageContext->translate(-clampedAbsoluteTargetRect.x(), -clampedAbsoluteTargetRect.y());
+ maskImageContext->concatCTM(absoluteTransform);
+
+ drawContentIntoMaskImage(maskerData, maskElement, object);
}
if (!maskerData->maskImage)
return false;
- SVGImageBufferTools::clipToImageBuffer(context, absoluteTransform, maskRect, maskerData->maskImage.get());
+ SVGImageBufferTools::clipToImageBuffer(context, absoluteTransform, clampedAbsoluteTargetRect, maskerData->maskImage);
return true;
}
-void RenderSVGResourceMasker::drawContentIntoMaskImage(const FloatRect& maskRect, MaskerData* maskerData, const SVGMaskElement* maskElement, RenderObject* object)
+void RenderSVGResourceMasker::drawContentIntoMaskImage(MaskerData* maskerData, const SVGMaskElement* maskElement, RenderObject* object)
{
- IntRect maskImageRect = enclosingIntRect(maskRect);
- maskImageRect.setLocation(IntPoint());
+ GraphicsContext* maskImageContext = maskerData->maskImage->context();
+ ASSERT(maskImageContext);
// Eventually adjust the mask image context according to the target objectBoundingBox.
+ AffineTransform maskContentTransformation;
if (maskElement->maskContentUnits() == SVGUnitTypes::SVG_UNIT_TYPE_OBJECTBOUNDINGBOX) {
- GraphicsContext* maskImageContext = maskerData->maskImage->context();
- ASSERT(maskImageContext);
-
FloatRect objectBoundingBox = object->objectBoundingBox();
- AffineTransform contextTransform;
- contextTransform.translate(objectBoundingBox.x(), objectBoundingBox.y());
- contextTransform.scaleNonUniform(objectBoundingBox.width(), objectBoundingBox.height());
- maskImageContext->concatCTM(contextTransform);
+ maskContentTransformation.translate(objectBoundingBox.x(), objectBoundingBox.y());
+ maskContentTransformation.scaleNonUniform(objectBoundingBox.width(), objectBoundingBox.height());
+ maskImageContext->concatCTM(maskContentTransformation);
}
// Draw the content into the ImageBuffer.
@@ -143,14 +150,17 @@ void RenderSVGResourceMasker::drawContentIntoMaskImage(const FloatRect& maskRect
RenderStyle* style = renderer->style();
if (!style || style->display() == NONE || style->visibility() != VISIBLE)
continue;
- SVGRenderSupport::renderSubtreeToImage(maskerData->maskImage.get(), renderer);
+ SVGImageBufferTools::renderSubtreeToImageBuffer(maskerData->maskImage.get(), renderer, maskContentTransformation);
}
+ maskImageContext->restore();
+
#if !PLATFORM(CG)
maskerData->maskImage->transformColorSpace(DeviceRGB, LinearRGB);
#endif
- // create the luminance mask
+ // Create the luminance mask.
+ IntRect maskImageRect(IntPoint(), maskerData->maskImage->size());
RefPtr<ImageData> imageData(maskerData->maskImage->getUnmultipliedImageData(maskImageRect));
CanvasPixelArray* srcPixelArray(imageData->data());
diff --git a/WebCore/rendering/RenderSVGResourceMasker.h b/WebCore/rendering/RenderSVGResourceMasker.h
index f2d8cb2..fddecd0 100644
--- a/WebCore/rendering/RenderSVGResourceMasker.h
+++ b/WebCore/rendering/RenderSVGResourceMasker.h
@@ -58,7 +58,7 @@ public:
static RenderSVGResourceType s_resourceType;
private:
- void drawContentIntoMaskImage(const FloatRect& maskRect, MaskerData*, const SVGMaskElement*, RenderObject*);
+ void drawContentIntoMaskImage(MaskerData*, const SVGMaskElement*, RenderObject*);
void calculateMaskContentRepaintRect();
FloatRect m_maskContentBoundaries;
diff --git a/WebCore/rendering/RenderSVGResourcePattern.cpp b/WebCore/rendering/RenderSVGResourcePattern.cpp
index f4f5cf4..ccbdaca 100644
--- a/WebCore/rendering/RenderSVGResourcePattern.cpp
+++ b/WebCore/rendering/RenderSVGResourcePattern.cpp
@@ -27,6 +27,8 @@
#include "FrameView.h"
#include "GraphicsContext.h"
#include "PatternAttributes.h"
+#include "RenderSVGRoot.h"
+#include "SVGImageBufferTools.h"
#include "SVGRenderSupport.h"
namespace WebCore {
@@ -75,7 +77,7 @@ bool RenderSVGResourcePattern::applyResource(RenderObject* object, RenderStyle*
ASSERT(resourceMode != ApplyToDefaultMode);
// Be sure to synchronize all SVG properties on the patternElement _before_ processing any further.
- // Otherwhise the call to collectPatternAttributes() in createTileImage(), may cause the SVG DOM property
+ // Otherwhise the call to collectPatternAttributes() below, may cause the SVG DOM property
// synchronization to kick in, which causes removeAllClientsFromCache() to be called, which in turn deletes our
// PatternData object! Leaving out the line below will cause svg/dynamic-updates/SVGPatternElement-svgdom* to crash.
SVGPatternElement* patternElement = static_cast<SVGPatternElement*>(node());
@@ -89,17 +91,43 @@ bool RenderSVGResourcePattern::applyResource(RenderObject* object, RenderStyle*
PatternData* patternData = m_pattern.get(object);
if (!patternData->pattern) {
- // Create tile image
- OwnPtr<ImageBuffer> tileImage = createTileImage(patternData, patternElement, object);
+ PatternAttributes attributes = patternElement->collectPatternProperties();
+
+ // If we couldn't determine the pattern content element root, stop here.
+ if (!attributes.patternContentElement())
+ return false;
+
+ // Compute all necessary transformations to build the tile image & the pattern.
+ FloatRect tileBoundaries;
+ AffineTransform tileImageTransform = buildTileImageTransform(object, attributes, patternElement, tileBoundaries);
+
+ AffineTransform absoluteTransform;
+ SVGImageBufferTools::calculateTransformationToOutermostSVGCoordinateSystem(object, absoluteTransform);
+
+ FloatRect absoluteTileBoundaries = absoluteTransform.mapRect(tileBoundaries);
+
+ // Build tile image.
+ OwnPtr<ImageBuffer> tileImage = createTileImage(object, attributes, tileBoundaries, absoluteTileBoundaries, tileImageTransform);
if (!tileImage)
return false;
- // Create pattern object
- buildPattern(patternData, tileImage.release());
+ RefPtr<Image> copiedImage = tileImage->copyImage();
+ if (!copiedImage)
+ return false;
+ // Build pattern.
+ patternData->pattern = Pattern::create(copiedImage, true, true);
if (!patternData->pattern)
return false;
+ // Compute pattern space transformation.
+ patternData->transform.translate(tileBoundaries.x(), tileBoundaries.y());
+ patternData->transform.scale(tileBoundaries.width() / absoluteTileBoundaries.width(), tileBoundaries.height() / absoluteTileBoundaries.height());
+
+ AffineTransform patternTransform = attributes.patternTransform();
+ if (!patternTransform.isIdentity())
+ patternData->transform.multiply(patternTransform);
+
patternData->pattern->setPatternSpaceTransform(patternData->transform);
}
@@ -155,13 +183,15 @@ void RenderSVGResourcePattern::postApplyResource(RenderObject*, GraphicsContext*
context->restore();
}
-static inline FloatRect calculatePatternBoundaries(PatternAttributes& attributes,
+static inline FloatRect calculatePatternBoundaries(const PatternAttributes& attributes,
const FloatRect& objectBoundingBox,
const SVGPatternElement* patternElement)
{
+ ASSERT(patternElement);
+
if (attributes.boundingBoxMode())
- return FloatRect(attributes.x().valueAsPercentage() * objectBoundingBox.width(),
- attributes.y().valueAsPercentage() * objectBoundingBox.height(),
+ return FloatRect(attributes.x().valueAsPercentage() * objectBoundingBox.width() + objectBoundingBox.x(),
+ attributes.y().valueAsPercentage() * objectBoundingBox.height() + objectBoundingBox.y(),
attributes.width().valueAsPercentage() * objectBoundingBox.width(),
attributes.height().valueAsPercentage() * objectBoundingBox.height());
@@ -171,175 +201,77 @@ static inline FloatRect calculatePatternBoundaries(PatternAttributes& attributes
attributes.height().value(patternElement));
}
-FloatRect RenderSVGResourcePattern::calculatePatternBoundariesIncludingOverflow(PatternAttributes& attributes,
- const FloatRect& objectBoundingBox,
- const AffineTransform& viewBoxCTM,
- const FloatRect& patternBoundaries) const
+AffineTransform RenderSVGResourcePattern::buildTileImageTransform(RenderObject* renderer,
+ const PatternAttributes& attributes,
+ const SVGPatternElement* patternElement,
+ FloatRect& patternBoundaries) const
{
- // Eventually calculate the pattern content boundaries (only needed with overflow="visible").
- FloatRect patternContentBoundaries;
-
- const RenderStyle* style = this->style();
- if (style->overflowX() == OVISIBLE && style->overflowY() == OVISIBLE) {
- for (Node* node = attributes.patternContentElement()->firstChild(); node; node = node->nextSibling()) {
- if (!node->isSVGElement() || !static_cast<SVGElement*>(node)->isStyledTransformable() || !node->renderer())
- continue;
- patternContentBoundaries.unite(node->renderer()->repaintRectInLocalCoordinates());
- }
- }
+ ASSERT(renderer);
+ ASSERT(patternElement);
- if (patternContentBoundaries.isEmpty())
- return patternBoundaries;
+ FloatRect objectBoundingBox = renderer->objectBoundingBox();
+ patternBoundaries = calculatePatternBoundaries(attributes, objectBoundingBox, patternElement);
- FloatRect patternBoundariesIncludingOverflow = patternBoundaries;
+ AffineTransform viewBoxCTM = patternElement->viewBoxToViewTransform(patternElement->viewBox(), patternElement->preserveAspectRatio(), patternBoundaries.width(), patternBoundaries.height());
+ AffineTransform tileImageTransform;
- // Respect objectBoundingBoxMode for patternContentUnits, if viewBox is not set.
+ // Apply viewBox/objectBoundingBox transformations.
if (!viewBoxCTM.isIdentity())
- patternContentBoundaries = viewBoxCTM.mapRect(patternContentBoundaries);
- else if (attributes.boundingBoxModeContent())
- patternContentBoundaries = FloatRect(patternContentBoundaries.x() * objectBoundingBox.width(),
- patternContentBoundaries.y() * objectBoundingBox.height(),
- patternContentBoundaries.width() * objectBoundingBox.width(),
- patternContentBoundaries.height() * objectBoundingBox.height());
-
- patternBoundariesIncludingOverflow.unite(patternContentBoundaries);
- return patternBoundariesIncludingOverflow;
-}
-
-// FIXME: This method should be removed. RenderSVGResourcePatterns usage of it is just wrong.
-static inline void clampImageBufferSizeToViewport(FrameView* frameView, IntSize& size)
-{
- if (!frameView)
- return;
-
- int viewWidth = frameView->visibleWidth();
- int viewHeight = frameView->visibleHeight();
-
- if (size.width() > viewWidth)
- size.setWidth(viewWidth);
+ tileImageTransform = viewBoxCTM;
+ else if (attributes.boundingBoxModeContent()) {
+ tileImageTransform.translate(objectBoundingBox.x(), objectBoundingBox.y());
+ tileImageTransform.scale(objectBoundingBox.width(), objectBoundingBox.height());
+ }
- if (size.height() > viewHeight)
- size.setHeight(viewHeight);
+ return tileImageTransform;
}
-PassOwnPtr<ImageBuffer> RenderSVGResourcePattern::createTileImage(PatternData* patternData,
- const SVGPatternElement* patternElement,
- RenderObject* object) const
+PassOwnPtr<ImageBuffer> RenderSVGResourcePattern::createTileImage(RenderObject* object,
+ const PatternAttributes& attributes,
+ const FloatRect& tileBoundaries,
+ const FloatRect& absoluteTileBoundaries,
+ const AffineTransform& tileImageTransform) const
{
- PatternAttributes attributes = patternElement->collectPatternProperties();
-
- // If we couldn't determine the pattern content element root, stop here.
- if (!attributes.patternContentElement())
- return 0;
-
- FloatRect objectBoundingBox = object->objectBoundingBox();
- FloatRect patternBoundaries = calculatePatternBoundaries(attributes, objectBoundingBox, patternElement);
- AffineTransform patternTransform = attributes.patternTransform();
+ ASSERT(object);
- AffineTransform viewBoxCTM = patternElement->viewBoxToViewTransform(patternElement->viewBox(),
- patternElement->preserveAspectRatio(),
- patternBoundaries.width(),
- patternBoundaries.height());
+ // Clamp tile image size against SVG viewport size, as last resort, to avoid allocating huge image buffers.
+ FloatRect contentBoxRect = SVGRenderSupport::findTreeRootObject(object)->contentBoxRect();
- FloatRect patternBoundariesIncludingOverflow = calculatePatternBoundariesIncludingOverflow(attributes,
- objectBoundingBox,
- viewBoxCTM,
- patternBoundaries);
+ FloatRect clampedAbsoluteTileBoundaries = absoluteTileBoundaries;
+ if (clampedAbsoluteTileBoundaries.width() > contentBoxRect.width())
+ clampedAbsoluteTileBoundaries.setWidth(contentBoxRect.width());
- IntSize imageSize(lroundf(patternBoundariesIncludingOverflow.width()), lroundf(patternBoundariesIncludingOverflow.height()));
+ if (clampedAbsoluteTileBoundaries.height() > contentBoxRect.height())
+ clampedAbsoluteTileBoundaries.setHeight(contentBoxRect.height());
- // FIXME: We should be able to clip this more, needs investigation
- clampImageBufferSizeToViewport(object->document()->view(), imageSize);
+ OwnPtr<ImageBuffer> tileImage;
- // Don't create ImageBuffers with image size of 0
- if (imageSize.isEmpty())
- return 0;
+ if (!SVGImageBufferTools::createImageBuffer(absoluteTileBoundaries, clampedAbsoluteTileBoundaries, tileImage, DeviceRGB))
+ return PassOwnPtr<ImageBuffer>();
- OwnPtr<ImageBuffer> tileImage = ImageBuffer::create(imageSize);
+ GraphicsContext* tileImageContext = tileImage->context();
+ ASSERT(tileImageContext);
- GraphicsContext* context = tileImage->context();
- ASSERT(context);
+ // The image buffer represents the final rendered size, so the content has to be scaled (to avoid pixelation).
+ tileImageContext->scale(FloatSize(absoluteTileBoundaries.width() / tileBoundaries.width(),
+ absoluteTileBoundaries.height() / tileBoundaries.height()));
- context->save();
+ // Apply tile image transformations.
+ if (!tileImageTransform.isIdentity())
+ tileImageContext->concatCTM(tileImageTransform);
- // Translate to pattern start origin
- if (patternBoundariesIncludingOverflow.location() != patternBoundaries.location()) {
- context->translate(patternBoundaries.x() - patternBoundariesIncludingOverflow.x(),
- patternBoundaries.y() - patternBoundariesIncludingOverflow.y());
+ AffineTransform contentTransformation;
- patternBoundaries.setLocation(patternBoundariesIncludingOverflow.location());
- }
-
- // Process viewBox or boundingBoxModeContent correction
- if (!viewBoxCTM.isIdentity())
- context->concatCTM(viewBoxCTM);
- else if (attributes.boundingBoxModeContent()) {
- context->translate(objectBoundingBox.x(), objectBoundingBox.y());
- context->scale(FloatSize(objectBoundingBox.width(), objectBoundingBox.height()));
- }
-
- // Render subtree into ImageBuffer
+ // Draw the content into the ImageBuffer.
for (Node* node = attributes.patternContentElement()->firstChild(); node; node = node->nextSibling()) {
if (!node->isSVGElement() || !static_cast<SVGElement*>(node)->isStyled() || !node->renderer())
continue;
- SVGRenderSupport::renderSubtreeToImage(tileImage.get(), node->renderer());
+ SVGImageBufferTools::renderSubtreeToImageBuffer(tileImage.get(), node->renderer(), contentTransformation);
}
- patternData->boundaries = patternBoundaries;
-
- // Compute pattern transformation
- patternData->transform.translate(patternBoundaries.x(), patternBoundaries.y());
- patternData->transform.multiply(patternTransform);
-
- context->restore();
return tileImage.release();
}
-void RenderSVGResourcePattern::buildPattern(PatternData* patternData, PassOwnPtr<ImageBuffer> tileImage) const
-{
- RefPtr<Image> copiedImage = tileImage->copyImage();
- if (!copiedImage) {
- patternData->pattern = 0;
- return;
- }
-
- IntRect tileRect = copiedImage->rect();
- if (tileRect.width() <= patternData->boundaries.width() && tileRect.height() <= patternData->boundaries.height()) {
- patternData->pattern = Pattern::create(copiedImage, true, true);
- return;
- }
-
- // Draw the first cell of the pattern manually to support overflow="visible" on all platforms.
- int tileWidth = static_cast<int>(patternData->boundaries.width() + 0.5f);
- int tileHeight = static_cast<int>(patternData->boundaries.height() + 0.5f);
-
- // Don't create ImageBuffers with image size of 0
- if (!tileWidth || !tileHeight) {
- patternData->pattern = 0;
- return;
- }
-
- OwnPtr<ImageBuffer> newTileImage = ImageBuffer::create(IntSize(tileWidth, tileHeight));
- GraphicsContext* newTileImageContext = newTileImage->context();
-
- int numY = static_cast<int>(ceilf(tileRect.height() / tileHeight)) + 1;
- int numX = static_cast<int>(ceilf(tileRect.width() / tileWidth)) + 1;
-
- newTileImageContext->save();
- newTileImageContext->translate(-patternData->boundaries.width() * numX, -patternData->boundaries.height() * numY);
- for (int i = numY; i > 0; --i) {
- newTileImageContext->translate(0, patternData->boundaries.height());
- for (int j = numX; j > 0; --j) {
- newTileImageContext->translate(patternData->boundaries.width(), 0);
- newTileImageContext->drawImage(copiedImage.get(), style()->colorSpace(), tileRect, tileRect);
- }
- newTileImageContext->translate(-patternData->boundaries.width() * numX, 0);
- }
- newTileImageContext->restore();
-
- patternData->pattern = Pattern::create(newTileImage->copyImage(), true, true);
-}
-
}
#endif
diff --git a/WebCore/rendering/RenderSVGResourcePattern.h b/WebCore/rendering/RenderSVGResourcePattern.h
index 52bf09d..9a067c2 100644
--- a/WebCore/rendering/RenderSVGResourcePattern.h
+++ b/WebCore/rendering/RenderSVGResourcePattern.h
@@ -38,7 +38,6 @@ namespace WebCore {
struct PatternData {
RefPtr<Pattern> pattern;
- FloatRect boundaries;
AffineTransform transform;
};
@@ -62,10 +61,10 @@ public:
static RenderSVGResourceType s_resourceType;
private:
- PassOwnPtr<ImageBuffer> createTileImage(PatternData*, const SVGPatternElement*, RenderObject*) const;
- void buildPattern(PatternData*, PassOwnPtr<ImageBuffer> tileImage) const;
- FloatRect calculatePatternBoundariesIncludingOverflow(PatternAttributes&, const FloatRect& objectBoundingBox,
- const AffineTransform& viewBoxCTM, const FloatRect& patternBoundaries) const;
+ AffineTransform buildTileImageTransform(RenderObject*, const PatternAttributes&, const SVGPatternElement*, FloatRect& patternBoundaries) const;
+
+ PassOwnPtr<ImageBuffer> createTileImage(RenderObject*, const PatternAttributes&, const FloatRect& tileBoundaries,
+ const FloatRect& absoluteTileBoundaries, const AffineTransform& tileImageTransform) const;
HashMap<RenderObject*, PatternData*> m_pattern;
};
diff --git a/WebCore/rendering/RenderSlider.cpp b/WebCore/rendering/RenderSlider.cpp
index 591b1ac..aef807b 100644
--- a/WebCore/rendering/RenderSlider.cpp
+++ b/WebCore/rendering/RenderSlider.cpp
@@ -29,7 +29,7 @@
#include "Frame.h"
#include "HTMLInputElement.h"
#include "HTMLNames.h"
-#include "LegacyHTMLTreeBuilder.h"
+#include "HTMLTreeBuilder.h"
#include "MediaControlElements.h"
#include "MouseEvent.h"
#include "RenderLayer.h"
@@ -58,7 +58,7 @@ static double sliderPosition(HTMLInputElement* element)
class SliderThumbElement : public ShadowBlockElement {
public:
- static PassRefPtr<SliderThumbElement> create(Node* shadowParent);
+ static PassRefPtr<SliderThumbElement> create(HTMLElement* shadowParent);
bool inDragMode() const { return m_inDragMode; }
@@ -66,19 +66,19 @@ public:
virtual void detach();
private:
- SliderThumbElement(Node* shadowParent);
+ SliderThumbElement(HTMLElement* shadowParent);
FloatPoint m_offsetToThumb;
bool m_inDragMode;
};
-inline SliderThumbElement::SliderThumbElement(Node* shadowParent)
+inline SliderThumbElement::SliderThumbElement(HTMLElement* shadowParent)
: ShadowBlockElement(shadowParent)
, m_inDragMode(false)
{
}
-inline PassRefPtr<SliderThumbElement> SliderThumbElement::create(Node* shadowParent)
+inline PassRefPtr<SliderThumbElement> SliderThumbElement::create(HTMLElement* shadowParent)
{
return adoptRef(new SliderThumbElement(shadowParent));
}
@@ -309,7 +309,7 @@ void RenderSlider::updateFromElement()
{
// Layout will take care of the thumb's size and position.
if (!m_thumb) {
- m_thumb = SliderThumbElement::create(node());
+ m_thumb = SliderThumbElement::create(static_cast<HTMLElement*>(node()));
RefPtr<RenderStyle> thumbStyle = createThumbStyle(style());
m_thumb->setRenderer(m_thumb->createRenderer(renderArena(), thumbStyle.get()));
m_thumb->renderer()->setStyle(thumbStyle.release());
diff --git a/WebCore/rendering/RenderTextControl.cpp b/WebCore/rendering/RenderTextControl.cpp
index 5f8c788..9098bab 100644
--- a/WebCore/rendering/RenderTextControl.cpp
+++ b/WebCore/rendering/RenderTextControl.cpp
@@ -145,7 +145,7 @@ void RenderTextControl::createSubtreeIfNeeded(TextControlInnerElement* innerBloc
// For non-search fields, there is no intermediate innerBlock as the shadow node.
// m_innerText will be the shadow node in that case.
RenderStyle* parentStyle = innerBlock ? innerBlock->renderer()->style() : style();
- m_innerText = TextControlInnerTextElement::create(document(), innerBlock ? 0 : node());
+ m_innerText = TextControlInnerTextElement::create(document(), innerBlock ? 0 : static_cast<HTMLElement*>(node()));
m_innerText->attachInnerElement(innerBlock ? innerBlock : node(), createInnerTextStyle(parentStyle), renderArena());
}
}
diff --git a/WebCore/rendering/RenderTextControlSingleLine.cpp b/WebCore/rendering/RenderTextControlSingleLine.cpp
index ed5c2f4..b27a91a 100644
--- a/WebCore/rendering/RenderTextControlSingleLine.cpp
+++ b/WebCore/rendering/RenderTextControlSingleLine.cpp
@@ -610,17 +610,17 @@ void RenderTextControlSingleLine::createSubtreeIfNeeded()
#if ENABLE(INPUT_SPEECH)
if (inputElement()->isSpeechEnabled() && !m_speechButton) {
// Create the speech button element.
- m_speechButton = InputFieldSpeechButtonElement::create(node());
+ m_speechButton = InputFieldSpeechButtonElement::create(static_cast<HTMLElement*>(node()));
m_speechButton->attachInnerElement(node(), createSpeechButtonStyle(), renderArena());
}
#endif
bool hasSpinButton = inputElement()->hasSpinButton();
if (hasSpinButton && !m_innerSpinButton) {
- m_innerSpinButton = SpinButtonElement::create(node());
+ m_innerSpinButton = SpinButtonElement::create(static_cast<HTMLElement*>(node()));
m_innerSpinButton->attachInnerElement(node(), createInnerSpinButtonStyle(), renderArena());
}
if (hasSpinButton && !m_outerSpinButton) {
- m_outerSpinButton = SpinButtonElement::create(node());
+ m_outerSpinButton = SpinButtonElement::create(static_cast<HTMLElement*>(node()));
m_outerSpinButton->attachInnerElement(node(), createOuterSpinButtonStyle(), renderArena());
}
return;
@@ -628,18 +628,18 @@ void RenderTextControlSingleLine::createSubtreeIfNeeded()
if (!m_innerBlock) {
// Create the inner block element
- m_innerBlock = TextControlInnerElement::create(node());
+ m_innerBlock = TextControlInnerElement::create(static_cast<HTMLElement*>(node()));
m_innerBlock->attachInnerElement(node(), createInnerBlockStyle(style()), renderArena());
}
#if ENABLE(INPUT_SPEECH)
if (inputElement()->isSpeechEnabled() && !m_speechButton) {
// Create the speech button element.
- m_speechButton = InputFieldSpeechButtonElement::create(node());
+ m_speechButton = InputFieldSpeechButtonElement::create(static_cast<HTMLElement*>(node()));
m_speechButton->attachInnerElement(node(), createSpeechButtonStyle(), renderArena());
}
#endif
if (inputElement()->hasSpinButton() && !m_outerSpinButton) {
- m_outerSpinButton = SpinButtonElement::create(node());
+ m_outerSpinButton = SpinButtonElement::create(static_cast<HTMLElement*>(node()));
m_outerSpinButton->attachInnerElement(node(), createOuterSpinButtonStyle(), renderArena());
}
diff --git a/WebCore/rendering/RenderView.h b/WebCore/rendering/RenderView.h
index 799b206..8145cac 100644
--- a/WebCore/rendering/RenderView.h
+++ b/WebCore/rendering/RenderView.h
@@ -71,12 +71,18 @@ public:
enum SelectionRepaintMode { RepaintNewXOROld, RepaintNewMinusOld };
void setSelection(RenderObject* start, int startPos, RenderObject* end, int endPos, SelectionRepaintMode = RepaintNewXOROld);
void clearSelection();
- virtual RenderObject* selectionStart() const { return m_selectionStart; }
- virtual RenderObject* selectionEnd() const { return m_selectionEnd; }
+ RenderObject* selectionStart() const { return m_selectionStart; }
+ RenderObject* selectionEnd() const { return m_selectionEnd; }
+ IntRect selectionBounds(bool clipToVisibleContent = true) const;
+ void selectionStartEnd(int& startPos, int& endPos) const;
bool printing() const;
void setPrintImages(bool enable) { m_printImages = enable; }
bool printImages() const { return m_printImages; }
+
+ IntRect printRect() const { return m_printRect; }
+ void setPrintRect(const IntRect& r) { m_printRect = r; }
+
void setTruncatedAt(int y) { m_truncatedAt = y; m_bestTruncatedAt = m_truncatorWidth = 0; m_minimumColumnHeight = 0; m_forcedPageBreak = false; }
void setBestTruncatedAt(int y, RenderBoxModelObject* forRenderer, bool forcedBreak = false);
void setMinimumColumnHeight(int height) { m_minimumColumnHeight = height; }
@@ -88,8 +94,6 @@ public:
virtual void absoluteRects(Vector<IntRect>&, int tx, int ty);
virtual void absoluteQuads(Vector<FloatQuad>&);
- IntRect selectionBounds(bool clipToVisibleContent = true) const;
-
#if USE(ACCELERATED_COMPOSITING)
void setMaximalOutlineSize(int o);
#else
@@ -99,11 +103,6 @@ public:
virtual IntRect viewRect() const;
- void selectionStartEnd(int& startPos, int& endPos) const;
-
- IntRect printRect() const { return m_printRect; }
- void setPrintRect(const IntRect& r) { m_printRect = r; }
-
void updateWidgetPositions();
void addWidget(RenderWidget*);
void removeWidget(RenderWidget*);
diff --git a/WebCore/rendering/SVGImageBufferTools.cpp b/WebCore/rendering/SVGImageBufferTools.cpp
index 5b45ccc..709bf10 100644
--- a/WebCore/rendering/SVGImageBufferTools.cpp
+++ b/WebCore/rendering/SVGImageBufferTools.cpp
@@ -22,50 +22,118 @@
#if ENABLE(SVG)
#include "SVGImageBufferTools.h"
+#include "FrameView.h"
#include "GraphicsContext.h"
#include "RenderObject.h"
+#include "RenderSVGContainer.h"
+#include "RenderSVGRoot.h"
namespace WebCore {
-AffineTransform SVGImageBufferTools::absoluteTransformFromContext(GraphicsContext* context)
+static AffineTransform& currentContentTransformation()
{
- // Extract current transformation matrix used in the original context. Note that this coordinate
- // system is flipped compared to SVGs internal coordinate system, done in WebKit level. Fix
- // this transformation by flipping the y component.
- return context->getCTM() * AffineTransform().flipY();
+ DEFINE_STATIC_LOCAL(AffineTransform, s_currentContentTransformation, ());
+ return s_currentContentTransformation;
}
-bool SVGImageBufferTools::createImageBuffer(const AffineTransform& absoluteTransform, const FloatRect& absoluteTargetRect, OwnPtr<ImageBuffer>& imageBuffer, ImageColorSpace colorSpace)
+void SVGImageBufferTools::calculateTransformationToOutermostSVGCoordinateSystem(const RenderObject* renderer, AffineTransform& absoluteTransform)
{
- IntRect imageRect = enclosingIntRect(absoluteTargetRect);
- if (imageRect.isEmpty())
+ const RenderObject* current = renderer;
+ ASSERT(current);
+
+ absoluteTransform = currentContentTransformation();
+ while (current) {
+ absoluteTransform.multiply(current->localToParentTransform());
+ if (current->isSVGRoot())
+ break;
+ current = current->parent();
+ }
+}
+
+bool SVGImageBufferTools::createImageBuffer(const FloatRect& absoluteTargetRect, const FloatRect& clampedAbsoluteTargetRect, OwnPtr<ImageBuffer>& imageBuffer, ImageColorSpace colorSpace)
+{
+ IntSize imageSize(roundedImageBufferSize(clampedAbsoluteTargetRect.size()));
+ IntSize unclampedImageSize(SVGImageBufferTools::roundedImageBufferSize(absoluteTargetRect.size()));
+
+ // Don't create empty ImageBuffers.
+ if (imageSize.isEmpty())
return false;
- // Allocate an image buffer as big as the absolute unclipped size of the object
- OwnPtr<ImageBuffer> image = ImageBuffer::create(imageRect.size(), colorSpace);
+ OwnPtr<ImageBuffer> image = ImageBuffer::create(imageSize, colorSpace);
if (!image)
return false;
GraphicsContext* imageContext = image->context();
+ ASSERT(imageContext);
- // Transform the mask image coordinate system to absolute screen coordinates
- imageContext->translate(-absoluteTargetRect.x(), -absoluteTargetRect.y());
- imageContext->concatCTM(absoluteTransform);
+ // Compensate rounding effects, as the absolute target rect is using floating-point numbers and the image buffer size is integer.
+ imageContext->scale(FloatSize(unclampedImageSize.width() / absoluteTargetRect.width(), unclampedImageSize.height() / absoluteTargetRect.height()));
imageBuffer = image.release();
return true;
}
-void SVGImageBufferTools::clipToImageBuffer(GraphicsContext* context, const AffineTransform& absoluteTransform, const FloatRect& absoluteTargetRect, ImageBuffer* imageBuffer)
+void SVGImageBufferTools::renderSubtreeToImageBuffer(ImageBuffer* image, RenderObject* item, const AffineTransform& subtreeContentTransformation)
+{
+ ASSERT(item);
+ ASSERT(image);
+ ASSERT(image->context());
+
+ PaintInfo info(image->context(), PaintInfo::infiniteRect(), PaintPhaseForeground, 0, 0, 0);
+
+ // FIXME: isSVGContainer returns true for RenderSVGViewportContainer, so if this is ever
+ // called with one of those, we will read from the wrong offset in an object due to a bad cast.
+ RenderSVGContainer* svgContainer = 0;
+ if (item && item->isSVGContainer())
+ svgContainer = toRenderSVGContainer(item);
+
+ bool drawsContents = svgContainer ? svgContainer->drawsContents() : false;
+ if (svgContainer && !drawsContents)
+ svgContainer->setDrawsContents(true);
+
+ AffineTransform& contentTransformation = currentContentTransformation();
+ AffineTransform savedContentTransformation = contentTransformation;
+ contentTransformation.multiply(subtreeContentTransformation);
+
+ item->layoutIfNeeded();
+ item->paint(info, 0, 0);
+
+ contentTransformation = savedContentTransformation;
+
+ if (svgContainer && !drawsContents)
+ svgContainer->setDrawsContents(false);
+}
+
+void SVGImageBufferTools::clipToImageBuffer(GraphicsContext* context, const AffineTransform& absoluteTransform, const FloatRect& clampedAbsoluteTargetRect, OwnPtr<ImageBuffer>& imageBuffer)
{
ASSERT(context);
ASSERT(imageBuffer);
- // The mask image has been created in the device coordinate space, as the image should not be scaled.
- // So the actual masking process has to be done in the device coordinate space as well.
+ // The mask image has been created in the absolute coordinate space, as the image should not be scaled.
+ // So the actual masking process has to be done in the absolute coordinate space as well.
context->concatCTM(absoluteTransform.inverse());
- context->clipToImageBuffer(imageBuffer, absoluteTargetRect);
+ context->clipToImageBuffer(imageBuffer.get(), clampedAbsoluteTargetRect);
context->concatCTM(absoluteTransform);
+
+ // When nesting resources, with objectBoundingBox as content unit types, there's no use in caching the
+ // resulting image buffer as the parent resource already caches the result.
+ if (!currentContentTransformation().isIdentity())
+ imageBuffer.clear();
+}
+
+IntSize SVGImageBufferTools::roundedImageBufferSize(const FloatSize& size)
+{
+ return IntSize(static_cast<int>(lroundf(size.width())), static_cast<int>(lroundf(size.height())));
+}
+
+FloatRect SVGImageBufferTools::clampedAbsoluteTargetRectForRenderer(const RenderObject* renderer, const FloatRect& absoluteTargetRect)
+{
+ ASSERT(renderer);
+
+ const RenderSVGRoot* svgRoot = SVGRenderSupport::findTreeRootObject(renderer);
+ FloatRect clampedAbsoluteTargetRect = absoluteTargetRect;
+ clampedAbsoluteTargetRect.intersect(svgRoot->contentBoxRect());
+ return clampedAbsoluteTargetRect;
}
}
diff --git a/WebCore/rendering/SVGImageBufferTools.h b/WebCore/rendering/SVGImageBufferTools.h
index bdbcb1c..8894aae 100644
--- a/WebCore/rendering/SVGImageBufferTools.h
+++ b/WebCore/rendering/SVGImageBufferTools.h
@@ -28,15 +28,19 @@ namespace WebCore {
class AffineTransform;
class FloatRect;
+class FloatSize;
class GraphicsContext;
class RenderObject;
class SVGImageBufferTools : public Noncopyable {
public:
- static bool createImageBuffer(const AffineTransform& absoluteTransform, const FloatRect& absoluteTargetRect, OwnPtr<ImageBuffer>&, ImageColorSpace);
- static void clipToImageBuffer(GraphicsContext*, const AffineTransform& absoluteTransform, const FloatRect& absoluteTargetRect, ImageBuffer*);
+ static bool createImageBuffer(const FloatRect& absoluteTargetRect, const FloatRect& clampedAbsoluteTargetRect, OwnPtr<ImageBuffer>&, ImageColorSpace);
+ static void renderSubtreeToImageBuffer(ImageBuffer*, RenderObject*, const AffineTransform&);
+ static void clipToImageBuffer(GraphicsContext*, const AffineTransform& absoluteTransform, const FloatRect& clampedAbsoluteTargetRect, OwnPtr<ImageBuffer>&);
- static AffineTransform absoluteTransformFromContext(GraphicsContext*);
+ static void calculateTransformationToOutermostSVGCoordinateSystem(const RenderObject*, AffineTransform& absoluteTransform);
+ static FloatRect clampedAbsoluteTargetRectForRenderer(const RenderObject*, const FloatRect& absoluteTargetRect);
+ static IntSize roundedImageBufferSize(const FloatSize&);
private:
SVGImageBufferTools() { }
diff --git a/WebCore/rendering/SVGInlineTextBox.cpp b/WebCore/rendering/SVGInlineTextBox.cpp
index f5bbe5b..ccba5b4 100644
--- a/WebCore/rendering/SVGInlineTextBox.cpp
+++ b/WebCore/rendering/SVGInlineTextBox.cpp
@@ -408,7 +408,7 @@ void SVGInlineTextBox::computeTextMatchMarkerRect(RenderStyle* style)
return;
Document* document = renderer()->document();
- Vector<DocumentMarker> markers = document->markersForNode(renderer()->node());
+ Vector<DocumentMarker> markers = document->markers()->markersForNode(renderer()->node());
Vector<DocumentMarker>::iterator markerEnd = markers.end();
for (Vector<DocumentMarker>::iterator markerIt = markers.begin(); markerIt != markerEnd; ++markerIt) {
@@ -430,7 +430,7 @@ void SVGInlineTextBox::computeTextMatchMarkerRect(RenderStyle* style)
if (!m_chunkTransformation.isIdentity())
markerRect = m_chunkTransformation.mapRect(markerRect);
- document->setRenderedRectForMarker(node, marker, renderer()->localToAbsoluteQuad(markerRect).enclosingBoundingBox());
+ document->markers()->setRenderedRectForMarker(node, marker, renderer()->localToAbsoluteQuad(markerRect).enclosingBoundingBox());
}
}
diff --git a/WebCore/rendering/SVGRenderSupport.cpp b/WebCore/rendering/SVGRenderSupport.cpp
index e265b2b..12d6d77 100644
--- a/WebCore/rendering/SVGRenderSupport.cpp
+++ b/WebCore/rendering/SVGRenderSupport.cpp
@@ -33,7 +33,6 @@
#include "NodeRenderStyle.h"
#include "RenderLayer.h"
#include "RenderPath.h"
-#include "RenderSVGContainer.h"
#include "RenderSVGResource.h"
#include "RenderSVGResourceClipper.h"
#include "RenderSVGResourceFilter.h"
@@ -116,8 +115,10 @@ bool SVGRenderSupport::prepareToRenderSVGContent(RenderObject* object, PaintInfo
return false;
}
- if (RenderSVGResourceClipper* clipper = resources->clipper())
- clipper->applyResource(object, style, paintInfo.context, ApplyToDefaultMode);
+ if (RenderSVGResourceClipper* clipper = resources->clipper()) {
+ if (!clipper->applyResource(object, style, paintInfo.context, ApplyToDefaultMode))
+ return false;
+ }
#if ENABLE(FILTERS)
if (RenderSVGResourceFilter* filter = resources->filter()) {
@@ -163,37 +164,6 @@ void SVGRenderSupport::finishRenderSVGContent(RenderObject* object, PaintInfo& p
paintInfo.context->endTransparencyLayer();
}
-void SVGRenderSupport::renderSubtreeToImage(ImageBuffer* image, RenderObject* item)
-{
- ASSERT(item);
- ASSERT(image);
- ASSERT(image->context());
-
- // FIXME: This sets the rect to the viewable area of the current frame. This
- // is used to support text drawings to the ImageBuffer. See bug 30399.
- IntRect rect;
- FrameView* frameView = item->document()->view();
- if (frameView)
- rect = IntRect(0, 0, frameView->visibleWidth(), frameView->visibleHeight());
- PaintInfo info(image->context(), rect, PaintPhaseForeground, 0, 0, 0);
-
- // FIXME: isSVGContainer returns true for RenderSVGViewportContainer, so if this is ever
- // called with one of those, we will read from the wrong offset in an object due to a bad cast.
- RenderSVGContainer* svgContainer = 0;
- if (item && item->isSVGContainer())
- svgContainer = toRenderSVGContainer(item);
-
- bool drawsContents = svgContainer ? svgContainer->drawsContents() : false;
- if (svgContainer && !drawsContents)
- svgContainer->setDrawsContents(true);
-
- item->layoutIfNeeded();
- item->paint(info, 0, 0);
-
- if (svgContainer && !drawsContents)
- svgContainer->setDrawsContents(false);
-}
-
FloatRect SVGRenderSupport::computeContainerBoundingBox(const RenderObject* container, ContainerBoundingBoxMode mode)
{
FloatRect boundingBox;
@@ -219,7 +189,7 @@ FloatRect SVGRenderSupport::computeContainerBoundingBox(const RenderObject* cont
return boundingBox;
}
-static inline RenderSVGRoot* svgRootTreeObject(RenderObject* start)
+const RenderSVGRoot* SVGRenderSupport::findTreeRootObject(const RenderObject* start)
{
while (start && !start->isSVGRoot())
start = start->parent();
@@ -241,7 +211,7 @@ static inline void invalidateResourcesOfChildren(RenderObject* start)
void SVGRenderSupport::layoutChildren(RenderObject* start, bool selfNeedsLayout)
{
- bool layoutSizeChanged = svgRootTreeObject(start)->isLayoutSizeChanged();
+ bool layoutSizeChanged = findTreeRootObject(start)->isLayoutSizeChanged();
HashSet<RenderObject*> notlayoutedObjects;
for (RenderObject* child = start->firstChild(); child; child = child->nextSibling()) {
diff --git a/WebCore/rendering/SVGRenderSupport.h b/WebCore/rendering/SVGRenderSupport.h
index 576475b..2de1e99 100644
--- a/WebCore/rendering/SVGRenderSupport.h
+++ b/WebCore/rendering/SVGRenderSupport.h
@@ -36,6 +36,7 @@ class ImageBuffer;
class RenderBoxModelObject;
class RenderObject;
class RenderStyle;
+class RenderSVGRoot;
class TransformState;
// SVGRendererSupport is a helper class sharing code between all SVG renderers.
@@ -72,14 +73,12 @@ public:
static void computeRectForRepaint(RenderObject*, RenderBoxModelObject* repaintContainer, IntRect&, bool fixed);
static void mapLocalToContainer(const RenderObject*, RenderBoxModelObject* repaintContainer, bool useTransforms, bool fixed, TransformState&);
- // This offers a way to render parts of a WebKit rendering tree into a ImageBuffer.
- static void renderSubtreeToImage(ImageBuffer*, RenderObject*);
-
// Shared between SVG renderers and resources.
static void applyStrokeStyleToContext(GraphicsContext*, const RenderStyle*, const RenderObject*);
// FIXME: These methods do not belong here.
static const RenderObject* findTextRootObject(const RenderObject* start);
+ static const RenderSVGRoot* findTreeRootObject(const RenderObject* start);
private:
// This class is not constructable.
diff --git a/WebCore/rendering/SVGShadowTreeElements.cpp b/WebCore/rendering/SVGShadowTreeElements.cpp
index f26f87e..311874c 100644
--- a/WebCore/rendering/SVGShadowTreeElements.cpp
+++ b/WebCore/rendering/SVGShadowTreeElements.cpp
@@ -45,7 +45,7 @@ FloatSize SVGShadowTreeContainerElement::containerTranslation() const
}
// SVGShadowTreeRootElement
-SVGShadowTreeRootElement::SVGShadowTreeRootElement(Document* document, Node* shadowParent)
+SVGShadowTreeRootElement::SVGShadowTreeRootElement(Document* document, Element* shadowParent)
: SVGShadowTreeContainerElement(document)
, m_shadowParent(shadowParent)
{
diff --git a/WebCore/rendering/SVGShadowTreeElements.h b/WebCore/rendering/SVGShadowTreeElements.h
index ed42e89..7611b8a 100644
--- a/WebCore/rendering/SVGShadowTreeElements.h
+++ b/WebCore/rendering/SVGShadowTreeElements.h
@@ -49,16 +49,16 @@ private:
class SVGShadowTreeRootElement : public SVGShadowTreeContainerElement {
public:
- SVGShadowTreeRootElement(Document*, Node* shadowParent);
+ SVGShadowTreeRootElement(Document*, Element* shadowParent);
virtual ~SVGShadowTreeRootElement();
virtual bool isShadowNode() const { return m_shadowParent; }
- virtual Node* shadowParentNode() { return m_shadowParent; }
+ virtual ContainerNode* shadowParentNode() { return m_shadowParent; }
void attachElement(PassRefPtr<RenderStyle>, RenderArena*);
private:
- Node* m_shadowParent;
+ ContainerNode* m_shadowParent;
};
}
diff --git a/WebCore/rendering/ShadowElement.cpp b/WebCore/rendering/ShadowElement.cpp
index 55a4b5c..c52ce17 100644
--- a/WebCore/rendering/ShadowElement.cpp
+++ b/WebCore/rendering/ShadowElement.cpp
@@ -29,12 +29,12 @@ namespace WebCore {
using namespace HTMLNames;
-PassRefPtr<ShadowBlockElement> ShadowBlockElement::create(Node* shadowParent)
+PassRefPtr<ShadowBlockElement> ShadowBlockElement::create(HTMLElement* shadowParent)
{
return adoptRef(new ShadowBlockElement(shadowParent));
}
-ShadowBlockElement::ShadowBlockElement(Node* shadowParent)
+ShadowBlockElement::ShadowBlockElement(HTMLElement* shadowParent)
: ShadowElement<HTMLDivElement>(divTag, shadowParent)
{
}
@@ -66,7 +66,7 @@ void ShadowBlockElement::updateStyleForPart(PseudoId pseudoId)
renderer()->setStyle(createStyleForPart(renderer()->parent(), pseudoId));
}
-PassRefPtr<ShadowBlockElement> ShadowBlockElement::createForPart(Node* shadowParent, PseudoId pseudoId)
+PassRefPtr<ShadowBlockElement> ShadowBlockElement::createForPart(HTMLElement* shadowParent, PseudoId pseudoId)
{
RenderObject* parentRenderer = shadowParent->renderer();
RefPtr<RenderStyle> styleForPart = createStyleForPart(parentRenderer, pseudoId);
@@ -103,12 +103,12 @@ bool ShadowBlockElement::partShouldHaveStyle(const RenderObject* parentRenderer,
return !(pseudoStyle && pseudoStyle->hasAppearance());
}
-PassRefPtr<ShadowInputElement> ShadowInputElement::create(Node* shadowParent)
+PassRefPtr<ShadowInputElement> ShadowInputElement::create(HTMLElement* shadowParent)
{
return adoptRef(new ShadowInputElement(shadowParent));
}
-ShadowInputElement::ShadowInputElement(Node* shadowParent)
+ShadowInputElement::ShadowInputElement(HTMLElement* shadowParent)
: ShadowElement<HTMLInputElement>(inputTag, shadowParent)
{
}
diff --git a/WebCore/rendering/ShadowElement.h b/WebCore/rendering/ShadowElement.h
index b8aacfd..04db62b 100644
--- a/WebCore/rendering/ShadowElement.h
+++ b/WebCore/rendering/ShadowElement.h
@@ -37,31 +37,31 @@ namespace WebCore {
template<class BaseElement>
class ShadowElement : public BaseElement {
protected:
- ShadowElement(const QualifiedName& name, Node* shadowParent)
+ ShadowElement(const QualifiedName& name, HTMLElement* shadowParent)
: BaseElement(name, shadowParent->document())
, m_shadowParent(shadowParent)
{
}
- Node* shadowParent() const { return m_shadowParent; }
+ HTMLElement* shadowParent() const { return m_shadowParent; }
private:
virtual bool isShadowNode() const { return true; }
- virtual Node* shadowParentNode() { return m_shadowParent; }
+ virtual ContainerNode* shadowParentNode() { return m_shadowParent; }
- Node* m_shadowParent;
+ HTMLElement* m_shadowParent;
};
class ShadowBlockElement : public ShadowElement<HTMLDivElement> {
public:
- static PassRefPtr<ShadowBlockElement> create(Node*);
- static PassRefPtr<ShadowBlockElement> createForPart(Node*, PseudoId);
+ static PassRefPtr<ShadowBlockElement> create(HTMLElement*);
+ static PassRefPtr<ShadowBlockElement> createForPart(HTMLElement*, PseudoId);
static bool partShouldHaveStyle(const RenderObject* parentRenderer, PseudoId pseudoId);
void layoutAsPart(const IntRect& partRect);
void updateStyleForPart(PseudoId);
protected:
- ShadowBlockElement(Node*);
+ ShadowBlockElement(HTMLElement*);
private:
static PassRefPtr<RenderStyle> createStyleForPart(RenderObject*, PseudoId);
@@ -69,9 +69,9 @@ private:
class ShadowInputElement : public ShadowElement<HTMLInputElement> {
public:
- static PassRefPtr<ShadowInputElement> create(Node*);
+ static PassRefPtr<ShadowInputElement> create(HTMLElement*);
protected:
- ShadowInputElement(Node*);
+ ShadowInputElement(HTMLElement*);
};
} // namespace WebCore
diff --git a/WebCore/rendering/TextControlInnerElements.cpp b/WebCore/rendering/TextControlInnerElements.cpp
index 9852aa6..1939133 100644
--- a/WebCore/rendering/TextControlInnerElements.cpp
+++ b/WebCore/rendering/TextControlInnerElements.cpp
@@ -39,6 +39,7 @@
#include "Page.h"
#include "RenderLayer.h"
#include "RenderTextControlSingleLine.h"
+#include "ScrollbarTheme.h"
#include "SpeechInput.h"
namespace WebCore {
@@ -84,13 +85,13 @@ VisiblePosition RenderTextControlInnerBlock::positionForPoint(const IntPoint& po
// ----------------------------
-TextControlInnerElement::TextControlInnerElement(Document* document, Node* shadowParent)
+TextControlInnerElement::TextControlInnerElement(Document* document, HTMLElement* shadowParent)
: HTMLDivElement(divTag, document)
, m_shadowParent(shadowParent)
{
}
-PassRefPtr<TextControlInnerElement> TextControlInnerElement::create(Node* shadowParent)
+PassRefPtr<TextControlInnerElement> TextControlInnerElement::create(HTMLElement* shadowParent)
{
return adoptRef(new TextControlInnerElement(shadowParent->document(), shadowParent));
}
@@ -112,9 +113,12 @@ void TextControlInnerElement::attachInnerElement(Node* parent, PassRefPtr<Render
setInDocument();
// For elements without a shadow parent, add the node to the DOM normally.
- if (!m_shadowParent)
- parent->legacyParserAddChild(this);
-
+ if (!m_shadowParent) {
+ // FIXME: This code seems very wrong. Why are we magically adding |this| to the DOM here?
+ // We shouldn't be calling parser API methods outside of the parser!
+ parent->deprecatedParserAddChild(this);
+ }
+
// Add the renderer to the render tree
if (renderer)
parent->renderer()->addChild(renderer);
@@ -122,12 +126,12 @@ void TextControlInnerElement::attachInnerElement(Node* parent, PassRefPtr<Render
// ----------------------------
-inline TextControlInnerTextElement::TextControlInnerTextElement(Document* document, Node* shadowParent)
+inline TextControlInnerTextElement::TextControlInnerTextElement(Document* document, HTMLElement* shadowParent)
: TextControlInnerElement(document, shadowParent)
{
}
-PassRefPtr<TextControlInnerTextElement> TextControlInnerTextElement::create(Document* document, Node* shadowParent)
+PassRefPtr<TextControlInnerTextElement> TextControlInnerTextElement::create(Document* document, HTMLElement* shadowParent)
{
return adoptRef(new TextControlInnerTextElement(document, shadowParent));
}
@@ -251,14 +255,16 @@ void SearchFieldCancelButtonElement::defaultEventHandler(Event* event)
// ----------------------------
-inline SpinButtonElement::SpinButtonElement(Node* shadowParent)
+inline SpinButtonElement::SpinButtonElement(HTMLElement* shadowParent)
: TextControlInnerElement(shadowParent->document(), shadowParent)
, m_capturing(false)
, m_upDownState(Indeterminate)
+ , m_pressStartingState(Indeterminate)
+ , m_repeatingTimer(this, &SpinButtonElement::repeatingTimerFired)
{
}
-PassRefPtr<SpinButtonElement> SpinButtonElement::create(Node* shadowParent)
+PassRefPtr<SpinButtonElement> SpinButtonElement::create(HTMLElement* shadowParent)
{
return adoptRef(new SpinButtonElement(shadowParent));
}
@@ -271,13 +277,6 @@ void SpinButtonElement::defaultEventHandler(Event* event)
return;
}
- MouseEvent* mouseEvent = static_cast<MouseEvent*>(event);
- if (mouseEvent->button() != LeftButton) {
- if (!event->defaultHandled())
- HTMLDivElement::defaultEventHandler(event);
- return;
- }
-
RenderBox* box = renderBox();
if (!box) {
if (!event->defaultHandled())
@@ -292,23 +291,24 @@ void SpinButtonElement::defaultEventHandler(Event* event)
return;
}
+ MouseEvent* mouseEvent = static_cast<MouseEvent*>(event);
IntPoint local = roundedIntPoint(box->absoluteToLocal(mouseEvent->absoluteLocation(), false, true));
- if (event->type() == eventNames().clickEvent) {
+ if (mouseEvent->type() == eventNames().mousedownEvent && mouseEvent->button() == LeftButton) {
if (box->borderBoxRect().contains(local)) {
RefPtr<Node> protector(input);
input->focus();
input->select();
- if (local.y() < box->height() / 2)
- input->stepUpFromRenderer(1);
- else
- input->stepUpFromRenderer(-1);
+ input->stepUpFromRenderer(m_upDownState == Up ? 1 : -1);
event->setDefaultHandled();
+ startRepeatingTimer();
}
- } else if (event->type() == eventNames().mousemoveEvent) {
+ } else if (mouseEvent->type() == eventNames().mouseupEvent && mouseEvent->button() == LeftButton)
+ stopRepeatingTimer();
+ else if (event->type() == eventNames().mousemoveEvent) {
if (box->borderBoxRect().contains(local)) {
if (!m_capturing) {
if (Frame* frame = document()->frame()) {
- frame->eventHandler()->setCapturingMouseEventsNode(input);
+ frame->eventHandler()->setCapturingMouseEventsNode(this);
m_capturing = true;
}
}
@@ -318,6 +318,7 @@ void SpinButtonElement::defaultEventHandler(Event* event)
renderer()->repaint();
} else {
if (m_capturing) {
+ stopRepeatingTimer();
if (Frame* frame = document()->frame()) {
frame->eventHandler()->setCapturingMouseEventsNode(0);
m_capturing = false;
@@ -330,6 +331,33 @@ void SpinButtonElement::defaultEventHandler(Event* event)
HTMLDivElement::defaultEventHandler(event);
}
+void SpinButtonElement::startRepeatingTimer()
+{
+ m_pressStartingState = m_upDownState;
+ ScrollbarTheme* theme = ScrollbarTheme::nativeTheme();
+ m_repeatingTimer.start(theme->initialAutoscrollTimerDelay(), theme->autoscrollTimerDelay());
+}
+
+void SpinButtonElement::stopRepeatingTimer()
+{
+ m_repeatingTimer.stop();
+}
+
+void SpinButtonElement::repeatingTimerFired(Timer<SpinButtonElement>*)
+{
+ HTMLInputElement* input = static_cast<HTMLInputElement*>(shadowAncestorNode());
+ if (input->disabled() || input->isReadOnlyFormControl())
+ return;
+ // On Mac OS, NSStepper updates the value for the button under the mouse
+ // cursor regardless of the button pressed at the beginning. So the
+ // following check is not needed for Mac OS.
+#if !OS(MAC_OS_X)
+ if (m_upDownState != m_pressStartingState)
+ return;
+#endif
+ input->stepUpFromRenderer(m_upDownState == Up ? 1 : -1);
+}
+
void SpinButtonElement::setHovered(bool flag)
{
if (!hovered() && flag)
@@ -342,7 +370,7 @@ void SpinButtonElement::setHovered(bool flag)
#if ENABLE(INPUT_SPEECH)
-inline InputFieldSpeechButtonElement::InputFieldSpeechButtonElement(Node* shadowParent)
+inline InputFieldSpeechButtonElement::InputFieldSpeechButtonElement(HTMLElement* shadowParent)
: TextControlInnerElement(shadowParent->document(), shadowParent)
, m_capturing(false)
, m_state(Idle)
@@ -360,7 +388,7 @@ InputFieldSpeechButtonElement::~InputFieldSpeechButtonElement()
}
}
-PassRefPtr<InputFieldSpeechButtonElement> InputFieldSpeechButtonElement::create(Node* shadowParent)
+PassRefPtr<InputFieldSpeechButtonElement> InputFieldSpeechButtonElement::create(HTMLElement* shadowParent)
{
return adoptRef(new InputFieldSpeechButtonElement(shadowParent));
}
@@ -397,7 +425,7 @@ void InputFieldSpeechButtonElement::defaultEventHandler(Event* event)
if (event->type() == eventNames().clickEvent) {
switch (m_state) {
case Idle:
- if (speechInput()->startRecognition(m_listenerId))
+ if (speechInput()->startRecognition(m_listenerId, input->renderer()->absoluteBoundingBoxRect()))
setState(Recording);
break;
case Recording:
@@ -455,6 +483,10 @@ void InputFieldSpeechButtonElement::detach()
if (Frame* frame = document()->frame())
frame->eventHandler()->setCapturingMouseEventsNode(0);
}
+
+ if (m_state != Idle)
+ speechInput()->cancelRecognition(m_listenerId);
+
TextControlInnerElement::detach();
}
diff --git a/WebCore/rendering/TextControlInnerElements.h b/WebCore/rendering/TextControlInnerElements.h
index 3fbc9c8..c146a42 100644
--- a/WebCore/rendering/TextControlInnerElements.h
+++ b/WebCore/rendering/TextControlInnerElements.h
@@ -29,6 +29,7 @@
#include "HTMLDivElement.h"
#include "SpeechInputListener.h"
+#include "Timer.h"
#include <wtf/Forward.h>
namespace WebCore {
@@ -37,30 +38,30 @@ class SpeechInput;
class TextControlInnerElement : public HTMLDivElement {
public:
- static PassRefPtr<TextControlInnerElement> create(Node* shadowParent);
+ static PassRefPtr<TextControlInnerElement> create(HTMLElement* shadowParent);
void attachInnerElement(Node*, PassRefPtr<RenderStyle>, RenderArena*);
protected:
- TextControlInnerElement(Document*, Node* shadowParent = 0);
+ TextControlInnerElement(Document*, HTMLElement* shadowParent = 0);
private:
virtual bool isMouseFocusable() const { return false; }
virtual bool isShadowNode() const { return m_shadowParent; }
- virtual Node* shadowParentNode() { return m_shadowParent; }
- void setShadowParentNode(Node* node) { m_shadowParent = node; }
+ virtual ContainerNode* shadowParentNode() { return m_shadowParent; }
+ void setShadowParentNode(HTMLElement* shadowParent) { m_shadowParent = shadowParent; }
- Node* m_shadowParent;
+ HTMLElement* m_shadowParent;
};
class TextControlInnerTextElement : public TextControlInnerElement {
public:
- static PassRefPtr<TextControlInnerTextElement> create(Document*, Node* shadowParent);
+ static PassRefPtr<TextControlInnerTextElement> create(Document*, HTMLElement* shadowParent);
virtual void defaultEventHandler(Event*);
private:
- TextControlInnerTextElement(Document*, Node* shadowParent);
+ TextControlInnerTextElement(Document*, HTMLElement* shadowParent);
virtual RenderObject* createRenderer(RenderArena*, RenderStyle*);
};
@@ -96,21 +97,26 @@ public:
Up,
};
- static PassRefPtr<SpinButtonElement> create(Node*);
+ static PassRefPtr<SpinButtonElement> create(HTMLElement*);
UpDownState upDownState() const { return m_upDownState; }
private:
- SpinButtonElement(Node*);
+ SpinButtonElement(HTMLElement*);
virtual bool isSpinButtonElement() const { return true; }
// FIXME: shadowAncestorNode() should be const.
virtual bool isEnabledFormControl() const { return static_cast<Element*>(const_cast<SpinButtonElement*>(this)->shadowAncestorNode())->isEnabledFormControl(); }
virtual bool isReadOnlyFormControl() const { return static_cast<Element*>(const_cast<SpinButtonElement*>(this)->shadowAncestorNode())->isReadOnlyFormControl(); }
virtual void defaultEventHandler(Event*);
+ void startRepeatingTimer();
+ void stopRepeatingTimer();
+ void repeatingTimerFired(Timer<SpinButtonElement>*);
virtual void setHovered(bool = true);
bool m_capturing;
UpDownState m_upDownState;
+ UpDownState m_pressStartingState;
+ Timer<SpinButtonElement> m_repeatingTimer;
};
#if ENABLE(INPUT_SPEECH)
@@ -125,7 +131,7 @@ public:
Recognizing,
};
- static PassRefPtr<InputFieldSpeechButtonElement> create(Node*);
+ static PassRefPtr<InputFieldSpeechButtonElement> create(HTMLElement*);
virtual ~InputFieldSpeechButtonElement();
virtual void detach();
@@ -138,7 +144,7 @@ public:
void setRecognitionResult(int, const String& result);
private:
- InputFieldSpeechButtonElement(Node*);
+ InputFieldSpeechButtonElement(HTMLElement*);
SpeechInput* speechInput();
void setState(SpeechInputState state);
diff --git a/WebCore/rendering/style/BindingURI.cpp b/WebCore/rendering/style/BindingURI.cpp
deleted file mode 100644
index fd96de4..0000000
--- a/WebCore/rendering/style/BindingURI.cpp
+++ /dev/null
@@ -1,71 +0,0 @@
-/*
- * Copyright (C) 1999 Antti Koivisto (koivisto@kde.org)
- * Copyright (C) 2004, 2005, 2006, 2007, 2008 Apple 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.
- *
- */
-
-#include "config.h"
-#include "BindingURI.h"
-
-#if ENABLE(XBL)
-
-namespace WebCore {
-
-BindingURI::BindingURI(StringImpl* uri)
- : m_next(0)
-{
- m_uri = uri;
- if (uri)
- uri->ref();
-}
-
-BindingURI::~BindingURI()
-{
- if (m_uri)
- m_uri->deref();
- delete m_next;
-}
-
-BindingURI* BindingURI::copy()
-{
- BindingURI* newBinding = new BindingURI(m_uri);
- if (next()) {
- BindingURI* nextCopy = next()->copy();
- newBinding->setNext(nextCopy);
- }
-
- return newBinding;
-}
-
-bool BindingURI::operator==(const BindingURI& o) const
-{
- if ((m_next && !o.m_next) || (!m_next && o.m_next) ||
- (m_next && o.m_next && *m_next != *o.m_next))
- return false;
-
- if (m_uri == o.m_uri)
- return true;
- if (!m_uri || !o.m_uri)
- return false;
-
- return String(m_uri) == String(o.m_uri);
-}
-
-} // namespace WebCore
-
-#endif // ENABLE(XBL)
diff --git a/WebCore/rendering/style/BindingURI.h b/WebCore/rendering/style/BindingURI.h
deleted file mode 100644
index c844b1d..0000000
--- a/WebCore/rendering/style/BindingURI.h
+++ /dev/null
@@ -1,59 +0,0 @@
-/*
- * Copyright (C) 2000 Lars Knoll (knoll@kde.org)
- * (C) 2000 Antti Koivisto (koivisto@kde.org)
- * (C) 2000 Dirk Mueller (mueller@kde.org)
- * Copyright (C) 2003, 2005, 2006, 2007, 2008 Apple Inc. All rights reserved.
- * Copyright (C) 2006 Graham Dennis (graham.dennis@gmail.com)
- *
- * 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 BindingURI_h
-#define BindingURI_h
-#if ENABLE(XBL)
-
-#include <wtf/text/StringImpl.h>
-
-namespace WebCore {
-
-// This struct holds information about shadows for the text-shadow and box-shadow properties.
-
-struct BindingURI {
- BindingURI(StringImpl*);
- ~BindingURI();
-
- BindingURI* copy();
-
- bool operator==(const BindingURI& o) const;
- bool operator!=(const BindingURI& o) const
- {
- return !(*this == o);
- }
-
- BindingURI* next() { return m_next; }
- void setNext(BindingURI* n) { m_next = n; }
-
- StringImpl* uri() { return m_uri; }
-
- BindingURI* m_next;
- StringImpl* m_uri;
-};
-
-} // namespace WebCore
-
-#endif // ENABLE(XBL)
-#endif // BindingURI_h
diff --git a/WebCore/rendering/style/RenderStyle.cpp b/WebCore/rendering/style/RenderStyle.cpp
index 5a66c67..aaccbf7 100644
--- a/WebCore/rendering/style/RenderStyle.cpp
+++ b/WebCore/rendering/style/RenderStyle.cpp
@@ -699,20 +699,6 @@ void RenderStyle::applyTransform(TransformationMatrix& transform, const IntSize&
}
}
-#if ENABLE(XBL)
-void RenderStyle::addBindingURI(StringImpl* uri)
-{
- BindingURI* binding = new BindingURI(uri);
- if (!bindingURIs())
- SET_VAR(rareNonInheritedData, bindingURI, binding)
- else
- for (BindingURI* b = bindingURIs(); b; b = b->next()) {
- if (!b->next())
- b->setNext(binding);
- }
-}
-#endif
-
void RenderStyle::setTextShadow(ShadowData* val, bool add)
{
ASSERT(!val || (!val->spread() && val->style() == Normal));
diff --git a/WebCore/rendering/style/RenderStyle.h b/WebCore/rendering/style/RenderStyle.h
index df32d6b..1681890 100644
--- a/WebCore/rendering/style/RenderStyle.h
+++ b/WebCore/rendering/style/RenderStyle.h
@@ -87,10 +87,6 @@
#include "SVGRenderStyle.h"
#endif
-#if ENABLE(XBL)
-#include "BindingURI.h"
-#endif
-
#if COMPILER(WINSCW)
#define compareEqual(t, u) ((t) == (u))
#else
@@ -598,9 +594,6 @@ public:
EPageBreak pageBreakAfter() const { return static_cast<EPageBreak>(noninherited_flags._page_break_after); }
// CSS3 Getter Methods
-#if ENABLE(XBL)
- BindingURI* bindingURIs() const { return rareNonInheritedData->bindingURI; }
-#endif
int outlineOffset() const
{
@@ -963,12 +956,6 @@ public:
void setPageBreakAfter(EPageBreak b) { noninherited_flags._page_break_after = b; }
// CSS3 Setters
-#if ENABLE(XBL)
- void deleteBindingURIs() { SET_VAR(rareNonInheritedData, bindingURI, static_cast<BindingURI*>(0)); }
- void inheritBindingURIs(BindingURI* other) { SET_VAR(rareNonInheritedData, bindingURI, other->copy()); }
- void addBindingURI(StringImpl* uri);
-#endif
-
void setOutlineOffset(int v) { SET_VAR(m_background, m_outline.m_offset, v) }
void setTextShadow(ShadowData* val, bool add=false);
void setTextStrokeColor(const Color& c) { SET_VAR(rareInheritedData, textStrokeColor, c) }
diff --git a/WebCore/rendering/style/SVGRenderStyle.cpp b/WebCore/rendering/style/SVGRenderStyle.cpp
index 0df26f4..dc8a5af 100644
--- a/WebCore/rendering/style/SVGRenderStyle.cpp
+++ b/WebCore/rendering/style/SVGRenderStyle.cpp
@@ -178,6 +178,10 @@ StyleDifference SVGRenderStyle::diff(const SVGRenderStyle* other) const
// NOTE: All comparisions below may only return StyleDifferenceRepaint
+ // Shadow changes need to cause repaints.
+ if (shadowSVG != other->shadowSVG)
+ return StyleDifferenceRepaint;
+
// Painting related properties only need repaints.
if (miscNotEqual) {
if (misc->floodColor != other->misc->floodColor
diff --git a/WebCore/rendering/style/StyleRareNonInheritedData.cpp b/WebCore/rendering/style/StyleRareNonInheritedData.cpp
index d5c9536..e293984 100644
--- a/WebCore/rendering/style/StyleRareNonInheritedData.cpp
+++ b/WebCore/rendering/style/StyleRareNonInheritedData.cpp
@@ -56,9 +56,6 @@ StyleRareNonInheritedData::StyleRareNonInheritedData()
, m_perspective(RenderStyle::initialPerspective())
, m_perspectiveOriginX(RenderStyle::initialPerspectiveOriginX())
, m_perspectiveOriginY(RenderStyle::initialPerspectiveOriginY())
-#if ENABLE(XBL)
- , bindingURI(0)
-#endif
, m_pageSize()
, m_pageSizeType(PAGE_SIZE_AUTO)
{
@@ -97,9 +94,6 @@ StyleRareNonInheritedData::StyleRareNonInheritedData(const StyleRareNonInherited
, m_perspective(o.m_perspective)
, m_perspectiveOriginX(o.m_perspectiveOriginX)
, m_perspectiveOriginY(o.m_perspectiveOriginY)
-#if ENABLE(XBL)
- , bindingURI(o.bindingURI ? o.bindingURI->copy() : 0)
-#endif
, m_pageSize(o.m_pageSize)
, m_pageSizeType(o.m_pageSizeType)
{
@@ -109,18 +103,6 @@ StyleRareNonInheritedData::~StyleRareNonInheritedData()
{
}
-#if ENABLE(XBL)
-bool StyleRareNonInheritedData::bindingsEquivalent(const StyleRareNonInheritedData& o) const
-{
- if (this == &o) return true;
- if (!bindingURI && o.bindingURI || bindingURI && !o.bindingURI)
- return false;
- if (bindingURI && o.bindingURI && (*bindingURI != *o.bindingURI))
- return false;
- return true;
-}
-#endif
-
bool StyleRareNonInheritedData::operator==(const StyleRareNonInheritedData& o) const
{
return lineClamp == o.lineClamp
@@ -152,9 +134,6 @@ bool StyleRareNonInheritedData::operator==(const StyleRareNonInheritedData& o) c
&& transitionDataEquivalent(o)
&& m_mask == o.m_mask
&& m_maskBoxImage == o.m_maskBoxImage
-#if ENABLE(XBL)
- && bindingsEquivalent(o)
-#endif
&& (m_transformStyle3D == o.m_transformStyle3D)
&& (m_backfaceVisibility == o.m_backfaceVisibility)
&& (m_perspective == o.m_perspective)
diff --git a/WebCore/rendering/style/StyleRareNonInheritedData.h b/WebCore/rendering/style/StyleRareNonInheritedData.h
index 1025d81..6003ea4 100644
--- a/WebCore/rendering/style/StyleRareNonInheritedData.h
+++ b/WebCore/rendering/style/StyleRareNonInheritedData.h
@@ -54,10 +54,6 @@ struct LengthSize;
struct StyleDashboardRegion;
#endif
-#if ENABLE(XBL)
-class BindingURI;
-#endif
-
// Page size type.
// StyleRareNonInheritedData::m_pageSize is meaningful only when
// StyleRareNonInheritedData::m_pageSizeType is PAGE_SIZE_RESOLVED.
@@ -77,10 +73,6 @@ public:
PassRefPtr<StyleRareNonInheritedData> copy() const { return adoptRef(new StyleRareNonInheritedData(*this)); }
~StyleRareNonInheritedData();
-#if ENABLE(XBL)
- bool bindingsEquivalent(const StyleRareNonInheritedData&) const;
-#endif
-
bool operator==(const StyleRareNonInheritedData&) const;
bool operator!=(const StyleRareNonInheritedData& o) const { return !(*this == o); }
@@ -137,10 +129,6 @@ public:
LengthSize m_pageSize;
PageSizeType m_pageSizeType;
-#if ENABLE(XBL)
- OwnPtr<BindingURI> bindingURI; // The XBL binding URI list.
-#endif
-
private:
StyleRareNonInheritedData();
StyleRareNonInheritedData(const StyleRareNonInheritedData&);
diff --git a/WebCore/storage/DOMFilePath.cpp b/WebCore/storage/DOMFilePath.cpp
new file mode 100644
index 0000000..2da057c
--- /dev/null
+++ b/WebCore/storage/DOMFilePath.cpp
@@ -0,0 +1,166 @@
+/*
+ * Copyright (C) 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 "DOMFilePath.h"
+
+#if ENABLE(FILE_SYSTEM)
+
+#include "RegularExpression.h"
+#include <wtf/Vector.h>
+#include <wtf/text/CString.h>
+
+namespace WebCore {
+
+const char DOMFilePath::separator = '/';
+const char DOMFilePath::root[] = "/";
+
+String DOMFilePath::append(const String& base, const String& components)
+{
+ return ensureDirectoryPath(base) + components;
+}
+
+String DOMFilePath::ensureDirectoryPath(const String& path)
+{
+ if (!DOMFilePath::endsWithSeparator(path)) {
+ String newPath = path;
+ newPath.append(DOMFilePath::separator);
+ return newPath;
+ }
+ return path;
+}
+
+String DOMFilePath::getName(const String& path)
+{
+ int index = path.reverseFind(DOMFilePath::separator);
+ if (index != -1)
+ return path.substring(index);
+ return path;
+}
+
+String DOMFilePath::getDirectory(const String& path)
+{
+ int index = path.reverseFind(DOMFilePath::separator);
+ if (index == 0)
+ return DOMFilePath::root;
+ if (index != -1)
+ return path.substring(0, index);
+ return ".";
+}
+
+bool DOMFilePath::isParentOf(const String& parent, const String& mayBeChild)
+{
+ ASSERT(DOMFilePath::isAbsolute(parent));
+ ASSERT(DOMFilePath::isAbsolute(mayBeChild));
+ if (parent == DOMFilePath::root && mayBeChild != DOMFilePath::root)
+ return true;
+ if (parent.length() >= mayBeChild.length() || !mayBeChild.startsWith(parent, false))
+ return false;
+ if (mayBeChild[parent.length()] != DOMFilePath::separator)
+ return false;
+ return true;
+}
+
+String DOMFilePath::removeExtraParentReferences(const String& path)
+{
+ ASSERT(DOMFilePath::isAbsolute(path));
+ Vector<String> components;
+ Vector<String> canonicalized;
+ path.split(DOMFilePath::separator, components);
+ for (size_t i = 0; i < components.size(); ++i) {
+ if (components[i] == ".")
+ continue;
+ if (components[i] == "..") {
+ if (canonicalized.size() > 0)
+ canonicalized.removeLast();
+ continue;
+ }
+ canonicalized.append(components[i]);
+ }
+ if (canonicalized.isEmpty())
+ return DOMFilePath::root;
+ String result;
+ for (size_t i = 0; i < canonicalized.size(); ++i) {
+ result.append(DOMFilePath::separator);
+ result.append(canonicalized[i]);
+ }
+ return result;
+}
+
+// Check the naming restrictions defined in FileSystem API 8.3.
+// http://dev.w3.org/2009/dap/file-system/file-dir-sys.html#naming-restrictions
+bool DOMFilePath::isValidPath(const String& path)
+{
+ if (path.isEmpty() || path == DOMFilePath::root)
+ return true;
+
+ // Chars 0-31 in UTF-8 prepresentation are not allowed.
+ for (size_t i = 0; i < path.length(); ++i)
+ if (path[i] < 32)
+ return false;
+
+ // Unallowed names.
+ DEFINE_STATIC_LOCAL(RegularExpression, unallowedNamesRegExp1, ("(/|^)(CON|PRN|AUX|NUL)([\\./]|$)", TextCaseInsensitive));
+ DEFINE_STATIC_LOCAL(RegularExpression, unallowedNamesRegExp2, ("(/|^)(COM|LPT)[1-9]([\\./]|$)", TextCaseInsensitive));
+
+ if (unallowedNamesRegExp1.match(path) >= 0)
+ return false;
+ if (unallowedNamesRegExp2.match(path) >= 0)
+ return false;
+
+ // Names must not end with period or whitespace.
+ DEFINE_STATIC_LOCAL(RegularExpression, endingRegExp, ("[\\.\\s](/|$)", TextCaseInsensitive));
+
+ if (endingRegExp.match(path) >= 0)
+ return false;
+
+ // Unallowed chars: '\', '<', '>', ':', '?', '*', '"', '|'
+ // (We don't check '/' here as this method takes paths as its argument.)
+ DEFINE_STATIC_LOCAL(RegularExpression, unallowedCharsRegExp, ("[\\\\<>:\\?\\*\"|]", TextCaseInsensitive));
+
+ if (unallowedCharsRegExp.match(path) >= 0)
+ return false;
+
+ return true;
+}
+
+bool DOMFilePath::isValidName(const String& name)
+{
+ if (name.isEmpty())
+ return true;
+ // '/' is not allowed in name.
+ if (name.contains('/'))
+ return false;
+ return isValidPath(name);
+}
+
+} // namespace WebCore
+
+#endif // ENABLE(FILE_SYSTEM)
diff --git a/WebCore/storage/DOMFilePath.h b/WebCore/storage/DOMFilePath.h
new file mode 100644
index 0000000..2f2bb23
--- /dev/null
+++ b/WebCore/storage/DOMFilePath.h
@@ -0,0 +1,86 @@
+/*
+ * Copyright (C) 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 DOMFilePath_h
+#define DOMFilePath_h
+
+#include "PlatformString.h"
+#include <wtf/PassRefPtr.h>
+#include <wtf/RefCounted.h>
+
+namespace WebCore {
+
+// DOMFileSystem path utilities. All methods in this class are static.
+class DOMFilePath {
+public:
+ static const char separator;
+ static const char root[];
+
+ // Returns the name part from the given path.
+ static String getName(const String& path);
+
+ // Returns the parent directory path of the given path.
+ static String getDirectory(const String& path);
+
+ // Checks if a given path is a parent of mayBeChild. This method assumes given paths are absolute and do not have extra references to a parent (i.e. "../").
+ static bool isParentOf(const String& path, const String& mayBeChild);
+
+ // Appends the separator at the end of the path if it's not there already.
+ static String ensureDirectoryPath(const String& path);
+
+ // Returns a new path by appending a separator and the supplied path component to the path.
+ static String append(const String& path, const String& component);
+
+ static bool isAbsolute(const String& path)
+ {
+ return path.startsWith(DOMFilePath::root);
+ }
+
+ static bool endsWithSeparator(const String& path)
+ {
+ return path[path.length() - 1] == DOMFilePath::separator;
+ }
+
+ // Evaluates all "../" and "./" segments. Note that "/../" expands to "/", so you can't ever refer to anything above the root directory.
+ static String removeExtraParentReferences(const String& path);
+
+ // Checks if the given path follows the FileSystem API naming restrictions.
+ static bool isValidPath(const String& path);
+
+ // Checks if the given name follows the FileSystem API naming restrictions.
+ static bool isValidName(const String& name);
+
+private:
+ DOMFilePath() { }
+};
+
+} // namespace WebCore
+
+#endif // DOMFilePath_h
diff --git a/WebCore/storage/Database.cpp b/WebCore/storage/Database.cpp
index 961310d..089f9ee 100644
--- a/WebCore/storage/Database.cpp
+++ b/WebCore/storage/Database.cpp
@@ -65,7 +65,7 @@ class DatabaseCreationCallbackTask : public ScriptExecutionContext::Task {
public:
static PassOwnPtr<DatabaseCreationCallbackTask> create(PassRefPtr<Database> database, PassRefPtr<DatabaseCallback> creationCallback)
{
- return new DatabaseCreationCallbackTask(database, creationCallback);
+ return adoptPtr(new DatabaseCreationCallbackTask(database, creationCallback));
}
virtual void performTask(ScriptExecutionContext*)
@@ -142,7 +142,7 @@ class DerefContextTask : public ScriptExecutionContext::Task {
public:
static PassOwnPtr<DerefContextTask> create(PassRefPtr<ScriptExecutionContext> context)
{
- return new DerefContextTask(context);
+ return adoptPtr(new DerefContextTask(context));
}
virtual void performTask(ScriptExecutionContext* context)
@@ -329,7 +329,7 @@ class DeliverPendingCallbackTask : public ScriptExecutionContext::Task {
public:
static PassOwnPtr<DeliverPendingCallbackTask> create(PassRefPtr<SQLTransaction> transaction)
{
- return new DeliverPendingCallbackTask(transaction);
+ return adoptPtr(new DeliverPendingCallbackTask(transaction));
}
virtual void performTask(ScriptExecutionContext*)
diff --git a/WebCore/storage/DatabaseSync.cpp b/WebCore/storage/DatabaseSync.cpp
index 817fdcc..9c654a1 100644
--- a/WebCore/storage/DatabaseSync.cpp
+++ b/WebCore/storage/DatabaseSync.cpp
@@ -161,7 +161,7 @@ class CloseSyncDatabaseOnContextThreadTask : public ScriptExecutionContext::Task
public:
static PassOwnPtr<CloseSyncDatabaseOnContextThreadTask> create(PassRefPtr<DatabaseSync> database)
{
- return new CloseSyncDatabaseOnContextThreadTask(database);
+ return adoptPtr(new CloseSyncDatabaseOnContextThreadTask(database));
}
virtual void performTask(ScriptExecutionContext*)
diff --git a/WebCore/storage/DatabaseTask.h b/WebCore/storage/DatabaseTask.h
index 847846d..b61e465 100644
--- a/WebCore/storage/DatabaseTask.h
+++ b/WebCore/storage/DatabaseTask.h
@@ -98,7 +98,7 @@ class Database::DatabaseOpenTask : public DatabaseTask {
public:
static PassOwnPtr<DatabaseOpenTask> create(Database* db, bool setVersionInNewDatabase, DatabaseTaskSynchronizer* synchronizer, ExceptionCode& code, bool& success)
{
- return new DatabaseOpenTask(db, setVersionInNewDatabase, synchronizer, code, success);
+ return adoptPtr(new DatabaseOpenTask(db, setVersionInNewDatabase, synchronizer, code, success));
}
private:
@@ -118,7 +118,7 @@ class Database::DatabaseCloseTask : public DatabaseTask {
public:
static PassOwnPtr<DatabaseCloseTask> create(Database* db, DatabaseTaskSynchronizer* synchronizer)
{
- return new DatabaseCloseTask(db, synchronizer);
+ return adoptPtr(new DatabaseCloseTask(db, synchronizer));
}
private:
@@ -135,7 +135,7 @@ public:
// Transaction task is never synchronous, so no 'synchronizer' parameter.
static PassOwnPtr<DatabaseTransactionTask> create(PassRefPtr<SQLTransaction> transaction)
{
- return new DatabaseTransactionTask(transaction);
+ return adoptPtr(new DatabaseTransactionTask(transaction));
}
SQLTransaction* transaction() const { return m_transaction.get(); }
@@ -155,7 +155,7 @@ class Database::DatabaseTableNamesTask : public DatabaseTask {
public:
static PassOwnPtr<DatabaseTableNamesTask> create(Database* db, DatabaseTaskSynchronizer* synchronizer, Vector<String>& names)
{
- return new DatabaseTableNamesTask(db, synchronizer, names);
+ return adoptPtr(new DatabaseTableNamesTask(db, synchronizer, names));
}
private:
diff --git a/WebCore/storage/DatabaseThread.cpp b/WebCore/storage/DatabaseThread.cpp
index 99cf3b9..3b790ee 100644
--- a/WebCore/storage/DatabaseThread.cpp
+++ b/WebCore/storage/DatabaseThread.cpp
@@ -43,8 +43,8 @@ namespace WebCore {
DatabaseThread::DatabaseThread()
: m_threadID(0)
- , m_transactionClient(new SQLTransactionClient())
- , m_transactionCoordinator(new SQLTransactionCoordinator())
+ , m_transactionClient(adoptPtr(new SQLTransactionClient()))
+ , m_transactionCoordinator(adoptPtr(new SQLTransactionCoordinator()))
, m_cleanupSync(0)
{
m_selfRef = this;
diff --git a/WebCore/storage/DatabaseTracker.cpp b/WebCore/storage/DatabaseTracker.cpp
index e0ba422..1a13612 100644
--- a/WebCore/storage/DatabaseTracker.cpp
+++ b/WebCore/storage/DatabaseTracker.cpp
@@ -336,7 +336,7 @@ void DatabaseTracker::populateOrigins()
if (m_quotaMap)
return;
- m_quotaMap.set(new QuotaMap);
+ m_quotaMap = adoptPtr(new QuotaMap);
openTrackerDatabase(false);
if (!m_database.isOpen())
@@ -516,7 +516,7 @@ void DatabaseTracker::addOpenDatabase(AbstractDatabase* database)
MutexLocker openDatabaseMapLock(m_openDatabaseMapGuard);
if (!m_openDatabaseMap)
- m_openDatabaseMap.set(new DatabaseOriginMap);
+ m_openDatabaseMap = adoptPtr(new DatabaseOriginMap);
String name(database->stringIdentifier());
DatabaseNameMap* nameMap = m_openDatabaseMap->get(database->securityOrigin());
diff --git a/WebCore/storage/EntryCallback.h b/WebCore/storage/EntryCallback.h
index 121bf07..9580eda 100644
--- a/WebCore/storage/EntryCallback.h
+++ b/WebCore/storage/EntryCallback.h
@@ -38,7 +38,6 @@
namespace WebCore {
class Entry;
-class ScriptExecutionContext;
class EntryCallback : public RefCounted<EntryCallback> {
public:
diff --git a/WebCore/storage/FileSystemCallback.h b/WebCore/storage/FileSystemCallback.h
index 19f44df..63f8416 100644
--- a/WebCore/storage/FileSystemCallback.h
+++ b/WebCore/storage/FileSystemCallback.h
@@ -38,7 +38,6 @@
namespace WebCore {
class DOMFileSystem;
-class ScriptExecutionContext;
class FileSystemCallback : public RefCounted<FileSystemCallback> {
public:
diff --git a/WebCore/storage/FileSystemCallbacks.cpp b/WebCore/storage/FileSystemCallbacks.cpp
new file mode 100644
index 0000000..ec352dd
--- /dev/null
+++ b/WebCore/storage/FileSystemCallbacks.cpp
@@ -0,0 +1,200 @@
+/*
+ * Copyright (C) 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 "FileSystemCallbacks.h"
+
+#if ENABLE(FILE_SYSTEM)
+
+#include "DOMFileSystem.h"
+#include "DirectoryEntry.h"
+#include "EntriesCallback.h"
+#include "EntryArray.h"
+#include "EntryCallback.h"
+#include "ErrorCallback.h"
+#include "ExceptionCode.h"
+#include "FileEntry.h"
+#include "FileError.h"
+#include "FileSystemCallback.h"
+#include "Metadata.h"
+#include "MetadataCallback.h"
+#include "ScriptExecutionContext.h"
+#include "VoidCallback.h"
+
+namespace WebCore {
+
+FileSystemCallbacksBase::FileSystemCallbacksBase(PassRefPtr<ErrorCallback> errorCallback)
+ : m_errorCallback(errorCallback)
+{
+}
+
+FileSystemCallbacksBase::~FileSystemCallbacksBase()
+{
+}
+
+void FileSystemCallbacksBase::didSucceed()
+{
+ // Each subclass must implement an appropriate one.
+ ASSERT_NOT_REACHED();
+}
+
+void FileSystemCallbacksBase::didOpenFileSystem(const String&, const String&)
+{
+ // Each subclass must implement an appropriate one.
+ ASSERT_NOT_REACHED();
+}
+
+void FileSystemCallbacksBase::didReadMetadata(double)
+{
+ // Each subclass must implement an appropriate one.
+ ASSERT_NOT_REACHED();
+}
+
+void FileSystemCallbacksBase::didReadDirectoryChunkDone(bool)
+{
+ // Each subclass must implement an appropriate one.
+ ASSERT_NOT_REACHED();
+}
+
+void FileSystemCallbacksBase::didReadDirectoryEntry(const String&, bool)
+{
+ // Each subclass must implement an appropriate one.
+ ASSERT_NOT_REACHED();
+}
+
+void FileSystemCallbacksBase::didFail(ExceptionCode code)
+{
+ if (m_errorCallback) {
+ m_errorCallback->handleEvent(FileError::create(code).get());
+ m_errorCallback.clear();
+ }
+}
+
+// EntryCallbacks -------------------------------------------------------------
+
+EntryCallbacks::EntryCallbacks(PassRefPtr<EntryCallback> successCallback, PassRefPtr<ErrorCallback> errorCallback, DOMFileSystem* fileSystem, const String& expectedPath, bool isDirectory)
+ : FileSystemCallbacksBase(errorCallback)
+ , m_successCallback(successCallback)
+ , m_fileSystem(fileSystem)
+ , m_expectedPath(expectedPath)
+ , m_isDirectory(isDirectory)
+{
+}
+
+void EntryCallbacks::didSucceed()
+{
+ if (m_successCallback) {
+ if (m_isDirectory)
+ m_successCallback->handleEvent(DirectoryEntry::create(m_fileSystem, m_expectedPath).get());
+ else
+ m_successCallback->handleEvent(FileEntry::create(m_fileSystem, m_expectedPath).get());
+ }
+ m_successCallback.clear();
+}
+
+// EntriesCallbacks -----------------------------------------------------------
+
+EntriesCallbacks::EntriesCallbacks(PassRefPtr<EntriesCallback> successCallback, PassRefPtr<ErrorCallback> errorCallback, DOMFileSystem* fileSystem, const String& basePath)
+ : FileSystemCallbacksBase(errorCallback)
+ , m_successCallback(successCallback)
+ , m_fileSystem(fileSystem)
+ , m_basePath(basePath)
+{
+}
+
+void EntriesCallbacks::didReadDirectoryEntry(const String& name, bool isDirectory)
+{
+ if (isDirectory)
+ m_entries->append(DirectoryEntry::create(m_fileSystem, m_basePath + "/" + name));
+ else
+ m_entries->append(FileEntry::create(m_fileSystem, m_basePath + "/" + name));
+}
+
+void EntriesCallbacks::didReadDirectoryChunkDone(bool hasMore)
+{
+ if (m_successCallback) {
+ m_successCallback->handleEvent(m_entries.get());
+ m_entries->clear();
+ if (!hasMore) {
+ // If there're no more entries, call back once more with an empty array.
+ m_successCallback->handleEvent(m_entries.get());
+ m_successCallback.clear();
+ }
+ }
+}
+
+// FileSystemCallbacks --------------------------------------------------------
+
+FileSystemCallbacks::FileSystemCallbacks(PassRefPtr<FileSystemCallback> successCallback, PassRefPtr<ErrorCallback> errorCallback)
+ : FileSystemCallbacksBase(errorCallback)
+ , m_successCallback(successCallback)
+{
+}
+
+void FileSystemCallbacks::didOpenFileSystem(const String& name, const String& rootPath)
+{
+ if (m_successCallback)
+ m_successCallback->handleEvent(DOMFileSystem::create(name, rootPath).get());
+ m_successCallback.clear();
+}
+
+// MetadataCallbacks ----------------------------------------------------------
+
+MetadataCallbacks::MetadataCallbacks(PassRefPtr<MetadataCallback> successCallback, PassRefPtr<ErrorCallback> errorCallback)
+ : FileSystemCallbacksBase(errorCallback)
+ , m_successCallback(successCallback)
+{
+}
+
+void MetadataCallbacks::didReadMetadata(double modificationTime)
+{
+ if (m_successCallback)
+ m_successCallback->handleEvent(Metadata::create(modificationTime).get());
+ m_successCallback.clear();
+}
+
+// VoidCallbacks --------------------------------------------------------------
+
+VoidCallbacks::VoidCallbacks(PassRefPtr<VoidCallback> successCallback, PassRefPtr<ErrorCallback> errorCallback)
+ : FileSystemCallbacksBase(errorCallback)
+ , m_successCallback(successCallback)
+{
+}
+
+void VoidCallbacks::didSucceed()
+{
+ if (m_successCallback)
+ m_successCallback->handleEvent();
+ m_successCallback.clear();
+}
+
+} // namespace
+
+#endif // ENABLE(FILE_SYSTEM)
diff --git a/WebCore/storage/FileSystemCallbacks.h b/WebCore/storage/FileSystemCallbacks.h
new file mode 100644
index 0000000..e0e78d3
--- /dev/null
+++ b/WebCore/storage/FileSystemCallbacks.h
@@ -0,0 +1,138 @@
+/*
+ * Copyright (C) 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 FileSystemCallbacks_h
+#define FileSystemCallbacks_h
+
+#if ENABLE(FILE_SYSTEM)
+
+#include "PlatformString.h"
+#include <wtf/PassRefPtr.h>
+#include <wtf/Vector.h>
+
+namespace WebCore {
+
+class DOMFileSystem;
+class ErrorCallback;
+class EntriesCallback;
+class EntryArray;
+class EntryCallback;
+class FileSystemCallback;
+class MetadataCallback;
+class ScriptExecutionContext;
+class VoidCallback;
+
+typedef int ExceptionCode;
+
+// A base class for FileSystem callbacks that bundles successCallback, errorCallback and some closure data for the callbacks.
+class FileSystemCallbacksBase : public Noncopyable {
+public:
+ virtual ~FileSystemCallbacksBase();
+
+ // For EntryCallbacks and VoidCallbacks.
+ virtual void didSucceed();
+
+ // For FileSystemCallbacks.
+ virtual void didOpenFileSystem(const String& name, const String& rootPath);
+
+ // For MetadataCallbacks.
+ virtual void didReadMetadata(double modificationTime);
+
+ // For EntriesCallbacks. didReadDirectoryEntry is called each time the API reads an entry, and didReadDirectoryDone is called when a chunk of entries have been read (i.e. good time to call back to the application). If hasMore is true there can be more chunks.
+ virtual void didReadDirectoryEntry(const String& name, bool isDirectory);
+ virtual void didReadDirectoryChunkDone(bool hasMore);
+
+ // For ErrorCallback.
+ virtual void didFail(ExceptionCode code);
+
+protected:
+ FileSystemCallbacksBase(PassRefPtr<ErrorCallback> errorCallback);
+ RefPtr<ErrorCallback> m_errorCallback;
+};
+
+// Subclasses ----------------------------------------------------------------
+
+class EntryCallbacks : public FileSystemCallbacksBase {
+public:
+ EntryCallbacks(PassRefPtr<EntryCallback>, PassRefPtr<ErrorCallback>, DOMFileSystem*, const String& expectedPath, bool isDirectory);
+ virtual void didSucceed();
+
+private:
+ RefPtr<EntryCallback> m_successCallback;
+ DOMFileSystem* m_fileSystem;
+ String m_expectedPath;
+ bool m_isDirectory;
+};
+
+class EntriesCallbacks : public FileSystemCallbacksBase {
+public:
+ EntriesCallbacks(PassRefPtr<EntriesCallback>, PassRefPtr<ErrorCallback>, DOMFileSystem*, const String& basePath);
+ virtual void didReadDirectoryEntry(const String& name, bool isDirectory);
+ virtual void didReadDirectoryChunkDone(bool hasMore);
+
+private:
+ RefPtr<EntriesCallback> m_successCallback;
+ DOMFileSystem* m_fileSystem;
+ String m_basePath;
+ RefPtr<EntryArray> m_entries;
+};
+
+class FileSystemCallbacks : public FileSystemCallbacksBase {
+public:
+ FileSystemCallbacks(PassRefPtr<FileSystemCallback>, PassRefPtr<ErrorCallback>);
+ virtual void didOpenFileSystem(const String& name, const String& rootPath);
+
+private:
+ RefPtr<FileSystemCallback> m_successCallback;
+};
+
+class MetadataCallbacks : public FileSystemCallbacksBase {
+public:
+ MetadataCallbacks(PassRefPtr<MetadataCallback>, PassRefPtr<ErrorCallback>);
+ virtual void didReadMetadata(double modificationTime);
+
+private:
+ RefPtr<MetadataCallback> m_successCallback;
+};
+
+class VoidCallbacks : public FileSystemCallbacksBase {
+public:
+ VoidCallbacks(PassRefPtr<VoidCallback>, PassRefPtr<ErrorCallback>);
+ virtual void didSucceed();
+
+private:
+ RefPtr<VoidCallback> m_successCallback;
+};
+
+} // namespace
+
+#endif // ENABLE(FILE_SYSTEM)
+
+#endif // FileSystemCallbacks_h
diff --git a/WebCore/storage/IDBAbortEvent.cpp b/WebCore/storage/IDBAbortEvent.cpp
new file mode 100644
index 0000000..21760f8
--- /dev/null
+++ b/WebCore/storage/IDBAbortEvent.cpp
@@ -0,0 +1,55 @@
+/*
+ * Copyright (C) 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:
+ *
+ * 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.
+ * 3. Neither the name of Apple Computer, Inc. ("Apple") 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 APPLE 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 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 "IDBAbortEvent.h"
+
+#if ENABLE(INDEXED_DATABASE)
+
+#include "EventNames.h"
+#include "IDBAny.h"
+
+namespace WebCore {
+
+PassRefPtr<IDBAbortEvent> IDBAbortEvent::create()
+{
+ return adoptRef(new IDBAbortEvent());
+}
+
+IDBAbortEvent::IDBAbortEvent()
+ : IDBEvent(eventNames().abortEvent, 0) // FIXME: set the source to the transaction
+{
+}
+
+IDBAbortEvent::~IDBAbortEvent()
+{
+}
+
+} // namespace WebCore
+
+#endif
diff --git a/WebCore/storage/IDBAbortEvent.h b/WebCore/storage/IDBAbortEvent.h
new file mode 100644
index 0000000..bdc2202
--- /dev/null
+++ b/WebCore/storage/IDBAbortEvent.h
@@ -0,0 +1,57 @@
+/*
+ * Copyright (C) 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:
+ *
+ * 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.
+ * 3. Neither the name of Apple Computer, Inc. ("Apple") 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 APPLE 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 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 IDBAbortEvent_h
+#define IDBAbortEvent_h
+
+#if ENABLE(INDEXED_DATABASE)
+
+#include "IDBEvent.h"
+#include "PlatformString.h"
+#include <wtf/PassRefPtr.h>
+#include <wtf/RefPtr.h>
+
+namespace WebCore {
+
+class IDBAbortEvent : public IDBEvent {
+public:
+ static PassRefPtr<IDBAbortEvent> create();
+ // FIXME: Need to allow creation of these events from JS.
+ virtual ~IDBAbortEvent();
+
+ virtual bool isIDBAbortEvent() const { return true; }
+
+private:
+ IDBAbortEvent();
+};
+
+} // namespace WebCore
+
+#endif // ENABLE(INDEXED_DATABASE)
+
+#endif // IDBAbortEvent_h
diff --git a/WebCore/storage/IDBCursorBackendImpl.cpp b/WebCore/storage/IDBCursorBackendImpl.cpp
index 4e08b8f..d3298b3 100644
--- a/WebCore/storage/IDBCursorBackendImpl.cpp
+++ b/WebCore/storage/IDBCursorBackendImpl.cpp
@@ -33,6 +33,7 @@
#include "IDBKeyRange.h"
#include "IDBObjectStoreBackendImpl.h"
#include "IDBRequest.h"
+#include "SQLiteDatabase.h"
#include "SerializedScriptValue.h"
namespace WebCore {
diff --git a/WebCore/storage/IDBDatabase.cpp b/WebCore/storage/IDBDatabase.cpp
index b00695b..78a6646 100644
--- a/WebCore/storage/IDBDatabase.cpp
+++ b/WebCore/storage/IDBDatabase.cpp
@@ -39,7 +39,6 @@ namespace WebCore {
IDBDatabase::IDBDatabase(PassRefPtr<IDBDatabaseBackendInterface> backend)
: m_backend(backend)
- , m_description(m_backend->description())
{
// We pass a reference to this object before it can be adopted.
relaxAdoptionRequirement();
@@ -75,8 +74,10 @@ PassRefPtr<IDBTransaction> IDBDatabase::transaction(ScriptExecutionContext* cont
// We need to create a new transaction synchronously. Locks are acquired asynchronously. Operations
// can be queued against the transaction at any point. They will start executing as soon as the
// appropriate locks have been acquired.
+ // Also note that each backend object corresponds to exactly one IDBTransaction object.
RefPtr<IDBTransactionBackendInterface> transactionBackend = m_backend->transaction(storeNames, mode, timeout);
- RefPtr<IDBTransaction> transaction = IDBTransaction::create(context, transactionBackend.release(), this);
+ RefPtr<IDBTransaction> transaction = IDBTransaction::create(context, transactionBackend, this);
+ transactionBackend->setCallbacks(transaction.get());
return transaction.release();
}
diff --git a/WebCore/storage/IDBDatabase.h b/WebCore/storage/IDBDatabase.h
index 1ad3c65..0e83288 100644
--- a/WebCore/storage/IDBDatabase.h
+++ b/WebCore/storage/IDBDatabase.h
@@ -52,7 +52,6 @@ public:
// Implement the IDL
String name() const { return m_backend->name(); }
- String description() const { return m_description; }
String version() const { return m_backend->version(); }
PassRefPtr<DOMStringList> objectStores() const { return m_backend->objectStores(); }
@@ -65,8 +64,6 @@ private:
IDBDatabase(PassRefPtr<IDBDatabaseBackendInterface>);
RefPtr<IDBDatabaseBackendInterface> m_backend;
-
- String m_description;
};
} // namespace WebCore
diff --git a/WebCore/storage/IDBDatabase.idl b/WebCore/storage/IDBDatabase.idl
index 4e3f620..51bbafb 100644
--- a/WebCore/storage/IDBDatabase.idl
+++ b/WebCore/storage/IDBDatabase.idl
@@ -29,7 +29,6 @@ module storage {
Conditional=INDEXED_DATABASE
] IDBDatabase {
readonly attribute DOMString name;
- readonly attribute DOMString description;
readonly attribute DOMString version;
readonly attribute DOMStringList objectStores;
diff --git a/WebCore/storage/IDBDatabaseBackendImpl.cpp b/WebCore/storage/IDBDatabaseBackendImpl.cpp
index e550e18..23bc44e 100644
--- a/WebCore/storage/IDBDatabaseBackendImpl.cpp
+++ b/WebCore/storage/IDBDatabaseBackendImpl.cpp
@@ -29,8 +29,10 @@
#include "DOMStringList.h"
#include "IDBDatabaseException.h"
#include "IDBObjectStoreBackendImpl.h"
+#include "IDBTransactionCoordinator.h"
#include "SQLiteDatabase.h"
#include "SQLiteStatement.h"
+#include "SQLiteTransaction.h"
#if ENABLE(INDEXED_DATABASE)
@@ -83,10 +85,11 @@ static bool setMetaData(SQLiteDatabase* sqliteDatabase, const String& name, cons
return true;
}
-IDBDatabaseBackendImpl::IDBDatabaseBackendImpl(const String& name, const String& description, PassOwnPtr<SQLiteDatabase> sqliteDatabase)
+IDBDatabaseBackendImpl::IDBDatabaseBackendImpl(const String& name, const String& description, PassOwnPtr<SQLiteDatabase> sqliteDatabase, IDBTransactionCoordinator* coordinator)
: m_sqliteDatabase(sqliteDatabase)
, m_name(name)
, m_version("")
+ , m_transactionCoordinator(coordinator)
{
ASSERT(!m_name.isNull());
@@ -97,6 +100,8 @@ IDBDatabaseBackendImpl::IDBDatabaseBackendImpl(const String& name, const String&
if (!result || m_description != foundDescription)
setMetaData(m_sqliteDatabase.get(), m_name, m_description, m_version);
+
+ loadObjectStores();
}
IDBDatabaseBackendImpl::~IDBDatabaseBackendImpl()
@@ -127,9 +132,20 @@ void IDBDatabaseBackendImpl::createObjectStore(const String& name, const String&
return;
}
- RefPtr<IDBObjectStoreBackendInterface> objectStore = IDBObjectStoreBackendImpl::create(name, keyPath, autoIncrement);
+ SQLiteStatement insert(sqliteDatabase(), "INSERT INTO ObjectStores (name, keyPath, doAutoIncrement) VALUES (?, ?, ?)");
+ bool ok = insert.prepare() == SQLResultOk;
+ ASSERT_UNUSED(ok, ok); // FIXME: Better error handling.
+ insert.bindText(1, name);
+ insert.bindText(2, keyPath);
+ insert.bindInt(3, static_cast<int>(autoIncrement));
+ ok = insert.step() == SQLResultDone;
+ ASSERT_UNUSED(ok, ok); // FIXME: Better error handling.
+ int64_t id = sqliteDatabase().lastInsertRowID();
+
+ RefPtr<IDBObjectStoreBackendImpl> objectStore = IDBObjectStoreBackendImpl::create(this, id, name, keyPath, autoIncrement);
+ ASSERT(objectStore->name() == name);
m_objectStores.set(name, objectStore);
- callbacks->onSuccess(objectStore.release());
+ callbacks->onSuccess(objectStore.get());
}
PassRefPtr<IDBObjectStoreBackendInterface> IDBDatabaseBackendImpl::objectStore(const String& name, unsigned short mode)
@@ -139,22 +155,55 @@ PassRefPtr<IDBObjectStoreBackendInterface> IDBDatabaseBackendImpl::objectStore(c
return m_objectStores.get(name);
}
+static void doDelete(SQLiteDatabase& db, const char* sql, int64_t id)
+{
+ SQLiteStatement deleteQuery(db, sql);
+ bool ok = deleteQuery.prepare() == SQLResultOk;
+ ASSERT_UNUSED(ok, ok); // FIXME: Better error handling.
+ deleteQuery.bindInt64(1, id);
+ ok = deleteQuery.step() == SQLResultDone;
+ ASSERT_UNUSED(ok, ok); // FIXME: Better error handling.
+}
+
void IDBDatabaseBackendImpl::removeObjectStore(const String& name, PassRefPtr<IDBCallbacks> callbacks)
{
- if (!m_objectStores.contains(name)) {
+ RefPtr<IDBObjectStoreBackendImpl> objectStore = m_objectStores.get(name);
+ if (!objectStore) {
callbacks->onError(IDBDatabaseError::create(IDBDatabaseException::NOT_FOUND_ERR, "No objectStore with that name exists."));
return;
}
+ SQLiteTransaction transaction(sqliteDatabase());
+ transaction.begin();
+ doDelete(sqliteDatabase(), "DELETE FROM ObjectStores WHERE id = ?", objectStore->id());
+ doDelete(sqliteDatabase(), "DELETE FROM ObjectStoreData WHERE objectStoreId = ?", objectStore->id());
+ doDelete(sqliteDatabase(), "DELETE FROM Indexes WHERE objectStoreId = ?", objectStore->id());
+ // FIXME: Delete index data as well.
+ transaction.commit();
+
m_objectStores.remove(name);
callbacks->onSuccess();
}
-PassRefPtr<IDBTransactionBackendInterface> IDBDatabaseBackendImpl::transaction(DOMStringList*, unsigned short, unsigned long)
+PassRefPtr<IDBTransactionBackendInterface> IDBDatabaseBackendImpl::transaction(DOMStringList* objectStores, unsigned short mode, unsigned long timeout)
{
- // FIXME: Ask the transaction manager for a new IDBTransactionBackendImpl.
- ASSERT_NOT_REACHED();
- return 0;
+ return m_transactionCoordinator->createTransaction(objectStores, mode, timeout, this);
+}
+
+void IDBDatabaseBackendImpl::loadObjectStores()
+{
+ SQLiteStatement objectStoresQuery(sqliteDatabase(), "SELECT id, name, keyPath, doAutoIncrement FROM ObjectStores");
+ bool ok = objectStoresQuery.prepare() == SQLResultOk;
+ ASSERT_UNUSED(ok, ok); // FIXME: Better error handling?
+
+ while (objectStoresQuery.step() == SQLResultRow) {
+ int64_t id = objectStoresQuery.getColumnInt64(0);
+ String name = objectStoresQuery.getColumnText(1);
+ String keyPath = objectStoresQuery.getColumnText(2);
+ bool autoIncrement = !!objectStoresQuery.getColumnInt(3);
+
+ m_objectStores.set(name, IDBObjectStoreBackendImpl::create(this, id, name, keyPath, autoIncrement));
+ }
}
} // namespace WebCore
diff --git a/WebCore/storage/IDBDatabaseBackendImpl.h b/WebCore/storage/IDBDatabaseBackendImpl.h
index 60bec1f..3540b21 100644
--- a/WebCore/storage/IDBDatabaseBackendImpl.h
+++ b/WebCore/storage/IDBDatabaseBackendImpl.h
@@ -35,17 +35,20 @@
namespace WebCore {
+class IDBObjectStoreBackendImpl;
+class IDBTransactionCoordinator;
class SQLiteDatabase;
class IDBDatabaseBackendImpl : public IDBDatabaseBackendInterface {
public:
- static PassRefPtr<IDBDatabaseBackendImpl> create(const String& name, const String& description, PassOwnPtr<SQLiteDatabase> database)
+ static PassRefPtr<IDBDatabaseBackendImpl> create(const String& name, const String& description, PassOwnPtr<SQLiteDatabase> database, IDBTransactionCoordinator* coordinator)
{
- return adoptRef(new IDBDatabaseBackendImpl(name, description, database));
+ return adoptRef(new IDBDatabaseBackendImpl(name, description, database, coordinator));
}
virtual ~IDBDatabaseBackendImpl();
void setDescription(const String& description);
+ SQLiteDatabase& sqliteDatabase() const { return *m_sqliteDatabase.get(); }
// Implements IDBDatabase
virtual String name() const { return m_name; }
@@ -58,16 +61,19 @@ public:
virtual void removeObjectStore(const String& name, PassRefPtr<IDBCallbacks>);
virtual PassRefPtr<IDBTransactionBackendInterface> transaction(DOMStringList* storeNames, unsigned short mode, unsigned long timeout);
private:
- IDBDatabaseBackendImpl(const String& name, const String& description, PassOwnPtr<SQLiteDatabase> database);
+ IDBDatabaseBackendImpl(const String& name, const String& description, PassOwnPtr<SQLiteDatabase> database, IDBTransactionCoordinator*);
- OwnPtr<SQLiteDatabase> m_sqliteDatabase;
+ void loadObjectStores();
+ OwnPtr<SQLiteDatabase> m_sqliteDatabase;
String m_name;
String m_description;
String m_version;
- typedef HashMap<String, RefPtr<IDBObjectStoreBackendInterface> > ObjectStoreMap;
+ typedef HashMap<String, RefPtr<IDBObjectStoreBackendImpl> > ObjectStoreMap;
ObjectStoreMap m_objectStores;
+
+ RefPtr<IDBTransactionCoordinator> m_transactionCoordinator;
};
} // namespace WebCore
diff --git a/WebCore/storage/IDBDatabaseBackendInterface.h b/WebCore/storage/IDBDatabaseBackendInterface.h
index ac12bf1..9e35369 100644
--- a/WebCore/storage/IDBDatabaseBackendInterface.h
+++ b/WebCore/storage/IDBDatabaseBackendInterface.h
@@ -39,6 +39,7 @@ class Frame;
class IDBCallbacks;
class IDBObjectStoreBackendInterface;
class IDBTransactionBackendInterface;
+class IDBTransactionCallbacks;
// This class is shared by IDBDatabase (async) and IDBDatabaseSync (sync).
// This is implemented by IDBDatabaseBackendImpl and optionally others (in order to proxy
diff --git a/WebCore/storage/IDBFactoryBackendImpl.cpp b/WebCore/storage/IDBFactoryBackendImpl.cpp
index 905726f..d656128 100644
--- a/WebCore/storage/IDBFactoryBackendImpl.cpp
+++ b/WebCore/storage/IDBFactoryBackendImpl.cpp
@@ -33,6 +33,7 @@
#include "FileSystem.h"
#include "IDBDatabaseBackendImpl.h"
#include "IDBDatabaseException.h"
+#include "IDBTransactionCoordinator.h"
#include "SQLiteDatabase.h"
#include "SecurityOrigin.h"
#include <wtf/Threading.h>
@@ -42,7 +43,8 @@
namespace WebCore {
-IDBFactoryBackendImpl::IDBFactoryBackendImpl()
+IDBFactoryBackendImpl::IDBFactoryBackendImpl()
+ : m_transactionCoordinator(IDBTransactionCoordinator::create())
{
}
@@ -75,8 +77,25 @@ static PassOwnPtr<SQLiteDatabase> openSQLiteDatabase(SecurityOrigin* securityOri
static bool createTables(SQLiteDatabase* sqliteDatabase)
{
+ // FIXME: Remove all the drop table commands once the on disk structure stabilizes.
static const char* commands[] = {
- "CREATE TABLE IF NOT EXISTS MetaData (name TEXT, description TEXT, version TEXT)"
+ "DROP TABLE IF EXISTS MetaData",
+ "CREATE TABLE IF NOT EXISTS MetaData (id INTEGER PRIMARY KEY, name TEXT NOT NULL, description TEXT NOT NULL, version TEXT NOT NULL)",
+
+ "DROP TABLE IF EXISTS ObjectStores",
+ "CREATE TABLE IF NOT EXISTS ObjectStores (id INTEGER PRIMARY KEY, name TEXT NOT NULL, keyPath TEXT, doAutoIncrement INTEGER NOT NULL)",
+ "DROP INDEX IF EXISTS ObjectStores_name",
+ "CREATE UNIQUE INDEX IF NOT EXISTS ObjectStores_name ON ObjectStores(name)",
+
+ "DROP TABLE IF EXISTS Indexes",
+ "CREATE TABLE IF NOT EXISTS Indexes (id INTEGER PRIMARY KEY, objectStoreId INTEGER NOT NULL REFERENCES ObjectStore(id), name TEXT NOT NULL, keyPath TEXT, isUnique INTEGER NOT NULL)",
+ "DROP INDEX IF EXISTS Indexes_composit",
+ "CREATE UNIQUE INDEX IF NOT EXISTS Indexes_composit ON Indexes(objectStoreId, name)",
+
+ "DROP TABLE IF EXISTS ObjectStoreData",
+ "CREATE TABLE IF NOT EXISTS ObjectStoreData (id INTEGER PRIMARY KEY, objectStoreId INTEGER NOT NULL REFERENCES ObjectStore(id), keyString TEXT, keyDate INTEGER, keyNumber INTEGER, value TEXT NOT NULL)",
+ "DROP INDEX IF EXISTS ObjectStoreData_composit",
+ "CREATE UNIQUE INDEX IF NOT EXISTS ObjectStoreData_composit ON ObjectStoreData(keyString, keyDate, keyNumber, objectStoreId)"
};
for (size_t i = 0; i < arraysize(commands); ++i) {
@@ -107,11 +126,17 @@ void IDBFactoryBackendImpl::open(const String& name, const String& description,
return;
}
- RefPtr<IDBDatabaseBackendImpl> databaseBackend = IDBDatabaseBackendImpl::create(name, description, sqliteDatabase.release());
+ RefPtr<IDBDatabaseBackendImpl> databaseBackend = IDBDatabaseBackendImpl::create(name, description, sqliteDatabase.release(), m_transactionCoordinator.get());
callbacks->onSuccess(databaseBackend.get());
m_databaseBackendMap.set(name, databaseBackend.release());
}
+void IDBFactoryBackendImpl::abortPendingTransactions(const Vector<int>& pendingIDs)
+{
+ for (size_t i = 0; i < pendingIDs.size(); ++i)
+ m_transactionCoordinator->abort(pendingIDs.at(i));
+}
+
} // namespace WebCore
#endif // ENABLE(INDEXED_DATABASE)
diff --git a/WebCore/storage/IDBFactoryBackendImpl.h b/WebCore/storage/IDBFactoryBackendImpl.h
index e87ea39..c9a33da 100644
--- a/WebCore/storage/IDBFactoryBackendImpl.h
+++ b/WebCore/storage/IDBFactoryBackendImpl.h
@@ -37,7 +37,9 @@
namespace WebCore {
class DOMStringList;
+
class IDBDatabaseBackendImpl;
+class IDBTransactionCoordinator;
class IDBFactoryBackendImpl : public IDBFactoryBackendInterface {
public:
@@ -48,12 +50,14 @@ public:
virtual ~IDBFactoryBackendImpl();
virtual void open(const String& name, const String& description, PassRefPtr<IDBCallbacks>, PassRefPtr<SecurityOrigin>, Frame*);
+ virtual void abortPendingTransactions(const Vector<int>& pendingIDs);
private:
IDBFactoryBackendImpl();
typedef HashMap<String, RefPtr<IDBDatabaseBackendImpl> > IDBDatabaseBackendMap;
IDBDatabaseBackendMap m_databaseBackendMap;
+ RefPtr<IDBTransactionCoordinator> m_transactionCoordinator;
// We only create one instance of this class at a time.
static IDBFactoryBackendImpl* idbFactoryBackendImpl;
diff --git a/WebCore/storage/IDBFactoryBackendInterface.h b/WebCore/storage/IDBFactoryBackendInterface.h
index ba18098..c052bc2 100644
--- a/WebCore/storage/IDBFactoryBackendInterface.h
+++ b/WebCore/storage/IDBFactoryBackendInterface.h
@@ -32,6 +32,7 @@
#include "IDBCallbacks.h"
#include "PlatformString.h"
#include <wtf/Threading.h>
+#include <wtf/Vector.h>
#if ENABLE(INDEXED_DATABASE)
@@ -51,6 +52,7 @@ public:
virtual ~IDBFactoryBackendInterface() { }
virtual void open(const String& name, const String& description, PassRefPtr<IDBCallbacks>, PassRefPtr<SecurityOrigin>, Frame*) = 0;
+ virtual void abortPendingTransactions(const Vector<int>& ids) = 0;
};
} // namespace WebCore
diff --git a/WebCore/storage/IDBIndexBackendImpl.cpp b/WebCore/storage/IDBIndexBackendImpl.cpp
index 406e37f..180ff1d 100644
--- a/WebCore/storage/IDBIndexBackendImpl.cpp
+++ b/WebCore/storage/IDBIndexBackendImpl.cpp
@@ -28,10 +28,16 @@
#if ENABLE(INDEXED_DATABASE)
+#include "IDBDatabaseBackendImpl.h"
+#include "IDBObjectStoreBackendImpl.h"
+#include "SQLiteDatabase.h"
+
namespace WebCore {
-IDBIndexBackendImpl::IDBIndexBackendImpl(const String& name, const String& keyPath, bool unique)
- : m_name(name)
+IDBIndexBackendImpl::IDBIndexBackendImpl(IDBObjectStoreBackendImpl* objectStore, int64_t id, const String& name, const String& keyPath, bool unique)
+ : m_objectStore(objectStore)
+ , m_id(id)
+ , m_name(name)
, m_keyPath(keyPath)
, m_unique(unique)
{
@@ -41,6 +47,11 @@ IDBIndexBackendImpl::~IDBIndexBackendImpl()
{
}
+SQLiteDatabase& IDBIndexBackendImpl::sqliteDatabase() const
+{
+ return m_objectStore->database()->sqliteDatabase();
+}
+
} // namespace WebCore
#endif // ENABLE(INDEXED_DATABASE)
diff --git a/WebCore/storage/IDBIndexBackendImpl.h b/WebCore/storage/IDBIndexBackendImpl.h
index ca3f01e..acf6b1f 100644
--- a/WebCore/storage/IDBIndexBackendImpl.h
+++ b/WebCore/storage/IDBIndexBackendImpl.h
@@ -32,11 +32,14 @@
namespace WebCore {
+class IDBObjectStoreBackendImpl;
+class SQLiteDatabase;
+
class IDBIndexBackendImpl : public IDBIndexBackendInterface {
public:
- static PassRefPtr<IDBIndexBackendImpl> create(const String& name, const String& keyPath, bool unique)
+ static PassRefPtr<IDBIndexBackendImpl> create(IDBObjectStoreBackendImpl* objectStore, int64_t id, const String& name, const String& keyPath, bool unique)
{
- return adoptRef(new IDBIndexBackendImpl(name, keyPath, unique));
+ return adoptRef(new IDBIndexBackendImpl(objectStore, id, name, keyPath, unique));
}
virtual ~IDBIndexBackendImpl();
@@ -46,8 +49,13 @@ public:
virtual bool unique() { return m_unique; }
private:
- IDBIndexBackendImpl(const String& name, const String& keyPath, bool unique);
+ IDBIndexBackendImpl(IDBObjectStoreBackendImpl*, int64_t id, const String& name, const String& keyPath, bool unique);
+
+ SQLiteDatabase& sqliteDatabase() const;
+
+ RefPtr<IDBObjectStoreBackendImpl> m_objectStore;
+ int64_t m_id;
String m_name;
String m_keyPath;
bool m_unique;
diff --git a/WebCore/storage/IDBKeyPathBackendImpl.cpp b/WebCore/storage/IDBKeyPathBackendImpl.cpp
new file mode 100644
index 0000000..6cc9be5
--- /dev/null
+++ b/WebCore/storage/IDBKeyPathBackendImpl.cpp
@@ -0,0 +1,36 @@
+/*
+ * Copyright (C) 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:
+ *
+ * 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 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 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 "IDBKeyPathBackendImpl.h"
+
+#if PLATFORM(CHROMIUM)
+#error "Chromium should not compile this file and instead define its own version of this factory that navigates the multi-process boundry."
+#endif
+
+void IDBKeyPathBackendImpl::createIDBKeysFromSerializedValuesAndKeyPath(const Vector<RefPtr<SerializedScriptValue>&, 0> values, const String& keyPath, Vector<RefPtr<IDBKey>, 0>& keys)
+{
+ // FIXME: Implement this method once JSC supports WireFormat for SerializedScriptValue.
+}
diff --git a/WebCore/storage/IDBKeyPathBackendImpl.h b/WebCore/storage/IDBKeyPathBackendImpl.h
new file mode 100644
index 0000000..32af5e3
--- /dev/null
+++ b/WebCore/storage/IDBKeyPathBackendImpl.h
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 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:
+ *
+ * 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 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 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 IDBKeyPathBackendImpl_h
+#define IDBKeyPathBackendImpl_h
+
+#if ENABLE(INDEXED_DATABASE)
+
+#include <wtf/Forward.h>
+
+namespace WebCore {
+
+class IDBKey;
+class SerializedScriptValue;
+
+class IDBKeyPathBackendImpl {
+public:
+ static void createIDBKeysFromSerializedValuesAndKeyPath(const Vector<RefPtr<SerializedScriptValue>, 0>& values, const String& keyPath, Vector<RefPtr<IDBKey>, 0>& keys);
+};
+
+}
+
+#endif // ENABLE(INDEXED_DATABASE)
+
+#endif // IDBKeyPathBackendImpl_h
diff --git a/WebCore/storage/IDBObjectStoreBackendImpl.cpp b/WebCore/storage/IDBObjectStoreBackendImpl.cpp
index 9732bc1..1b9b76b 100755
--- a/WebCore/storage/IDBObjectStoreBackendImpl.cpp
+++ b/WebCore/storage/IDBObjectStoreBackendImpl.cpp
@@ -30,10 +30,14 @@
#include "IDBBindingUtilities.h"
#include "IDBCallbacks.h"
#include "IDBCursorBackendImpl.h"
+#include "IDBDatabaseBackendImpl.h"
#include "IDBDatabaseException.h"
#include "IDBIndexBackendImpl.h"
+#include "IDBKeyPath.h"
+#include "IDBKeyPathBackendImpl.h"
#include "IDBKeyRange.h"
-#include "IDBKeyTree.h"
+#include "SQLiteDatabase.h"
+#include "SQLiteStatement.h"
#if ENABLE(INDEXED_DATABASE)
@@ -43,12 +47,14 @@ IDBObjectStoreBackendImpl::~IDBObjectStoreBackendImpl()
{
}
-IDBObjectStoreBackendImpl::IDBObjectStoreBackendImpl(const String& name, const String& keyPath, bool autoIncrement)
- : m_name(name)
+IDBObjectStoreBackendImpl::IDBObjectStoreBackendImpl(IDBDatabaseBackendImpl* database, int64_t id, const String& name, const String& keyPath, bool autoIncrement)
+ : m_database(database)
+ , m_id(id)
+ , m_name(name)
, m_keyPath(keyPath)
, m_autoIncrement(autoIncrement)
- , m_tree(Tree::create())
{
+ loadIndexes();
}
PassRefPtr<DOMStringList> IDBObjectStoreBackendImpl::indexNames() const
@@ -59,28 +65,86 @@ PassRefPtr<DOMStringList> IDBObjectStoreBackendImpl::indexNames() const
return indexNames.release();
}
+static String whereClause(IDBKey::Type type)
+{
+ switch (type) {
+ case IDBKey::StringType:
+ return "WHERE objectStoreId = ? AND keyString = ?";
+ case IDBKey::NumberType:
+ return "WHERE objectStoreId = ? AND keyNumber = ?";
+ // FIXME: Implement date.
+ case IDBKey::NullType:
+ return "WHERE objectStoreId = ? AND keyString IS NULL AND keyDate IS NULL AND keyNumber IS NULL";
+ }
+
+ ASSERT_NOT_REACHED();
+ return "";
+}
+
+// Returns number of items bound.
+static int bindKey(SQLiteStatement& query, int column, IDBKey* key)
+{
+ switch (key->type()) {
+ case IDBKey::StringType:
+ query.bindText(column, key->string());
+ return 1;
+ case IDBKey::NumberType:
+ query.bindInt(column, key->number());
+ return 1;
+ // FIXME: Implement date.
+ case IDBKey::NullType:
+ return 0;
+ }
+
+ ASSERT_NOT_REACHED();
+ return 0;
+}
+
+static void bindWhereClause(SQLiteStatement& query, int64_t id, IDBKey* key)
+{
+ query.bindInt64(1, id);
+ bindKey(query, 2, key);
+}
+
void IDBObjectStoreBackendImpl::get(PassRefPtr<IDBKey> key, PassRefPtr<IDBCallbacks> callbacks)
{
- RefPtr<SerializedScriptValue> value = m_tree->get(key.get());
- if (!value) {
+ SQLiteStatement query(sqliteDatabase(), "SELECT keyString, keyDate, keyNumber, value FROM ObjectStoreData " + whereClause(key->type()));
+ bool ok = query.prepare() == SQLResultOk;
+ ASSERT_UNUSED(ok, ok); // FIXME: Better error handling?
+
+ bindWhereClause(query, m_id, key.get());
+ if (query.step() != SQLResultRow) {
callbacks->onError(IDBDatabaseError::create(IDBDatabaseException::NOT_FOUND_ERR, "Key does not exist in the object store."));
return;
}
- callbacks->onSuccess(value.get());
+
+ ASSERT((key->type() == IDBKey::StringType) != query.isColumnNull(0));
+ // FIXME: Implement date.
+ ASSERT((key->type() == IDBKey::NumberType) != query.isColumnNull(2));
+
+ callbacks->onSuccess(SerializedScriptValue::createFromWire(query.getColumnText(3)));
+ ASSERT(query.step() != SQLResultRow);
}
-void IDBObjectStoreBackendImpl::put(PassRefPtr<SerializedScriptValue> value, PassRefPtr<IDBKey> prpKey, bool addOnly, PassRefPtr<IDBCallbacks> callbacks)
+void IDBObjectStoreBackendImpl::put(PassRefPtr<SerializedScriptValue> prpValue, PassRefPtr<IDBKey> prpKey, bool addOnly, PassRefPtr<IDBCallbacks> callbacks)
{
+ RefPtr<SerializedScriptValue> value = prpValue;
RefPtr<IDBKey> key = prpKey;
if (!m_keyPath.isNull()) {
if (key) {
- callbacks->onError(IDBDatabaseError::create(IDBDatabaseException::UNKNOWN_ERR, "A key was supplied for an objectStore that has a keyPath."));
+ callbacks->onError(IDBDatabaseError::create(IDBDatabaseException::UNKNOWN_ERR, "A key was supplied for an objectStore that has a keyPath."));
return;
}
- ASSERT_NOT_REACHED();
- callbacks->onError(IDBDatabaseError::create(IDBDatabaseException::UNKNOWN_ERR, "FIXME: keyPath not yet supported."));
- return;
+ Vector<RefPtr<SerializedScriptValue> > values;
+ values.append(value);
+ Vector<RefPtr<IDBKey> > idbKeys;
+ IDBKeyPathBackendImpl::createIDBKeysFromSerializedValuesAndKeyPath(values, m_keyPath, idbKeys);
+ if (idbKeys.isEmpty()) {
+ callbacks->onError(IDBDatabaseError::create(IDBDatabaseException::UNKNOWN_ERR, "An invalid keyPath was supplied for an objectStore."));
+ return;
+ }
+ key = idbKeys[0];
}
if (!key) {
@@ -88,18 +152,66 @@ void IDBObjectStoreBackendImpl::put(PassRefPtr<SerializedScriptValue> value, Pas
return;
}
- if (addOnly && m_tree->get(key.get())) {
+ SQLiteStatement getQuery(sqliteDatabase(), "SELECT id FROM ObjectStoreData " + whereClause(key->type()));
+ bool ok = getQuery.prepare() == SQLResultOk;
+ ASSERT_UNUSED(ok, ok); // FIXME: Better error handling?
+
+ bindWhereClause(getQuery, m_id, key.get());
+ bool existingValue = getQuery.step() == SQLResultRow;
+ if (addOnly && existingValue) {
callbacks->onError(IDBDatabaseError::create(IDBDatabaseException::CONSTRAINT_ERR, "Key already exists in the object store."));
return;
}
- m_tree->put(key.get(), value.get());
+ String sql = existingValue ? "UPDATE ObjectStoreData SET keyString = ?, keyDate = ?, keyNumber = ?, value = ? WHERE id = ?"
+ : "INSERT INTO ObjectStoreData (keyString, keyDate, keyNumber, value, objectStoreId) VALUES (?, ?, ?, ?, ?)";
+ SQLiteStatement putQuery(sqliteDatabase(), sql);
+ ok = putQuery.prepare() == SQLResultOk;
+ ASSERT_UNUSED(ok, ok); // FIXME: Better error handling?
+ switch (key->type()) {
+ case IDBKey::StringType:
+ putQuery.bindText(1, key->string());
+ putQuery.bindNull(2);
+ putQuery.bindNull(3);
+ break;
+ // FIXME: Implement date.
+ case IDBKey::NumberType:
+ putQuery.bindNull(1);
+ putQuery.bindNull(2);
+ putQuery.bindInt(3, key->number());
+ break;
+ case IDBKey::NullType:
+ putQuery.bindNull(1);
+ putQuery.bindNull(2);
+ putQuery.bindNull(3);
+ break;
+ default:
+ ASSERT_NOT_REACHED();
+ }
+ putQuery.bindText(4, value->toWireString());
+ if (existingValue)
+ putQuery.bindInt(5, getQuery.getColumnInt(0));
+ else
+ putQuery.bindInt64(5, m_id);
+
+ ok = putQuery.step() == SQLResultDone;
+ ASSERT_UNUSED(ok, ok); // FIXME: Better error handling?
+
callbacks->onSuccess(key.get());
}
void IDBObjectStoreBackendImpl::remove(PassRefPtr<IDBKey> key, PassRefPtr<IDBCallbacks> callbacks)
{
- m_tree->remove(key.get());
+ SQLiteStatement query(sqliteDatabase(), "DELETE FROM ObjectStoreData " + whereClause(key->type()));
+ bool ok = query.prepare() == SQLResultOk;
+ ASSERT_UNUSED(ok, ok); // FIXME: Better error handling?
+
+ bindWhereClause(query, m_id, key.get());
+ if (query.step() != SQLResultDone) {
+ callbacks->onError(IDBDatabaseError::create(IDBDatabaseException::NOT_FOUND_ERR, "Key does not exist in the object store."));
+ return;
+ }
+
callbacks->onSuccess();
}
@@ -110,7 +222,18 @@ void IDBObjectStoreBackendImpl::createIndex(const String& name, const String& ke
return;
}
- RefPtr<IDBIndexBackendInterface> index = IDBIndexBackendImpl::create(name, keyPath, unique);
+ SQLiteStatement insert(sqliteDatabase(), "INSERT INTO Indexes (objectStoreId, name, keyPath, isUnique) VALUES (?, ?, ?, ?)");
+ bool ok = insert.prepare() == SQLResultOk;
+ ASSERT_UNUSED(ok, ok); // FIXME: Better error handling.
+ insert.bindInt64(1, m_id);
+ insert.bindText(2, name);
+ insert.bindText(3, keyPath);
+ insert.bindInt(4, static_cast<int>(unique));
+ ok = insert.step() == SQLResultDone;
+ ASSERT_UNUSED(ok, ok); // FIXME: Better error handling.
+ int64_t id = sqliteDatabase().lastInsertRowID();
+
+ RefPtr<IDBIndexBackendInterface> index = IDBIndexBackendImpl::create(this, id, name, keyPath, unique);
ASSERT(index->name() == name);
m_indexes.set(name, index);
callbacks->onSuccess(index.release());
@@ -128,19 +251,61 @@ void IDBObjectStoreBackendImpl::removeIndex(const String& name, PassRefPtr<IDBCa
return;
}
+ SQLiteStatement deleteQuery(sqliteDatabase(), "DELETE FROM Indexes WHERE name = ? AND objectStoreId = ?");
+ bool ok = deleteQuery.prepare() == SQLResultOk;
+ ASSERT_UNUSED(ok, ok); // FIXME: Better error handling.
+ deleteQuery.bindText(1, name);
+ deleteQuery.bindInt64(2, m_id);
+ ok = deleteQuery.step() == SQLResultDone;
+ ASSERT_UNUSED(ok, ok); // FIXME: Better error handling.
+
+ // FIXME: Delete index data as well.
+
m_indexes.remove(name);
callbacks->onSuccess();
}
void IDBObjectStoreBackendImpl::openCursor(PassRefPtr<IDBKeyRange> range, unsigned short direction, PassRefPtr<IDBCallbacks> callbacks)
{
+ // FIXME: Fully implement.
+
RefPtr<IDBKey> key = range->left();
- RefPtr<SerializedScriptValue> value = m_tree->get(key.get());
- if (value) {
- RefPtr<IDBCursorBackendInterface> cursor = IDBCursorBackendImpl::create(this, range, static_cast<IDBCursor::Direction>(direction), key, value);
- callbacks->onSuccess(cursor.release());
- } else
- callbacks->onSuccess();
+ SQLiteStatement query(sqliteDatabase(), "SELECT id, value FROM ObjectStoreData " + whereClause(key->type()));
+ bool ok = query.prepare() == SQLResultOk;
+ ASSERT_UNUSED(ok, ok); // FIXME: Better error handling?
+
+ bindWhereClause(query, m_id, key.get());
+ if (query.step() != SQLResultRow) {
+ callbacks->onSuccess();
+ return;
+ }
+
+ RefPtr<SerializedScriptValue> value = SerializedScriptValue::createFromWire(query.getColumnText(1));
+ RefPtr<IDBCursorBackendInterface> cursor = IDBCursorBackendImpl::create(this, range, static_cast<IDBCursor::Direction>(direction), key.release(), value.release());
+ callbacks->onSuccess(cursor.release());
+}
+
+void IDBObjectStoreBackendImpl::loadIndexes()
+{
+ SQLiteStatement indexQuery(sqliteDatabase(), "SELECT id, name, keyPath, isUnique FROM Indexes WHERE objectStoreId = ?");
+ bool ok = indexQuery.prepare() == SQLResultOk;
+ ASSERT_UNUSED(ok, ok); // FIXME: Better error handling?
+
+ indexQuery.bindInt64(1, m_id);
+
+ while (indexQuery.step() == SQLResultRow) {
+ int64_t id = indexQuery.getColumnInt64(0);
+ String name = indexQuery.getColumnText(1);
+ String keyPath = indexQuery.getColumnText(2);
+ bool unique = !!indexQuery.getColumnInt(3);
+
+ m_indexes.set(name, IDBIndexBackendImpl::create(this, id, name, keyPath, unique));
+ }
+}
+
+SQLiteDatabase& IDBObjectStoreBackendImpl::sqliteDatabase() const
+{
+ return m_database->sqliteDatabase();
}
} // namespace WebCore
diff --git a/WebCore/storage/IDBObjectStoreBackendImpl.h b/WebCore/storage/IDBObjectStoreBackendImpl.h
index 4b909af..e1058c8 100644
--- a/WebCore/storage/IDBObjectStoreBackendImpl.h
+++ b/WebCore/storage/IDBObjectStoreBackendImpl.h
@@ -34,16 +34,18 @@
namespace WebCore {
-template <typename ValueType> class IDBKeyTree;
+class IDBDatabaseBackendImpl;
+class SQLiteDatabase;
class IDBObjectStoreBackendImpl : public IDBObjectStoreBackendInterface {
public:
- static PassRefPtr<IDBObjectStoreBackendInterface> create(const String& name, const String& keyPath, bool autoIncrement)
+ static PassRefPtr<IDBObjectStoreBackendImpl> create(IDBDatabaseBackendImpl* database, int64_t id, const String& name, const String& keyPath, bool autoIncrement)
{
- return adoptRef(new IDBObjectStoreBackendImpl(name, keyPath, autoIncrement));
+ return adoptRef(new IDBObjectStoreBackendImpl(database, id, name, keyPath, autoIncrement));
}
~IDBObjectStoreBackendImpl();
+ int64_t id() const { return m_id; }
String name() const { return m_name; }
String keyPath() const { return m_keyPath; }
PassRefPtr<DOMStringList> indexNames() const;
@@ -58,18 +60,23 @@ public:
void openCursor(PassRefPtr<IDBKeyRange> range, unsigned short direction, PassRefPtr<IDBCallbacks>);
+ IDBDatabaseBackendImpl* database() const { return m_database.get(); }
+
private:
- IDBObjectStoreBackendImpl(const String& name, const String& keyPath, bool autoIncrement);
+ IDBObjectStoreBackendImpl(IDBDatabaseBackendImpl*, int64_t id, const String& name, const String& keyPath, bool autoIncrement);
+
+ void loadIndexes();
+ SQLiteDatabase& sqliteDatabase() const;
+ RefPtr<IDBDatabaseBackendImpl> m_database;
+
+ int64_t m_id;
String m_name;
String m_keyPath;
bool m_autoIncrement;
typedef HashMap<String, RefPtr<IDBIndexBackendInterface> > IndexMap;
IndexMap m_indexes;
-
- typedef IDBKeyTree<SerializedScriptValue> Tree;
- RefPtr<Tree> m_tree;
};
} // namespace WebCore
diff --git a/WebCore/storage/IDBPendingTransactionMonitor.cpp b/WebCore/storage/IDBPendingTransactionMonitor.cpp
new file mode 100644
index 0000000..d026099
--- /dev/null
+++ b/WebCore/storage/IDBPendingTransactionMonitor.cpp
@@ -0,0 +1,72 @@
+/*
+ * Copyright (C) 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:
+ *
+ * 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 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 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 "IDBPendingTransactionMonitor.h"
+
+#if ENABLE(INDEXED_DATABASE)
+
+namespace WebCore {
+
+Vector<int>* IDBPendingTransactionMonitor::m_ids = 0;
+
+bool IDBPendingTransactionMonitor::hasPendingTransactions()
+{
+ return m_ids && m_ids->size();
+}
+
+void IDBPendingTransactionMonitor::addPendingTransaction(int id)
+{
+ if (!m_ids)
+ m_ids = new Vector<int>();
+ m_ids->append(id);
+}
+
+void IDBPendingTransactionMonitor::removePendingTransaction(int id)
+{
+ m_ids->remove(id);
+ if (!m_ids->size()) {
+ delete m_ids;
+ m_ids = 0;
+ }
+}
+
+void IDBPendingTransactionMonitor::clearPendingTransactions()
+{
+ if (!m_ids)
+ return;
+
+ m_ids->clear();
+ delete m_ids;
+ m_ids = 0;
+}
+
+const Vector<int>& IDBPendingTransactionMonitor::pendingTransactions()
+{
+ return *m_ids;
+}
+
+};
+#endif // ENABLE(INDEXED_DATABASE)
diff --git a/WebCore/storage/IDBPendingTransactionMonitor.h b/WebCore/storage/IDBPendingTransactionMonitor.h
new file mode 100644
index 0000000..00e833a
--- /dev/null
+++ b/WebCore/storage/IDBPendingTransactionMonitor.h
@@ -0,0 +1,63 @@
+/*
+ * Copyright (C) 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:
+ *
+ * 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 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 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 IDBPendingTransactionMonitor_h
+#define IDBPendingTransactionMonitor_h
+
+#if ENABLE(INDEXED_DATABASE)
+
+#include <wtf/Noncopyable.h>
+#include <wtf/Vector.h>
+
+namespace WebCore {
+
+// This class keeps track of the transactions created during the current
+// Javascript execution context. A transaction is 'pending' if no asynchronous
+// operation is currently queued for it (e.g. an IDBObjectStore::put() or similar).
+// All pending transactions are aborted as soon as execution returns from
+// the script engine.
+//
+// FIXME: move the vector of transaction IDs to TLS. Keeping it static
+// will not work once we add support for workers. Another possible
+// solution is to keep the vector in the ScriptExecutionContext.
+class IDBPendingTransactionMonitor : public Noncopyable {
+public:
+ static bool hasPendingTransactions();
+ static void addPendingTransaction(int id);
+ static void removePendingTransaction(int id);
+ static void clearPendingTransactions();
+ static const Vector<int>& pendingTransactions();
+
+private:
+ IDBPendingTransactionMonitor();
+
+ static Vector<int>* m_ids;
+};
+
+} // namespace WebCore
+
+#endif // ENABLE(INDEXED_DATABASE)
+
+#endif // IDBPendingTransactionMonitor_h
diff --git a/WebCore/storage/IDBTransaction.cpp b/WebCore/storage/IDBTransaction.cpp
index 1bc059a..4e93378 100644
--- a/WebCore/storage/IDBTransaction.cpp
+++ b/WebCore/storage/IDBTransaction.cpp
@@ -1,3 +1,28 @@
+/*
+ * Copyright (C) 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:
+ *
+ * 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 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 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 "IDBTransaction.h"
@@ -5,9 +30,11 @@
#include "Event.h"
#include "EventException.h"
+#include "IDBAbortEvent.h"
#include "IDBDatabase.h"
#include "IDBObjectStore.h"
#include "IDBObjectStoreBackendInterface.h"
+#include "IDBPendingTransactionMonitor.h"
#include "ScriptExecutionContext.h"
namespace WebCore {
@@ -16,7 +43,10 @@ IDBTransaction::IDBTransaction(ScriptExecutionContext* context, PassRefPtr<IDBTr
: ActiveDOMObject(context, this)
, m_backend(backend)
, m_database(db)
+ , m_stopped(false)
+ , m_timer(this, &IDBTransaction::timerFired)
{
+ IDBPendingTransactionMonitor::addPendingTransaction(m_backend->id());
}
IDBTransaction::~IDBTransaction()
@@ -50,6 +80,22 @@ ScriptExecutionContext* IDBTransaction::scriptExecutionContext() const
return ActiveDOMObject::scriptExecutionContext();
}
+void IDBTransaction::onAbort()
+{
+ if (!m_stopped) {
+ m_selfRef = this;
+ m_stopped = true;
+ m_timer.startOneShot(0);
+ }
+ // Release the backend as it holds a (circular) reference back to us.
+ m_backend.clear();
+}
+
+int IDBTransaction::id() const
+{
+ return m_backend->id();
+}
+
bool IDBTransaction::canSuspend() const
{
// We may be in the middle of a transaction so we cannot suspend our object.
@@ -57,6 +103,15 @@ bool IDBTransaction::canSuspend() const
return false;
}
+void IDBTransaction::stop()
+{
+ if (!m_stopped) {
+ // The document is getting detached. Abort!
+ m_stopped = true;
+ m_backend->abort();
+ }
+}
+
EventTargetData* IDBTransaction::eventTargetData()
{
return &m_eventTargetData;
@@ -67,6 +122,14 @@ EventTargetData* IDBTransaction::ensureEventTargetData()
return &m_eventTargetData;
}
+void IDBTransaction::timerFired(Timer<IDBTransaction>* transaction)
+{
+ ASSERT(m_selfRef);
+
+ RefPtr<IDBTransaction> selfRef = m_selfRef.release();
+ dispatchEvent(IDBAbortEvent::create());
+}
+
}
#endif // ENABLE(INDEXED_DATABASE)
diff --git a/WebCore/storage/IDBTransaction.h b/WebCore/storage/IDBTransaction.h
index 2e3167c..3c7f9dd 100644
--- a/WebCore/storage/IDBTransaction.h
+++ b/WebCore/storage/IDBTransaction.h
@@ -34,13 +34,16 @@
#include "EventNames.h"
#include "EventTarget.h"
#include "IDBTransactionBackendInterface.h"
+#include "IDBTransactionCallbacks.h"
+#include "Timer.h"
+#include <wtf/RefCounted.h>
namespace WebCore {
class IDBDatabase;
class IDBObjectStore;
-class IDBTransaction : public EventTarget, public ActiveDOMObject {
+class IDBTransaction : public IDBTransactionCallbacks, public EventTarget, public ActiveDOMObject {
public:
static PassRefPtr<IDBTransaction> create(ScriptExecutionContext* context, PassRefPtr<IDBTransactionBackendInterface> backend, IDBDatabase* db)
{
@@ -63,12 +66,20 @@ public:
DEFINE_ATTRIBUTE_EVENT_LISTENER(complete);
DEFINE_ATTRIBUTE_EVENT_LISTENER(timeout);
+ // IDBTransactionCallbacks
+ virtual void onAbort();
+ virtual int id() const;
+
// EventTarget
virtual IDBTransaction* toIDBTransaction() { return this; }
// ActiveDOMObject
virtual ScriptExecutionContext* scriptExecutionContext() const;
virtual bool canSuspend() const;
+ virtual void stop();
+
+ using RefCounted<IDBTransactionCallbacks>::ref;
+ using RefCounted<IDBTransactionCallbacks>::deref;
private:
IDBTransaction(ScriptExecutionContext*, PassRefPtr<IDBTransactionBackendInterface>, IDBDatabase*);
@@ -79,9 +90,15 @@ private:
virtual EventTargetData* eventTargetData();
virtual EventTargetData* ensureEventTargetData();
+ void timerFired(Timer<IDBTransaction>*);
+
EventTargetData m_eventTargetData;
RefPtr<IDBTransactionBackendInterface> m_backend;
RefPtr<IDBDatabase> m_database;
+
+ bool m_stopped;
+ Timer<IDBTransaction> m_timer;
+ RefPtr<IDBTransaction> m_selfRef; // This is set to us iff there's an event pending.
};
} // namespace WebCore
diff --git a/WebCore/storage/IDBTransactionBackendImpl.cpp b/WebCore/storage/IDBTransactionBackendImpl.cpp
new file mode 100755
index 0000000..51b33b2
--- /dev/null
+++ b/WebCore/storage/IDBTransactionBackendImpl.cpp
@@ -0,0 +1,70 @@
+/*
+ * Copyright (C) 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:
+ *
+ * 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 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 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 "IDBTransactionBackendImpl.h"
+
+#if ENABLE(INDEXED_DATABASE)
+
+#include "IDBDatabaseBackendImpl.h"
+#include "SQLiteDatabase.h"
+
+namespace WebCore {
+
+PassRefPtr<IDBTransactionBackendInterface> IDBTransactionBackendImpl::create(DOMStringList* objectStores, unsigned short mode, unsigned long timeout, int id, IDBDatabaseBackendImpl* database)
+{
+ return adoptRef(new IDBTransactionBackendImpl(objectStores, mode, timeout, id, database));
+}
+
+IDBTransactionBackendImpl::IDBTransactionBackendImpl(DOMStringList* objectStores, unsigned short mode, unsigned long timeout, int id, IDBDatabaseBackendImpl* database)
+ : m_objectStoreNames(objectStores)
+ , m_mode(mode)
+ , m_timeout(timeout)
+ , m_id(id)
+ , m_aborted(false)
+ , m_database(database)
+{
+}
+
+PassRefPtr<IDBObjectStoreBackendInterface> IDBTransactionBackendImpl::objectStore(const String& name)
+{
+ return m_database->objectStore(name, 0); // FIXME: remove mode param.
+}
+
+void IDBTransactionBackendImpl::scheduleTask(PassOwnPtr<ScriptExecutionContext::Task>)
+{
+ // FIXME: implement.
+ ASSERT_NOT_REACHED();
+}
+
+void IDBTransactionBackendImpl::abort()
+{
+ m_aborted = true;
+ m_callbacks->onAbort();
+}
+
+};
+
+#endif // ENABLE(INDEXED_DATABASE)
diff --git a/WebCore/storage/IDBTransactionBackendImpl.h b/WebCore/storage/IDBTransactionBackendImpl.h
new file mode 100755
index 0000000..fb57401
--- /dev/null
+++ b/WebCore/storage/IDBTransactionBackendImpl.h
@@ -0,0 +1,68 @@
+/*
+ * Copyright (C) 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:
+ *
+ * 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 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 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 IDBTransactionBackendImpl_h
+#define IDBTransactionBackendImpl_h
+
+#if ENABLE(INDEXED_DATABASE)
+
+#include "DOMStringList.h"
+#include "IDBTransactionBackendInterface.h"
+#include "IDBTransactionCallbacks.h"
+#include <wtf/RefPtr.h>
+
+namespace WebCore {
+
+class IDBDatabaseBackendImpl;
+
+class IDBTransactionBackendImpl : public IDBTransactionBackendInterface {
+public:
+ static PassRefPtr<IDBTransactionBackendInterface> create(DOMStringList* objectStores, unsigned short mode, unsigned long timeout, int id, IDBDatabaseBackendImpl*);
+ virtual ~IDBTransactionBackendImpl() { }
+
+ virtual PassRefPtr<IDBObjectStoreBackendInterface> objectStore(const String& name);
+ virtual unsigned short mode() const { return m_mode; }
+ virtual void scheduleTask(PassOwnPtr<ScriptExecutionContext::Task>);
+ virtual void abort();
+ virtual int id() const { return m_id; }
+ virtual void setCallbacks(IDBTransactionCallbacks* callbacks) { m_callbacks = callbacks; }
+
+private:
+ IDBTransactionBackendImpl(DOMStringList* objectStores, unsigned short mode, unsigned long timeout, int id, IDBDatabaseBackendImpl*);
+
+ RefPtr<DOMStringList> m_objectStoreNames;
+ unsigned short m_mode;
+ unsigned long m_timeout;
+ int m_id;
+ bool m_aborted;
+ RefPtr<IDBTransactionCallbacks> m_callbacks;
+ RefPtr<IDBDatabaseBackendImpl> m_database;
+};
+
+} // namespace WebCore
+
+#endif // ENABLE(INDEXED_DATABASE)
+
+#endif // IDBTransactionBackendImpl_h
diff --git a/WebCore/storage/IDBTransactionBackendInterface.h b/WebCore/storage/IDBTransactionBackendInterface.h
index dff2bd7..39651f1 100644
--- a/WebCore/storage/IDBTransactionBackendInterface.h
+++ b/WebCore/storage/IDBTransactionBackendInterface.h
@@ -37,6 +37,7 @@
namespace WebCore {
class IDBObjectStoreBackendInterface;
+class IDBTransactionCallbacks;
class SQLiteDatabase;
// This class is shared by IDBTransaction (async) and IDBTransactionSync (sync).
@@ -51,7 +52,8 @@ public:
virtual unsigned short mode() const = 0;
virtual void scheduleTask(PassOwnPtr<ScriptExecutionContext::Task>) = 0;
virtual void abort() = 0;
- virtual SQLiteDatabase* sqliteDatabase() = 0;
+ virtual int id() const = 0;
+ virtual void setCallbacks(IDBTransactionCallbacks*) = 0;
};
} // namespace WebCore
diff --git a/WebCore/storage/IDBTransactionCallbacks.h b/WebCore/storage/IDBTransactionCallbacks.h
new file mode 100644
index 0000000..38181fc
--- /dev/null
+++ b/WebCore/storage/IDBTransactionCallbacks.h
@@ -0,0 +1,52 @@
+/*
+ * Copyright (C) 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:
+ *
+ * 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.
+ * 3. Neither the name of Apple Computer, Inc. ("Apple") 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 APPLE 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 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 IDBTransactionCallbacks_h
+#define IDBTransactionCallbacks_h
+
+#if ENABLE(INDEXED_DATABASE)
+
+#include "SerializedScriptValue.h"
+#include <wtf/RefCounted.h>
+
+namespace WebCore {
+
+class IDBTransactionCallbacks : public RefCounted<IDBTransactionCallbacks> {
+public:
+ virtual ~IDBTransactionCallbacks() { }
+
+ virtual void onAbort() = 0;
+ virtual int id() const = 0;
+ // FIXME: add the rest
+};
+
+} // namespace WebCore
+
+#endif
+
+#endif // IDBTransactionCallbacks_h
diff --git a/WebCore/storage/IDBTransactionCoordinator.cpp b/WebCore/storage/IDBTransactionCoordinator.cpp
new file mode 100644
index 0000000..9790c1f
--- /dev/null
+++ b/WebCore/storage/IDBTransactionCoordinator.cpp
@@ -0,0 +1,69 @@
+/*
+ * Copyright (C) 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:
+ *
+ * 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 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 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 "IDBTransactionCoordinator.h"
+
+#if ENABLE(INDEXED_DATABASE)
+
+#include "IDBDatabaseBackendImpl.h"
+#include "IDBObjectStoreBackendInterface.h"
+#include "IDBTransactionBackendImpl.h"
+#include "SQLiteDatabase.h"
+#include "ScriptExecutionContext.h"
+
+namespace WebCore {
+
+IDBTransactionCoordinator::IDBTransactionCoordinator()
+ : m_nextID(0)
+{
+}
+
+IDBTransactionCoordinator::~IDBTransactionCoordinator()
+{
+}
+
+PassRefPtr<IDBTransactionBackendInterface> IDBTransactionCoordinator::createTransaction(DOMStringList* objectStores, unsigned short mode, unsigned long timeout, IDBDatabaseBackendImpl* database)
+{
+ RefPtr<IDBTransactionBackendInterface> transaction = IDBTransactionBackendImpl::create(objectStores, mode, timeout, ++m_nextID, database);
+ m_transactionQueue.add(transaction.get());
+ m_idMap.add(m_nextID, transaction);
+ return transaction.release();
+}
+
+void IDBTransactionCoordinator::abort(int id)
+{
+ ASSERT(m_idMap.contains(id));
+ RefPtr<IDBTransactionBackendInterface> transaction = m_idMap.get(id);
+ ASSERT(transaction);
+ m_transactionQueue.remove(transaction.get());
+ m_idMap.remove(id);
+ transaction->abort();
+ // FIXME: this will change once we have transactions actually running.
+}
+
+};
+
+#endif // ENABLE(INDEXED_DATABASE)
diff --git a/WebCore/storage/IDBTransactionCoordinator.h b/WebCore/storage/IDBTransactionCoordinator.h
new file mode 100644
index 0000000..104a956
--- /dev/null
+++ b/WebCore/storage/IDBTransactionCoordinator.h
@@ -0,0 +1,73 @@
+/*
+ * Copyright (C) 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:
+ *
+ * 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 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 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 IDBTransactionCoordinator_h
+#define IDBTransactionCoordinator_h
+
+#if ENABLE(INDEXED_DATABASE)
+
+#include "DOMStringList.h"
+#include "IDBTransactionBackendInterface.h"
+#include <wtf/ListHashSet.h>
+#include <wtf/RefPtr.h>
+
+namespace WebCore {
+
+class IDBTransactionCallbacks;
+class IDBDatabaseBackendImpl;
+
+// This class manages transactions as follows. Requests for new transactions are
+// always satisfied and the new transaction is placed in a queue.
+// Transactions are not actually started until the first operation is issued.
+// Each transaction executes in a separate thread and is committed automatically
+// when there are no more operations issued in its context.
+// When starting, a transaction will attempt to lock all the object stores in its
+// scope. If this does not happen within a given timeout, an exception is raised.
+// The Coordinator maintains a pool of threads. If there are no threads available
+// the next transaction in the queue will have to wait until a thread becomes
+// available.
+// Transactions are executed in the order the were created.
+class IDBTransactionCoordinator : public RefCounted<IDBTransactionCoordinator> {
+public:
+ static PassRefPtr<IDBTransactionCoordinator> create() { return adoptRef(new IDBTransactionCoordinator()); }
+ virtual ~IDBTransactionCoordinator();
+
+ PassRefPtr<IDBTransactionBackendInterface> createTransaction(DOMStringList* objectStores, unsigned short mode, unsigned long timeout, IDBDatabaseBackendImpl*);
+ void abort(int transactionId);
+
+private:
+ IDBTransactionCoordinator();
+
+ ListHashSet<IDBTransactionBackendInterface*> m_transactionQueue;
+ typedef HashMap<int, RefPtr<IDBTransactionBackendInterface> > IdToTransactionMap;
+ IdToTransactionMap m_idMap;
+ int m_nextID;
+};
+
+} // namespace WebCore
+
+#endif // ENABLE(INDEXED_DATABASE)
+
+#endif // IDBTransactionCoordinator_h
diff --git a/WebCore/storage/LocalStorageTask.h b/WebCore/storage/LocalStorageTask.h
index 8d53ce4..a2e35ea 100644
--- a/WebCore/storage/LocalStorageTask.h
+++ b/WebCore/storage/LocalStorageTask.h
@@ -43,10 +43,10 @@ namespace WebCore {
~LocalStorageTask();
- static PassOwnPtr<LocalStorageTask> createImport(StorageAreaSync* area) { return new LocalStorageTask(AreaImport, area); }
- static PassOwnPtr<LocalStorageTask> createSync(StorageAreaSync* area) { return new LocalStorageTask(AreaSync, area); }
- static PassOwnPtr<LocalStorageTask> createDeleteEmptyDatabase(StorageAreaSync* area) { return new LocalStorageTask(DeleteEmptyDatabase, area); }
- static PassOwnPtr<LocalStorageTask> createTerminate(LocalStorageThread* thread) { return new LocalStorageTask(TerminateThread, thread); }
+ static PassOwnPtr<LocalStorageTask> createImport(StorageAreaSync* area) { return adoptPtr(new LocalStorageTask(AreaImport, area)); }
+ static PassOwnPtr<LocalStorageTask> createSync(StorageAreaSync* area) { return adoptPtr(new LocalStorageTask(AreaSync, area)); }
+ static PassOwnPtr<LocalStorageTask> createDeleteEmptyDatabase(StorageAreaSync* area) { return adoptPtr(new LocalStorageTask(DeleteEmptyDatabase, area)); }
+ static PassOwnPtr<LocalStorageTask> createTerminate(LocalStorageThread* thread) { return adoptPtr(new LocalStorageTask(TerminateThread, thread)); }
void performTask();
diff --git a/WebCore/storage/LocalStorageThread.cpp b/WebCore/storage/LocalStorageThread.cpp
index d4a7b4c..cbb81c5 100644
--- a/WebCore/storage/LocalStorageThread.cpp
+++ b/WebCore/storage/LocalStorageThread.cpp
@@ -35,7 +35,7 @@ namespace WebCore {
PassOwnPtr<LocalStorageThread> LocalStorageThread::create()
{
- return new LocalStorageThread;
+ return adoptPtr(new LocalStorageThread);
}
LocalStorageThread::LocalStorageThread()
diff --git a/WebCore/storage/SQLTransaction.cpp b/WebCore/storage/SQLTransaction.cpp
index c9f6609..feaa46e 100644
--- a/WebCore/storage/SQLTransaction.cpp
+++ b/WebCore/storage/SQLTransaction.cpp
@@ -255,7 +255,7 @@ void SQLTransaction::openTransactionAndPreflight()
m_database->sqliteDatabase().setMaximumSize(m_database->maximumSize());
ASSERT(!m_sqliteTransaction);
- m_sqliteTransaction.set(new SQLiteTransaction(m_database->sqliteDatabase(), m_readOnly));
+ m_sqliteTransaction = adoptPtr(new SQLiteTransaction(m_database->sqliteDatabase(), m_readOnly));
m_database->resetDeletes();
m_database->disableAuthorizer();
@@ -273,7 +273,6 @@ void SQLTransaction::openTransactionAndPreflight()
// Transaction Steps 3 - Peform preflight steps, jumping to the error callback if they fail
if (m_wrapper && !m_wrapper->performPreflight(this)) {
- ASSERT(!m_database->sqliteDatabase().transactionInProgress());
m_sqliteTransaction.clear();
m_transactionError = m_wrapper->sqlError();
if (!m_transactionError)
diff --git a/WebCore/storage/SQLTransactionSync.cpp b/WebCore/storage/SQLTransactionSync.cpp
index e56d7b4..87f1eff 100644
--- a/WebCore/storage/SQLTransactionSync.cpp
+++ b/WebCore/storage/SQLTransactionSync.cpp
@@ -58,7 +58,7 @@ SQLTransactionSync::SQLTransactionSync(DatabaseSync* db, PassRefPtr<SQLTransacti
, m_callback(callback)
, m_readOnly(readOnly)
, m_modifiedDatabase(false)
- , m_transactionClient(new SQLTransactionClient())
+ , m_transactionClient(adoptPtr(new SQLTransactionClient()))
{
ASSERT(m_database->scriptExecutionContext()->isContextThread());
}
@@ -130,7 +130,7 @@ ExceptionCode SQLTransactionSync::begin()
m_database->sqliteDatabase().setMaximumSize(m_database->maximumSize());
ASSERT(!m_sqliteTransaction);
- m_sqliteTransaction.set(new SQLiteTransaction(m_database->sqliteDatabase(), m_readOnly));
+ m_sqliteTransaction = adoptPtr(new SQLiteTransaction(m_database->sqliteDatabase(), m_readOnly));
m_database->resetDeletes();
m_database->disableAuthorizer();
diff --git a/WebCore/storage/StorageNamespaceImpl.cpp b/WebCore/storage/StorageNamespaceImpl.cpp
index 0f07e07..3a21489 100644
--- a/WebCore/storage/StorageNamespaceImpl.cpp
+++ b/WebCore/storage/StorageNamespaceImpl.cpp
@@ -93,12 +93,12 @@ PassRefPtr<StorageNamespace> StorageNamespaceImpl::copy()
ASSERT(!m_isShutdown);
ASSERT(m_storageType == SessionStorage);
- StorageNamespaceImpl* newNamespace = new StorageNamespaceImpl(m_storageType, m_path, m_quota);
+ RefPtr<StorageNamespaceImpl> newNamespace = adoptRef(new StorageNamespaceImpl(m_storageType, m_path, m_quota));
StorageAreaMap::iterator end = m_storageAreaMap.end();
for (StorageAreaMap::iterator i = m_storageAreaMap.begin(); i != end; ++i)
newNamespace->m_storageAreaMap.set(i->first, i->second->copy());
- return adoptRef(newNamespace);
+ return newNamespace.release();
}
PassRefPtr<StorageArea> StorageNamespaceImpl::storageArea(PassRefPtr<SecurityOrigin> prpOrigin)
diff --git a/WebCore/storage/chromium/IDBKeyPathBackendImpl.cpp b/WebCore/storage/chromium/IDBKeyPathBackendImpl.cpp
new file mode 100644
index 0000000..0f10875
--- /dev/null
+++ b/WebCore/storage/chromium/IDBKeyPathBackendImpl.cpp
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 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:
+ *
+ * 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 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 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 "IDBKeyPathBackendImpl.h"
+
+#if ENABLE(INDEXED_DATABASE)
+
+#include "ChromiumBridge.h"
+
+namespace WebCore {
+
+void IDBKeyPathBackendImpl::createIDBKeysFromSerializedValuesAndKeyPath(const Vector<RefPtr<SerializedScriptValue>, 0>& values, const String& keyPath, Vector<RefPtr<IDBKey>, 0>& keys)
+{
+ ChromiumBridge::createIDBKeysFromSerializedValuesAndKeyPath(values, keyPath, keys);
+}
+
+} // namespace WebCore
+
+#endif
diff --git a/WebCore/svg/SVGElement.cpp b/WebCore/svg/SVGElement.cpp
index 055efcc..37e4930 100644
--- a/WebCore/svg/SVGElement.cpp
+++ b/WebCore/svg/SVGElement.cpp
@@ -312,7 +312,10 @@ void SVGElement::attributeChanged(Attribute* attr, bool preserveDecls)
if (isSynchronizingSVGAttributes())
return;
- svgAttributeChanged(attr->name());
+ // Changes to the style attribute are processed lazily (see Element::getAttribute() and related methods),
+ // so we don't want changes to the style attribute to result in extra work here.
+ if (attr->name() != HTMLNames::styleAttr)
+ svgAttributeChanged(attr->name());
}
void SVGElement::updateAnimatedSVGAttribute(const QualifiedName& name) const
@@ -331,10 +334,8 @@ void SVGElement::updateAnimatedSVGAttribute(const QualifiedName& name) const
ContainerNode* SVGElement::eventParentNode()
{
- if (Node* shadowParent = shadowParentNode()) {
- ASSERT(shadowParent->isContainerNode());
- return static_cast<ContainerNode*>(shadowParent);
- }
+ if (ContainerNode* shadowParent = shadowParentNode())
+ return shadowParent;
return StyledElement::eventParentNode();
}
diff --git a/WebCore/svg/SVGFEImageElement.cpp b/WebCore/svg/SVGFEImageElement.cpp
index 92534e8..eb024f6 100644
--- a/WebCore/svg/SVGFEImageElement.cpp
+++ b/WebCore/svg/SVGFEImageElement.cpp
@@ -30,10 +30,10 @@
#include "Document.h"
#include "RenderObject.h"
#include "RenderSVGResource.h"
+#include "SVGImageBufferTools.h"
#include "SVGLength.h"
#include "SVGNames.h"
#include "SVGPreserveAspectRatio.h"
-#include "SVGRenderSupport.h"
namespace WebCore {
@@ -134,7 +134,8 @@ PassRefPtr<FilterEffect> SVGFEImageElement::build(SVGFilterBuilder*)
IntRect targetRect = enclosingIntRect(renderer->objectBoundingBox());
m_targetImage = ImageBuffer::create(targetRect.size(), LinearRGB);
- SVGRenderSupport::renderSubtreeToImage(m_targetImage.get(), renderer);
+ AffineTransform contentTransformation;
+ SVGImageBufferTools::renderSubtreeToImageBuffer(m_targetImage.get(), renderer, contentTransformation);
}
return FEImage::create(m_targetImage ? m_targetImage->copyImage() : m_cachedImage->image(), preserveAspectRatio());
diff --git a/WebCore/svg/SVGLength.cpp b/WebCore/svg/SVGLength.cpp
index 415dc79..bdd5b27 100644
--- a/WebCore/svg/SVGLength.cpp
+++ b/WebCore/svg/SVGLength.cpp
@@ -27,6 +27,7 @@
#include "CSSHelper.h"
#include "FloatConversion.h"
#include "FrameView.h"
+#include "NotImplemented.h"
#include "RenderObject.h"
#include "RenderView.h"
#include "SVGParserUtilities.h"
@@ -203,7 +204,7 @@ void SVGLength::setValue(float value)
case LengthTypePercentage:
case LengthTypeEMS:
case LengthTypeEXS:
- ASSERT_NOT_REACHED();
+ notImplemented();
break;
case LengthTypePX:
m_valueInSpecifiedUnits = value;
diff --git a/WebCore/svg/SVGLocatable.cpp b/WebCore/svg/SVGLocatable.cpp
index 8147a88..b7b4440 100644
--- a/WebCore/svg/SVGLocatable.cpp
+++ b/WebCore/svg/SVGLocatable.cpp
@@ -71,10 +71,11 @@ SVGElement* SVGLocatable::farthestViewportElement(const SVGElement* element)
return farthest;
}
-FloatRect SVGLocatable::getBBox(const SVGElement* element)
+FloatRect SVGLocatable::getBBox(const SVGElement* element, StyleUpdateStrategy styleUpdateStrategy)
{
ASSERT(element);
- element->document()->updateLayoutIgnorePendingStylesheets();
+ if (styleUpdateStrategy == AllowStyleUpdate)
+ element->document()->updateLayoutIgnorePendingStylesheets();
// FIXME: Eventually we should support getBBox for detached elements.
if (!element->renderer())
@@ -83,10 +84,11 @@ FloatRect SVGLocatable::getBBox(const SVGElement* element)
return element->renderer()->objectBoundingBox();
}
-AffineTransform SVGLocatable::computeCTM(const SVGElement* element, CTMScope mode)
+AffineTransform SVGLocatable::computeCTM(const SVGElement* element, CTMScope mode, StyleUpdateStrategy styleUpdateStrategy)
{
ASSERT(element);
- element->document()->updateLayoutIgnorePendingStylesheets();
+ if (styleUpdateStrategy == AllowStyleUpdate)
+ element->document()->updateLayoutIgnorePendingStylesheets();
AffineTransform ctm;
@@ -108,12 +110,12 @@ AffineTransform SVGLocatable::computeCTM(const SVGElement* element, CTMScope mod
return ctm;
}
-AffineTransform SVGLocatable::getTransformToElement(SVGElement* target, ExceptionCode& ec) const
+AffineTransform SVGLocatable::getTransformToElement(SVGElement* target, ExceptionCode& ec, StyleUpdateStrategy styleUpdateStrategy) const
{
- AffineTransform ctm = getCTM();
+ AffineTransform ctm = getCTM(styleUpdateStrategy);
if (target && target->isStyledLocatable()) {
- AffineTransform targetCTM = static_cast<SVGStyledLocatableElement*>(target)->getCTM();
+ AffineTransform targetCTM = static_cast<SVGStyledLocatableElement*>(target)->getCTM(styleUpdateStrategy);
if (!targetCTM.isInvertible()) {
ec = SVGException::SVG_MATRIX_NOT_INVERTABLE;
return ctm;
diff --git a/WebCore/svg/SVGLocatable.h b/WebCore/svg/SVGLocatable.h
index 28df512..2e51dc5 100644
--- a/WebCore/svg/SVGLocatable.h
+++ b/WebCore/svg/SVGLocatable.h
@@ -40,10 +40,12 @@ public:
virtual SVGElement* nearestViewportElement() const = 0;
virtual SVGElement* farthestViewportElement() const = 0;
- virtual FloatRect getBBox() const = 0;
- virtual AffineTransform getCTM() const = 0;
- virtual AffineTransform getScreenCTM() const = 0;
- AffineTransform getTransformToElement(SVGElement*, ExceptionCode&) const;
+ enum StyleUpdateStrategy { AllowStyleUpdate, DisallowStyleUpdate };
+
+ virtual FloatRect getBBox(StyleUpdateStrategy) const = 0;
+ virtual AffineTransform getCTM(StyleUpdateStrategy) const = 0;
+ virtual AffineTransform getScreenCTM(StyleUpdateStrategy) const = 0;
+ AffineTransform getTransformToElement(SVGElement*, ExceptionCode&, StyleUpdateStrategy = AllowStyleUpdate) const;
static SVGElement* nearestViewportElement(const SVGElement*);
static SVGElement* farthestViewportElement(const SVGElement*);
@@ -56,8 +58,8 @@ public:
protected:
virtual AffineTransform localCoordinateSpaceTransform(SVGLocatable::CTMScope) const { return AffineTransform(); }
- static FloatRect getBBox(const SVGElement*);
- static AffineTransform computeCTM(const SVGElement*, CTMScope);
+ static FloatRect getBBox(const SVGElement*, StyleUpdateStrategy);
+ static AffineTransform computeCTM(const SVGElement*, CTMScope, StyleUpdateStrategy);
};
} // namespace WebCore
diff --git a/WebCore/svg/SVGPathBuilder.cpp b/WebCore/svg/SVGPathBuilder.cpp
index 85fbd65..6687edf 100644
--- a/WebCore/svg/SVGPathBuilder.cpp
+++ b/WebCore/svg/SVGPathBuilder.cpp
@@ -37,7 +37,7 @@ void SVGPathBuilder::moveTo(const FloatPoint& targetPoint, bool closed, PathCoor
{
ASSERT(m_path);
m_current = mode == AbsoluteCoordinates ? targetPoint : m_current + targetPoint;
- if (closed)
+ if (closed && !m_path->isEmpty())
m_path->closeSubpath();
m_path->moveTo(m_current);
}
diff --git a/WebCore/svg/SVGSVGElement.cpp b/WebCore/svg/SVGSVGElement.cpp
index 5193e2a..b7f9717 100644
--- a/WebCore/svg/SVGSVGElement.cpp
+++ b/WebCore/svg/SVGSVGElement.cpp
@@ -217,6 +217,9 @@ FloatPoint SVGSVGElement::currentTranslate() const
void SVGSVGElement::setCurrentTranslate(const FloatPoint &translation)
{
m_translation = translation;
+ if (RenderObject* object = renderer())
+ object->setNeedsLayout(true);
+
if (parentNode() == document() && document()->renderer())
document()->renderer()->repaint();
}
diff --git a/WebCore/svg/SVGStyledElement.cpp b/WebCore/svg/SVGStyledElement.cpp
index 4b073a0..6f04382 100644
--- a/WebCore/svg/SVGStyledElement.cpp
+++ b/WebCore/svg/SVGStyledElement.cpp
@@ -80,7 +80,7 @@ String SVGStyledElement::title() const
}
// Get the <use> element.
- Node* shadowParent = parent->shadowParentNode();
+ ContainerNode* shadowParent = parent->shadowParentNode();
if (shadowParent && shadowParent->isSVGElement() && shadowParent->hasTagName(SVGNames::useTag)) {
SVGUseElement* useElement = static_cast<SVGUseElement*>(shadowParent);
// If the <use> title is not empty we found the title to use.
diff --git a/WebCore/svg/SVGStyledLocatableElement.cpp b/WebCore/svg/SVGStyledLocatableElement.cpp
index 3d87da4..6b49542 100644
--- a/WebCore/svg/SVGStyledLocatableElement.cpp
+++ b/WebCore/svg/SVGStyledLocatableElement.cpp
@@ -50,19 +50,19 @@ SVGElement* SVGStyledLocatableElement::farthestViewportElement() const
return SVGLocatable::farthestViewportElement(this);
}
-FloatRect SVGStyledLocatableElement::getBBox() const
+FloatRect SVGStyledLocatableElement::getBBox(StyleUpdateStrategy styleUpdateStrategy) const
{
- return SVGLocatable::getBBox(this);
+ return SVGLocatable::getBBox(this, styleUpdateStrategy);
}
-AffineTransform SVGStyledLocatableElement::getCTM() const
+AffineTransform SVGStyledLocatableElement::getCTM(StyleUpdateStrategy styleUpdateStrategy) const
{
- return SVGLocatable::computeCTM(this, SVGLocatable::NearestViewportScope);
+ return SVGLocatable::computeCTM(this, SVGLocatable::NearestViewportScope, styleUpdateStrategy);
}
-AffineTransform SVGStyledLocatableElement::getScreenCTM() const
+AffineTransform SVGStyledLocatableElement::getScreenCTM(StyleUpdateStrategy styleUpdateStrategy) const
{
- return SVGLocatable::computeCTM(this, SVGLocatable::ScreenScope);
+ return SVGLocatable::computeCTM(this, SVGLocatable::ScreenScope, styleUpdateStrategy);
}
}
diff --git a/WebCore/svg/SVGStyledLocatableElement.h b/WebCore/svg/SVGStyledLocatableElement.h
index ef1c454..6eab7b0 100644
--- a/WebCore/svg/SVGStyledLocatableElement.h
+++ b/WebCore/svg/SVGStyledLocatableElement.h
@@ -40,9 +40,9 @@ namespace WebCore {
virtual SVGElement* nearestViewportElement() const;
virtual SVGElement* farthestViewportElement() const;
- virtual FloatRect getBBox() const;
- virtual AffineTransform getCTM() const;
- virtual AffineTransform getScreenCTM() const;
+ virtual FloatRect getBBox(StyleUpdateStrategy = AllowStyleUpdate) const;
+ virtual AffineTransform getCTM(StyleUpdateStrategy = AllowStyleUpdate) const;
+ virtual AffineTransform getScreenCTM(StyleUpdateStrategy = AllowStyleUpdate) const;
virtual AffineTransform localCoordinateSpaceTransform(SVGLocatable::CTMScope mode) const { return SVGLocatable::localCoordinateSpaceTransform(mode); }
};
diff --git a/WebCore/svg/SVGStyledTransformableElement.cpp b/WebCore/svg/SVGStyledTransformableElement.cpp
index 84af351..279f437 100644
--- a/WebCore/svg/SVGStyledTransformableElement.cpp
+++ b/WebCore/svg/SVGStyledTransformableElement.cpp
@@ -43,14 +43,14 @@ SVGStyledTransformableElement::~SVGStyledTransformableElement()
{
}
-AffineTransform SVGStyledTransformableElement::getCTM() const
+AffineTransform SVGStyledTransformableElement::getCTM(StyleUpdateStrategy styleUpdateStrategy) const
{
- return SVGLocatable::computeCTM(this, SVGLocatable::NearestViewportScope);
+ return SVGLocatable::computeCTM(this, SVGLocatable::NearestViewportScope, styleUpdateStrategy);
}
-AffineTransform SVGStyledTransformableElement::getScreenCTM() const
+AffineTransform SVGStyledTransformableElement::getScreenCTM(StyleUpdateStrategy styleUpdateStrategy) const
{
- return SVGLocatable::computeCTM(this, SVGLocatable::ScreenScope);
+ return SVGLocatable::computeCTM(this, SVGLocatable::ScreenScope, styleUpdateStrategy);
}
AffineTransform SVGStyledTransformableElement::animatedLocalTransform() const
@@ -101,9 +101,9 @@ SVGElement* SVGStyledTransformableElement::farthestViewportElement() const
return SVGTransformable::farthestViewportElement(this);
}
-FloatRect SVGStyledTransformableElement::getBBox() const
+FloatRect SVGStyledTransformableElement::getBBox(StyleUpdateStrategy styleUpdateStrategy) const
{
- return SVGTransformable::getBBox(this);
+ return SVGTransformable::getBBox(this, styleUpdateStrategy);
}
RenderObject* SVGStyledTransformableElement::createRenderer(RenderArena* arena, RenderStyle*)
diff --git a/WebCore/svg/SVGStyledTransformableElement.h b/WebCore/svg/SVGStyledTransformableElement.h
index f020c89..1d7b197 100644
--- a/WebCore/svg/SVGStyledTransformableElement.h
+++ b/WebCore/svg/SVGStyledTransformableElement.h
@@ -38,8 +38,8 @@ public:
virtual bool isStyledTransformable() const { return true; }
- virtual AffineTransform getCTM() const;
- virtual AffineTransform getScreenCTM() const;
+ virtual AffineTransform getCTM(StyleUpdateStrategy = AllowStyleUpdate) const;
+ virtual AffineTransform getScreenCTM(StyleUpdateStrategy = AllowStyleUpdate) const;
virtual SVGElement* nearestViewportElement() const;
virtual SVGElement* farthestViewportElement() const;
@@ -47,7 +47,7 @@ public:
virtual AffineTransform animatedLocalTransform() const;
virtual AffineTransform* supplementalTransform();
- virtual FloatRect getBBox() const;
+ virtual FloatRect getBBox(StyleUpdateStrategy = AllowStyleUpdate) const;
virtual void parseMappedAttribute(Attribute*);
virtual void synchronizeProperty(const QualifiedName&);
diff --git a/WebCore/svg/SVGTextElement.cpp b/WebCore/svg/SVGTextElement.cpp
index 57774cd..e13e611 100644
--- a/WebCore/svg/SVGTextElement.cpp
+++ b/WebCore/svg/SVGTextElement.cpp
@@ -68,19 +68,19 @@ SVGElement* SVGTextElement::farthestViewportElement() const
return SVGTransformable::farthestViewportElement(this);
}
-FloatRect SVGTextElement::getBBox() const
+FloatRect SVGTextElement::getBBox(StyleUpdateStrategy styleUpdateStrategy) const
{
- return SVGTransformable::getBBox(this);
+ return SVGTransformable::getBBox(this, styleUpdateStrategy);
}
-AffineTransform SVGTextElement::getCTM() const
+AffineTransform SVGTextElement::getCTM(StyleUpdateStrategy styleUpdateStrategy) const
{
- return SVGLocatable::computeCTM(this, SVGLocatable::NearestViewportScope);
+ return SVGLocatable::computeCTM(this, SVGLocatable::NearestViewportScope, styleUpdateStrategy);
}
-AffineTransform SVGTextElement::getScreenCTM() const
+AffineTransform SVGTextElement::getScreenCTM(StyleUpdateStrategy styleUpdateStrategy) const
{
- return SVGLocatable::computeCTM(this, SVGLocatable::ScreenScope);
+ return SVGLocatable::computeCTM(this, SVGLocatable::ScreenScope, styleUpdateStrategy);
}
AffineTransform SVGTextElement::animatedLocalTransform() const
diff --git a/WebCore/svg/SVGTextElement.h b/WebCore/svg/SVGTextElement.h
index b954835..1788ea9 100644
--- a/WebCore/svg/SVGTextElement.h
+++ b/WebCore/svg/SVGTextElement.h
@@ -38,9 +38,9 @@ namespace WebCore {
virtual SVGElement* nearestViewportElement() const;
virtual SVGElement* farthestViewportElement() const;
- virtual FloatRect getBBox() const;
- virtual AffineTransform getCTM() const;
- virtual AffineTransform getScreenCTM() const;
+ virtual FloatRect getBBox(StyleUpdateStrategy = AllowStyleUpdate) const;
+ virtual AffineTransform getCTM(StyleUpdateStrategy = AllowStyleUpdate) const;
+ virtual AffineTransform getScreenCTM(StyleUpdateStrategy = AllowStyleUpdate) const;
virtual AffineTransform animatedLocalTransform() const;
virtual AffineTransform* supplementalTransform();
virtual AffineTransform localCoordinateSpaceTransform(SVGLocatable::CTMScope mode) const { return SVGTransformable::localCoordinateSpaceTransform(mode); }
diff --git a/WebCore/xml/XSLTProcessor.cpp b/WebCore/xml/XSLTProcessor.cpp
index 6e149a1..41569d7 100644
--- a/WebCore/xml/XSLTProcessor.cpp
+++ b/WebCore/xml/XSLTProcessor.cpp
@@ -32,6 +32,7 @@
#include "Frame.h"
#include "FrameLoader.h"
#include "FrameView.h"
+#include "HTMLBodyElement.h"
#include "HTMLDocument.h"
#include "Page.h"
#include "Text.h"
@@ -99,9 +100,16 @@ static inline RefPtr<DocumentFragment> createFragmentFromSource(const String& so
{
RefPtr<DocumentFragment> fragment = outputDoc->createDocumentFragment();
- if (sourceMIMEType == "text/html")
- fragment->parseHTML(sourceString, 0);
- else if (sourceMIMEType == "text/plain")
+ if (sourceMIMEType == "text/html") {
+ // As far as I can tell, there isn't a spec for how transformToFragment
+ // is supposed to work. Based on the documentation I can find, it looks
+ // like we want to start parsing the fragment in the InBody insertion
+ // mode. Unfortunately, that's an implementation detail of the parser.
+ // We achieve that effect here by passing in a fake body element as
+ // context for the fragment.
+ RefPtr<HTMLBodyElement> fakeBody = HTMLBodyElement::create(outputDoc);
+ fragment->parseHTML(sourceString, fakeBody.get());
+ } else if (sourceMIMEType == "text/plain")
fragment->parserAddChild(Text::create(outputDoc, sourceString));
else {
bool successfulParse = fragment->parseXML(sourceString, 0);