2010-11-10 Peter Rybin <peter.rybin@gmail.com>
authorcaseq@chromium.org <caseq@chromium.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 10 Nov 2010 14:43:50 +0000 (14:43 +0000)
committercaseq@chromium.org <caseq@chromium.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 10 Nov 2010 14:43:50 +0000 (14:43 +0000)
        Reviewed by Adam Barth.

        HTML parser should provide script column position within HTML document to JavaScript engine
        https://bugs.webkit.org/show_bug.cgi?id=45271

        Adds TextPosition* classes -- a structure that stores line/column/generation
        level coordinates inside text document. Adds *BasedNumber classes -- typesafe int
        wrappers that emphasize whether int number is used as zero-based or
        one-based.

        * GNUmakefile.am:
        * JavaScriptCore.gypi:
        * JavaScriptCore.xcodeproj/project.pbxproj:
        * wtf/text/TextPosition.h: Added.
        (WTF::TextPosition::TextPosition):
        (WTF::TextPosition::minimumPosition):
        (WTF::TextPosition::belowRangePosition):
        (WTF::ZeroBasedNumber::fromZeroBasedInt):
        (WTF::ZeroBasedNumber::ZeroBasedNumber):
        (WTF::ZeroBasedNumber::zeroBasedInt):
        (WTF::ZeroBasedNumber::base):
        (WTF::ZeroBasedNumber::belowBase):
        (WTF::OneBasedNumber::fromOneBasedInt):
        (WTF::OneBasedNumber::OneBasedNumber):
        (WTF::OneBasedNumber::oneBasedInt):
        (WTF::OneBasedNumber::convertAsZeroBasedInt):
        (WTF::OneBasedNumber::convertToZeroBased):
        (WTF::OneBasedNumber::base):
        (WTF::OneBasedNumber::belowBase):
        (WTF::toZeroBasedTextPosition):
        (WTF::toOneBasedTextPosition):
        (WTF::ZeroBasedNumber::convertToOneBased):

2010-11-10  Peter Rybin  <peter.rybin@gmail.com>

        Reviewed by Adam Barth.

        HTML parser should provide script column position within HTML document to JavaScript engine
        https://bugs.webkit.org/show_bug.cgi?id=45271

        Replaces line number with TextPosition struct so that script engine
        gets script starting line/column.

        * ForwardingHeaders/wtf/text/TextPosition.h: Added.
        * bindings/js/ScriptSourceCode.h:
        (WebCore::ScriptSourceCode::ScriptSourceCode):
        * bindings/v8/ScheduledAction.cpp:
        (WebCore::ScheduledAction::ScheduledAction):
        * bindings/v8/ScriptController.cpp:
        (WebCore::ScriptController::eventHandlerPosition):
        * bindings/v8/ScriptController.h:
        * bindings/v8/ScriptEventListener.cpp:
        (WebCore::createAttributeEventListener):
        * bindings/v8/ScriptSourceCode.h:
        (WebCore::ScriptSourceCode::ScriptSourceCode):
        (WebCore::ScriptSourceCode::startLine):
        (WebCore::ScriptSourceCode::startPosition):
        * bindings/v8/V8LazyEventListener.cpp:
        (WebCore::V8LazyEventListener::V8LazyEventListener):
        (WebCore::V8LazyEventListener::prepareListenerObject):
        * bindings/v8/V8LazyEventListener.h:
        (WebCore::V8LazyEventListener::create):
        * bindings/v8/V8Proxy.cpp:
        (WebCore::V8Proxy::compileScript):
        (WebCore::V8Proxy::evaluate):
        (WebCore::V8Proxy::runScript):
        * bindings/v8/V8Proxy.h:
        * bindings/v8/WorkerContextExecutionProxy.cpp:
        (WebCore::WorkerContextExecutionProxy::evaluate):
        (WebCore::WorkerContextExecutionProxy::runScript):
        * bindings/v8/WorkerContextExecutionProxy.h:
        * bindings/v8/WorkerScriptController.cpp:
        (WebCore::WorkerScriptController::evaluate):
        * dom/PendingScript.cpp:
        (WebCore::PendingScript::releaseElementAndClear):
        * dom/PendingScript.h:
        (WebCore::PendingScript::PendingScript):
        (WebCore::PendingScript::operator=):
        (WebCore::PendingScript::startingPosition):
        * dom/ScriptableDocumentParser.h:
        * dom/XMLDocumentParser.h:
        * dom/XMLDocumentParserLibxml2.cpp:
        (WebCore::XMLDocumentParser::XMLDocumentParser):
        (WebCore::XMLDocumentParser::startElementNs):
        (WebCore::XMLDocumentParser::endElementNs):
        (WebCore::XMLDocumentParser::lineNumber):
        (WebCore::XMLDocumentParser::columnNumber):
        (WebCore::XMLDocumentParser::textPosition):
        (WebCore::XMLDocumentParser::textPositionOneBased):
        * dom/XMLDocumentParserQt.cpp:
        (WebCore::XMLDocumentParser::XMLDocumentParser):
        (WebCore::XMLDocumentParser::textPosition):
        (WebCore::XMLDocumentParser::parseStartElement):
        (WebCore::XMLDocumentParser::parseEndElement):
        * html/parser/HTMLDocumentParser.cpp:
        (WebCore::HTMLDocumentParser::runScriptsForPausedTreeBuilder):
        (WebCore::HTMLDocumentParser::textPosition):
        * html/parser/HTMLDocumentParser.h:
        * html/parser/HTMLScriptRunner.cpp:
        (WebCore::HTMLScriptRunner::sourceFromPendingScript):
        (WebCore::HTMLScriptRunner::execute):
        (WebCore::HTMLScriptRunner::runScript):
        * html/parser/HTMLScriptRunner.h:
        * html/parser/HTMLTreeBuilder.cpp:
        (WebCore::uninitializedPositionValue1):
        (WebCore::HTMLTreeBuilder::HTMLTreeBuilder):
        (WebCore::HTMLTreeBuilder::takeScriptToProcess):
        (WebCore::HTMLTreeBuilder::processEndTag):
        (WebCore::HTMLTreeBuilder::processScriptStartTag):
        * html/parser/HTMLTreeBuilder.h:

2010-11-10  Peter Rybin  <peter.rybin@gmail.com>

        Reviewed by Adam Barth.

        HTML parser should provide script column position within HTML document to JavaScript engine
        https://bugs.webkit.org/show_bug.cgi?id=45271

        Replaces script line number with TextPosition structure.

        * src/WebFrameImpl.cpp:
        (WebKit::WebFrameImpl::executeScript):
        (WebKit::WebFrameImpl::executeScriptInIsolatedWorld):
        (WebKit::WebFrameImpl::executeScriptAndReturnValue):

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

35 files changed:
JavaScriptCore/ChangeLog
JavaScriptCore/GNUmakefile.am
JavaScriptCore/JavaScriptCore.gypi
JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj
JavaScriptCore/wtf/text/TextPosition.h [new file with mode: 0644]
JavaScriptGlue/ForwardingHeaders/wtf/text/TextPosition.h [new file with mode: 0644]
WebCore/ChangeLog
WebCore/ForwardingHeaders/wtf/text/TextPosition.h [new file with mode: 0644]
WebCore/bindings/js/ScriptSourceCode.h
WebCore/bindings/v8/ScheduledAction.cpp
WebCore/bindings/v8/ScriptController.cpp
WebCore/bindings/v8/ScriptController.h
WebCore/bindings/v8/ScriptEventListener.cpp
WebCore/bindings/v8/ScriptSourceCode.h
WebCore/bindings/v8/V8LazyEventListener.cpp
WebCore/bindings/v8/V8LazyEventListener.h
WebCore/bindings/v8/V8Proxy.cpp
WebCore/bindings/v8/V8Proxy.h
WebCore/bindings/v8/WorkerContextExecutionProxy.cpp
WebCore/bindings/v8/WorkerContextExecutionProxy.h
WebCore/bindings/v8/WorkerScriptController.cpp
WebCore/dom/PendingScript.cpp
WebCore/dom/PendingScript.h
WebCore/dom/ScriptableDocumentParser.h
WebCore/dom/XMLDocumentParser.h
WebCore/dom/XMLDocumentParserLibxml2.cpp
WebCore/dom/XMLDocumentParserQt.cpp
WebCore/html/parser/HTMLDocumentParser.cpp
WebCore/html/parser/HTMLDocumentParser.h
WebCore/html/parser/HTMLScriptRunner.cpp
WebCore/html/parser/HTMLScriptRunner.h
WebCore/html/parser/HTMLTreeBuilder.cpp
WebCore/html/parser/HTMLTreeBuilder.h
WebKit/chromium/ChangeLog
WebKit/chromium/src/WebFrameImpl.cpp

index 22bdd48..80374d1 100644 (file)
@@ -1,3 +1,38 @@
+2010-11-10  Peter Rybin  <peter.rybin@gmail.com>
+
+        Reviewed by Adam Barth.
+
+        HTML parser should provide script column position within HTML document to JavaScript engine
+        https://bugs.webkit.org/show_bug.cgi?id=45271
+
+        Adds TextPosition* classes -- a structure that stores line/column/generation
+        level coordinates inside text document. Adds *BasedNumber classes -- typesafe int
+        wrappers that emphasize whether int number is used as zero-based or
+        one-based.
+
+        * GNUmakefile.am:
+        * JavaScriptCore.gypi:
+        * JavaScriptCore.xcodeproj/project.pbxproj:
+        * wtf/text/TextPosition.h: Added.
+        (WTF::TextPosition::TextPosition):
+        (WTF::TextPosition::minimumPosition):
+        (WTF::TextPosition::belowRangePosition):
+        (WTF::ZeroBasedNumber::fromZeroBasedInt):
+        (WTF::ZeroBasedNumber::ZeroBasedNumber):
+        (WTF::ZeroBasedNumber::zeroBasedInt):
+        (WTF::ZeroBasedNumber::base):
+        (WTF::ZeroBasedNumber::belowBase):
+        (WTF::OneBasedNumber::fromOneBasedInt):
+        (WTF::OneBasedNumber::OneBasedNumber):
+        (WTF::OneBasedNumber::oneBasedInt):
+        (WTF::OneBasedNumber::convertAsZeroBasedInt):
+        (WTF::OneBasedNumber::convertToZeroBased):
+        (WTF::OneBasedNumber::base):
+        (WTF::OneBasedNumber::belowBase):
+        (WTF::toZeroBasedTextPosition):
+        (WTF::toOneBasedTextPosition):
+        (WTF::ZeroBasedNumber::convertToOneBased):
+
 2010-11-09  Gabor Loki  <loki@webkit.org>
 
         Reviewed by Gavin Barraclough.
index c507f5d..f7806b4 100644 (file)
@@ -518,6 +518,7 @@ javascriptcore_sources += \
        JavaScriptCore/wtf/text/StringImpl.cpp \
        JavaScriptCore/wtf/text/StringImpl.h \
        JavaScriptCore/wtf/text/StringStatics.cpp \
+       JavaScriptCore/wtf/text/TextPosition.h \
        JavaScriptCore/wtf/text/WTFString.cpp \
        JavaScriptCore/wtf/text/WTFString.h \
        JavaScriptCore/wtf/ThreadIdentifierDataPthreads.cpp \
index 6252d07..deb36fb 100644 (file)
             'wtf/text/StringImpl.cpp',
             'wtf/text/StringImpl.h',
             'wtf/text/StringStatics.cpp',
+            'wtf/text/TextPosition.h',
             'wtf/text/WTFString.cpp',
             'wtf/text/WTFString.h',
             'wtf/unicode/Collator.h',
index d134a73..b40d74e 100644 (file)
                E1EE793D0D6C9B9200FEA3BA /* ThreadingPthreads.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E1EE793C0D6C9B9200FEA3BA /* ThreadingPthreads.cpp */; };
                E1EF79AA0CE97BA60088D500 /* UTF8.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E1EF79A80CE97BA60088D500 /* UTF8.cpp */; };
                E48E0F2D0F82151700A8CA37 /* FastAllocBase.h in Headers */ = {isa = PBXBuildFile; fileRef = E48E0F2C0F82151700A8CA37 /* FastAllocBase.h */; settings = {ATTRIBUTES = (Private, ); }; };
+               F3BD31ED126735770065467F /* TextPosition.h in Headers */ = {isa = PBXBuildFile; fileRef = F3BD31D0126730180065467F /* TextPosition.h */; settings = {ATTRIBUTES = (Private, ); }; };
                FE1B447A0ECCD73B004F4DD1 /* StdLibExtras.h in Headers */ = {isa = PBXBuildFile; fileRef = FE1B44790ECCD73B004F4DD1 /* StdLibExtras.h */; settings = {ATTRIBUTES = (Private, ); }; };
 /* End PBXBuildFile section */
 
                E1EF79A80CE97BA60088D500 /* UTF8.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = UTF8.cpp; sourceTree = "<group>"; };
                E1EF79A90CE97BA60088D500 /* UTF8.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = UTF8.h; sourceTree = "<group>"; };
                E48E0F2C0F82151700A8CA37 /* FastAllocBase.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FastAllocBase.h; sourceTree = "<group>"; };
+               F3BD31D0126730180065467F /* TextPosition.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = TextPosition.h; path = text/TextPosition.h; sourceTree = "<group>"; };
                F5BB2BC5030F772101FCFE1D /* Completion.h */ = {isa = PBXFileReference; fileEncoding = 30; indentWidth = 4; lastKnownFileType = sourcecode.c.h; path = Completion.h; sourceTree = "<group>"; tabWidth = 8; };
                F5C290E60284F98E018635CA /* JavaScriptCorePrefix.h */ = {isa = PBXFileReference; fileEncoding = 30; indentWidth = 4; lastKnownFileType = sourcecode.c.h; path = JavaScriptCorePrefix.h; sourceTree = "<group>"; tabWidth = 8; };
                F68EBB8C0255D4C601FF60F7 /* config.h */ = {isa = PBXFileReference; fileEncoding = 30; indentWidth = 4; lastKnownFileType = sourcecode.c.h; path = config.h; sourceTree = "<group>"; tabWidth = 8; };
                                868BFA07117CEFD100B908B1 /* StringImpl.h */,
                                86B99AE2117E578100DF5A90 /* StringImplBase.h */,
                                8626BECE11928E3900782FAB /* StringStatics.cpp */,
+                               F3BD31D0126730180065467F /* TextPosition.h */,
                                868BFA15117CF19900B908B1 /* WTFString.cpp */,
                                868BFA16117CF19900B908B1 /* WTFString.h */,
                        );
                                90213E3E123A40C200D422F3 /* MemoryStatistics.h in Headers */,
                                A730B6121250068F009D25B1 /* StrictEvalActivation.h in Headers */,
                                933F5CDC1269229B0049191E /* NullPtr.h in Headers */,
+                               F3BD31ED126735770065467F /* TextPosition.h in Headers */,
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
diff --git a/JavaScriptCore/wtf/text/TextPosition.h b/JavaScriptCore/wtf/text/TextPosition.h
new file mode 100644 (file)
index 0000000..63dc594
--- /dev/null
@@ -0,0 +1,141 @@
+/*
+ * 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 INC. AND ITS CONTRIBUTORS ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef TextPosition_h
+#define TextPosition_h
+
+#include <wtf/Assertions.h>
+
+namespace WTF {
+
+/*
+ * Text Position
+ *
+ * TextPosition structure specifies coordinates within an text resource. It is used mostly
+ * for saving script source position.
+ *
+ * Later TextPosition0 and TextPosition1 and both number types can be merged together quite easily.
+ *
+ * 0-based and 1-based
+ *
+ * Line and column numbers could be interpreted as zero-based or 1-based. Since
+ * both practices coexist in WebKit source base, 'int' type should be replaced with
+ * a dedicated wrapper types, so that compiler helped us with this ambiguity.
+ *
+ * Here we introduce 2 types of numbers: ZeroBasedNumber and OneBasedNumber and
+ * 2 corresponding types of TextPosition structure. While only one type ought to be enough,
+ * this is done to keep transition to the new types as transparent as possible:
+ * e.g. in areas where 0-based integers are used, TextPosition0 should be introduced. This
+ * way all changes will remain trackable.
+ *
+ * Later both number types can be merged in one type quite easily.
+ *
+ * For type safety and for the future type merge it is important that all operations in API
+ * that accept or return integer have a name explicitly defining base of integer. For this reason
+ * int-receiving constructors are hidden from API.
+ */
+
+template<typename NUMBER>
+class TextPosition {
+public:
+    TextPosition(NUMBER line, NUMBER column)
+        : m_line(line)
+        , m_column(column)
+    {
+    }
+    TextPosition() {}
+
+    // A 'minimum' value of position, used as a default value.
+    static TextPosition<NUMBER> minimumPosition() { return TextPosition<NUMBER>(NUMBER::base(), NUMBER::base()); }
+
+    // A value with line value less than a minimum; used as an impossible position.
+    static TextPosition<NUMBER> belowRangePosition() { return TextPosition<NUMBER>(NUMBER::belowBase(), NUMBER::base()); }
+
+    NUMBER m_line;
+    NUMBER m_column;
+};
+
+class OneBasedNumber;
+
+// An int wrapper that always reminds you that the number should be 0-based
+class ZeroBasedNumber {
+public:
+    static ZeroBasedNumber fromZeroBasedInt(int zeroBasedInt) { return ZeroBasedNumber(zeroBasedInt); }
+
+    ZeroBasedNumber() {}
+
+    int zeroBasedInt() const { return m_value; }
+
+    OneBasedNumber convertToOneBased() const;
+
+    static ZeroBasedNumber base() { return 0; }
+    static ZeroBasedNumber belowBase() { return -1; }
+
+private:
+    ZeroBasedNumber(int value) : m_value(value) {}
+    int m_value;
+};
+
+// An int wrapper that always reminds you that the number should be 1-based
+class OneBasedNumber {
+public:
+    static OneBasedNumber fromOneBasedInt(int oneBasedInt) { return OneBasedNumber(oneBasedInt); }
+    OneBasedNumber() {}
+
+    int oneBasedInt() const { return m_value; }
+    int convertAsZeroBasedInt() const { return m_value - 1; }
+    ZeroBasedNumber convertToZeroBased() const { return ZeroBasedNumber::fromZeroBasedInt(m_value - 1); }
+
+    static OneBasedNumber base() { return 1; }
+    static OneBasedNumber belowBase() { return 0; }
+
+private:
+    OneBasedNumber(int value) : m_value(value) {}
+    int m_value;
+};
+
+typedef TextPosition<ZeroBasedNumber> TextPosition0;
+typedef TextPosition<OneBasedNumber> TextPosition1;
+
+inline TextPosition0 toZeroBasedTextPosition(const TextPosition1& position)
+{
+    return TextPosition0(position.m_line.convertToZeroBased(), position.m_column.convertToZeroBased());
+}
+
+inline TextPosition1 toOneBasedTextPosition(const TextPosition0& position)
+{
+    return TextPosition1(position.m_line.convertToOneBased(), position.m_column.convertToOneBased());
+}
+
+inline OneBasedNumber ZeroBasedNumber::convertToOneBased() const
+{
+    return OneBasedNumber::fromOneBasedInt(m_value + 1);
+}
+
+}
+
+using WTF::TextPosition0;
+using WTF::TextPosition1;
+
+#endif // TextPosition_h
diff --git a/JavaScriptGlue/ForwardingHeaders/wtf/text/TextPosition.h b/JavaScriptGlue/ForwardingHeaders/wtf/text/TextPosition.h
new file mode 100644 (file)
index 0000000..bd4f09b
--- /dev/null
@@ -0,0 +1 @@
+#include <JavaScriptCore/TextPosition.h>
index d68af7d..655d2c4 100644 (file)
@@ -1,3 +1,81 @@
+2010-11-10  Peter Rybin  <peter.rybin@gmail.com>
+
+        Reviewed by Adam Barth.
+
+        HTML parser should provide script column position within HTML document to JavaScript engine
+        https://bugs.webkit.org/show_bug.cgi?id=45271
+
+        Replaces line number with TextPosition struct so that script engine
+        gets script starting line/column.
+
+        * ForwardingHeaders/wtf/text/TextPosition.h: Added.
+        * bindings/js/ScriptSourceCode.h:
+        (WebCore::ScriptSourceCode::ScriptSourceCode):
+        * bindings/v8/ScheduledAction.cpp:
+        (WebCore::ScheduledAction::ScheduledAction):
+        * bindings/v8/ScriptController.cpp:
+        (WebCore::ScriptController::eventHandlerPosition):
+        * bindings/v8/ScriptController.h:
+        * bindings/v8/ScriptEventListener.cpp:
+        (WebCore::createAttributeEventListener):
+        * bindings/v8/ScriptSourceCode.h:
+        (WebCore::ScriptSourceCode::ScriptSourceCode):
+        (WebCore::ScriptSourceCode::startLine):
+        (WebCore::ScriptSourceCode::startPosition):
+        * bindings/v8/V8LazyEventListener.cpp:
+        (WebCore::V8LazyEventListener::V8LazyEventListener):
+        (WebCore::V8LazyEventListener::prepareListenerObject):
+        * bindings/v8/V8LazyEventListener.h:
+        (WebCore::V8LazyEventListener::create):
+        * bindings/v8/V8Proxy.cpp:
+        (WebCore::V8Proxy::compileScript):
+        (WebCore::V8Proxy::evaluate):
+        (WebCore::V8Proxy::runScript):
+        * bindings/v8/V8Proxy.h:
+        * bindings/v8/WorkerContextExecutionProxy.cpp:
+        (WebCore::WorkerContextExecutionProxy::evaluate):
+        (WebCore::WorkerContextExecutionProxy::runScript):
+        * bindings/v8/WorkerContextExecutionProxy.h:
+        * bindings/v8/WorkerScriptController.cpp:
+        (WebCore::WorkerScriptController::evaluate):
+        * dom/PendingScript.cpp:
+        (WebCore::PendingScript::releaseElementAndClear):
+        * dom/PendingScript.h:
+        (WebCore::PendingScript::PendingScript):
+        (WebCore::PendingScript::operator=):
+        (WebCore::PendingScript::startingPosition):
+        * dom/ScriptableDocumentParser.h:
+        * dom/XMLDocumentParser.h:
+        * dom/XMLDocumentParserLibxml2.cpp:
+        (WebCore::XMLDocumentParser::XMLDocumentParser):
+        (WebCore::XMLDocumentParser::startElementNs):
+        (WebCore::XMLDocumentParser::endElementNs):
+        (WebCore::XMLDocumentParser::lineNumber):
+        (WebCore::XMLDocumentParser::columnNumber):
+        (WebCore::XMLDocumentParser::textPosition):
+        (WebCore::XMLDocumentParser::textPositionOneBased):
+        * dom/XMLDocumentParserQt.cpp:
+        (WebCore::XMLDocumentParser::XMLDocumentParser):
+        (WebCore::XMLDocumentParser::textPosition):
+        (WebCore::XMLDocumentParser::parseStartElement):
+        (WebCore::XMLDocumentParser::parseEndElement):
+        * html/parser/HTMLDocumentParser.cpp:
+        (WebCore::HTMLDocumentParser::runScriptsForPausedTreeBuilder):
+        (WebCore::HTMLDocumentParser::textPosition):
+        * html/parser/HTMLDocumentParser.h:
+        * html/parser/HTMLScriptRunner.cpp:
+        (WebCore::HTMLScriptRunner::sourceFromPendingScript):
+        (WebCore::HTMLScriptRunner::execute):
+        (WebCore::HTMLScriptRunner::runScript):
+        * html/parser/HTMLScriptRunner.h:
+        * html/parser/HTMLTreeBuilder.cpp:
+        (WebCore::uninitializedPositionValue1):
+        (WebCore::HTMLTreeBuilder::HTMLTreeBuilder):
+        (WebCore::HTMLTreeBuilder::takeScriptToProcess):
+        (WebCore::HTMLTreeBuilder::processEndTag):
+        (WebCore::HTMLTreeBuilder::processScriptStartTag):
+        * html/parser/HTMLTreeBuilder.h:
+
 2010-11-10  Ilya Sherman  <isherman@chromium.org>
 
         Reviewed by Shinichiro Hamaji.
diff --git a/WebCore/ForwardingHeaders/wtf/text/TextPosition.h b/WebCore/ForwardingHeaders/wtf/text/TextPosition.h
new file mode 100644 (file)
index 0000000..1600984
--- /dev/null
@@ -0,0 +1,4 @@
+#ifndef WebCore_FWD_TextPosition_h
+#define WebCore_FWD_TextPosition_h
+#include <JavaScriptCore/TextPosition.h>
+#endif
index 32d6298..092eeb8 100644 (file)
 #include "ScriptSourceProvider.h"
 #include "StringSourceProvider.h"
 #include "KURL.h"
+#include <wtf/text/TextPosition.h>
 #include <wtf/RefPtr.h>
 
 namespace WebCore {
 
 class ScriptSourceCode {
 public:
-    ScriptSourceCode(const String& source, const KURL& url = KURL(), int startLine = 1)
+    ScriptSourceCode(const String& source, const KURL& url = KURL(), const TextPosition1& startPosition = TextPosition1::minimumPosition())
         : m_provider(StringSourceProvider::create(source, url.isNull() ? String() : url.string()))
-        , m_code(m_provider, startLine)
+        , m_code(m_provider, startPosition.m_line.oneBasedInt())
         , m_url(url)
     {
     }
index dcd0bb3..708fbe6 100644 (file)
@@ -45,7 +45,7 @@ namespace WebCore {
 
 ScheduledAction::ScheduledAction(v8::Handle<v8::Context> context, v8::Handle<v8::Function> func, int argc, v8::Handle<v8::Value> argv[])
     : m_context(context)
-    , m_code(String(), KURL(), 0)
+    , m_code(String(), KURL(), TextPosition1::belowRangePosition())
 {
     m_function = v8::Persistent<v8::Function>::New(func);
 
index fa37c38..d746f15 100644 (file)
@@ -263,20 +263,12 @@ ScriptValue ScriptController::evaluate(const ScriptSourceCode& sourceCode, Shoul
     return ScriptValue(object);
 }
 
-int ScriptController::eventHandlerLineNumber() const
+TextPosition0 ScriptController::eventHandlerPosition() const
 {
     ScriptableDocumentParser* parser = m_frame->document()->scriptableDocumentParser();
     if (parser)
-        return parser->lineNumber();
-    return 0;
-}
-
-int ScriptController::eventHandlerColumnNumber() const
-{
-    ScriptableDocumentParser* parser = m_frame->document()->scriptableDocumentParser();
-    if (parser)
-        return parser->columnNumber();
-    return 0;
+        return parser->textPosition();
+    return TextPosition0::minimumPosition();
 }
 
 void ScriptController::finishedWithEvent(Event* event)
index 63f1c17..d093f39 100644 (file)
@@ -155,8 +155,7 @@ public:
 
     void finishedWithEvent(Event*);
 
-    int eventHandlerLineNumber() const;
-    int eventHandlerColumnNumber() const;
+    TextPosition0 eventHandlerPosition() const;
 
     void setProcessingTimerCallback(bool processingTimerCallback) { m_processingTimerCallback = processingTimerCallback; }
     // FIXME: Currently we don't use the parameter world at all.
index 72df79d..b46fc5a 100644 (file)
@@ -50,8 +50,8 @@ PassRefPtr<V8LazyEventListener> createAttributeEventListener(Node* node, Attribu
     if (attr->isNull())
         return 0;
 
-    int lineNumber = 1;
-    int columnNumber = 0;
+    // FIXME: Very strange: we initialize zero-based number with '1'.
+    TextPosition0 position(WTF::ZeroBasedNumber::fromZeroBasedInt(1), WTF::ZeroBasedNumber::base());
     String sourceURL;
 
     if (Frame* frame = node->document()->frame()) {
@@ -64,12 +64,11 @@ PassRefPtr<V8LazyEventListener> createAttributeEventListener(Node* node, Attribu
             return 0;
         }
 
-        lineNumber = scriptController->eventHandlerLineNumber();
-        columnNumber = scriptController->eventHandlerColumnNumber();
+        position = scriptController->eventHandlerPosition();
         sourceURL = node->document()->url().string();
     }
 
-    return V8LazyEventListener::create(attr->localName().string(), node->isSVGElement(), attr->value(), sourceURL, lineNumber, columnNumber, WorldContextHandle(UseMainWorld));
+    return V8LazyEventListener::create(attr->localName().string(), node->isSVGElement(), attr->value(), sourceURL, position, WorldContextHandle(UseMainWorld));
 }
 
 PassRefPtr<V8LazyEventListener> createAttributeEventListener(Frame* frame, Attribute* attr)
@@ -81,10 +80,6 @@ PassRefPtr<V8LazyEventListener> createAttributeEventListener(Frame* frame, Attri
     if (attr->isNull())
         return 0;
 
-    int lineNumber = 1;
-    int columnNumber = 0;
-    String sourceURL;
-
     ScriptController* scriptController = frame->script();
     if (!scriptController->canExecuteScripts(AboutToExecuteScript))
         return 0;
@@ -94,10 +89,9 @@ PassRefPtr<V8LazyEventListener> createAttributeEventListener(Frame* frame, Attri
         return 0;
     }
 
-    lineNumber = scriptController->eventHandlerLineNumber();
-    columnNumber = scriptController->eventHandlerColumnNumber();
-    sourceURL = frame->document()->url().string();
-    return V8LazyEventListener::create(attr->localName().string(), frame->document()->isSVGDocument(), attr->value(), sourceURL, lineNumber, columnNumber, WorldContextHandle(UseMainWorld));
+    TextPosition0 position = scriptController->eventHandlerPosition();
+    String sourceURL = frame->document()->url().string();
+    return V8LazyEventListener::create(attr->localName().string(), frame->document()->isSVGDocument(), attr->value(), sourceURL, position, WorldContextHandle(UseMainWorld));
 }
 
 String eventListenerHandlerBody(Document* document, EventListener* listener)
index dbc9d5e..2478151 100644 (file)
 #include "CachedScript.h"
 #include "KURL.h"
 #include "PlatformString.h"
+#include <wtf/text/TextPosition.h>
 
 namespace WebCore {
 
 class ScriptSourceCode {
 public:
-    ScriptSourceCode(const String& source, const KURL& url = KURL(), int startLine = 1)
+    ScriptSourceCode(const String& source, const KURL& url = KURL(), const TextPosition1& startPosition = TextPosition1::minimumPosition())
         : m_source(source)
         , m_cachedScript(0)
         , m_url(url)
-        , m_startLine(startLine)
+        , m_startPosition(startPosition)
     {
     }
 
@@ -54,7 +55,7 @@ public:
         : m_source(cs->script())
         , m_cachedScript(cs)
         , m_url(ParsedURLString, cs->url())
-        , m_startLine(1)
+        , m_startPosition(TextPosition1::minimumPosition())
     {
     }
 
@@ -63,13 +64,14 @@ public:
     const String& source() const { return m_source; }
     CachedScript* cachedScript() const { return m_cachedScript.get(); }
     const KURL& url() const { return m_url; }
-    int startLine() const { return m_startLine; }
+    int startLine() const { return m_startPosition.m_line.oneBasedInt(); }
+    const TextPosition1& startPosition() const { return m_startPosition; }
 
 private:
     String m_source;
     CachedResourceHandle<CachedScript> m_cachedScript;
     KURL m_url;
-    int m_startLine;
+    TextPosition1 m_startPosition;
 };
 
 } // namespace WebCore
index 7f13c5a..7f46333 100644 (file)
 
 namespace WebCore {
 
-V8LazyEventListener::V8LazyEventListener(const String& functionName, bool isSVGEvent, const String& code, const String sourceURL, int lineNumber, int columnNumber, const WorldContextHandle& worldContext)
+V8LazyEventListener::V8LazyEventListener(const String& functionName, bool isSVGEvent, const String& code, const String sourceURL, const TextPosition0& position, const WorldContextHandle& worldContext)
     : V8AbstractEventListener(true, worldContext)
     , m_functionName(functionName)
     , m_isSVGEvent(isSVGEvent)
     , m_code(code)
     , m_sourceURL(sourceURL)
-    , m_lineNumber(lineNumber)
-    , m_columnNumber(columnNumber)
+    , m_position(position)
 {
 }
 
@@ -114,7 +113,7 @@ void V8LazyEventListener::prepareListenerObject(ScriptExecutionContext* context)
     // Insert '\n' otherwise //-style comments could break the handler.
     code.append(  "\n}).call(this, evt);}}}})");
     v8::Handle<v8::String> codeExternalString = v8ExternalString(code);
-    v8::Handle<v8::Script> script = V8Proxy::compileScript(codeExternalString, m_sourceURL, m_lineNumber);
+    v8::Handle<v8::Script> script = V8Proxy::compileScript(codeExternalString, m_sourceURL, m_position);
     if (!script.IsEmpty()) {
         v8::Local<v8::Value> value = proxy->runScript(script, false);
         if (!value.IsEmpty()) {
index f174d23..08467fe 100644 (file)
@@ -34,6 +34,7 @@
 #include "PlatformString.h"
 #include "V8AbstractEventListener.h"
 #include <v8.h>
+#include <wtf/text/TextPosition.h>
 #include <wtf/PassRefPtr.h>
 
 namespace WebCore {
@@ -45,9 +46,9 @@ namespace WebCore {
     // A V8LazyEventListener is always a HTML event handler.
     class V8LazyEventListener : public V8AbstractEventListener {
     public:
-        static PassRefPtr<V8LazyEventListener> create(const String& functionName, bool isSVGEvent, const String& code, const String& sourceURL, int lineNumber, int columnNumber, const WorldContextHandle& worldContext)
+        static PassRefPtr<V8LazyEventListener> create(const String& functionName, bool isSVGEvent, const String& code, const String& sourceURL, const TextPosition0& position, const WorldContextHandle& worldContext)
         {
-            return adoptRef(new V8LazyEventListener(functionName, isSVGEvent, code, sourceURL, lineNumber, columnNumber, worldContext));
+            return adoptRef(new V8LazyEventListener(functionName, isSVGEvent, code, sourceURL, position, worldContext));
         }
 
         virtual bool isLazy() const { return true; }
@@ -56,7 +57,7 @@ namespace WebCore {
         virtual void prepareListenerObject(ScriptExecutionContext*);
 
     private:
-        V8LazyEventListener(const String& functionName, bool isSVGEvent, const String& code, const String sourceURL, int lineNumber, int columnNumber, const WorldContextHandle& worldContext);
+        V8LazyEventListener(const String& functionName, bool isSVGEvent, const String& code, const String sourceURL, const TextPosition0& position, const WorldContextHandle& worldContext);
 
         virtual v8::Local<v8::Value> callListenerFunction(ScriptExecutionContext*, v8::Handle<v8::Value> jsEvent, Event*);
 
@@ -70,8 +71,7 @@ namespace WebCore {
         bool m_isSVGEvent;
         String m_code;
         String m_sourceURL;
-        int m_lineNumber;
-        int m_columnNumber;
+        TextPosition0 m_position;
     };
 
 } // namespace WebCore
index e7d6bf6..7b596c8 100644 (file)
@@ -236,12 +236,13 @@ V8Proxy::~V8Proxy()
     windowShell()->destroyGlobal();
 }
 
-v8::Handle<v8::Script> V8Proxy::compileScript(v8::Handle<v8::String> code, const String& fileName, int baseLine, v8::ScriptData* scriptData)
+v8::Handle<v8::Script> V8Proxy::compileScript(v8::Handle<v8::String> code, const String& fileName, const TextPosition0& scriptStartPosition, v8::ScriptData* scriptData)
 {
     const uint16_t* fileNameString = fromWebCoreString(fileName);
     v8::Handle<v8::String> name = v8::String::New(fileNameString, fileName.length());
-    v8::Handle<v8::Integer> line = v8::Integer::New(baseLine);
-    v8::ScriptOrigin origin(name, line);
+    v8::Handle<v8::Integer> line = v8::Integer::New(scriptStartPosition.m_line.zeroBasedInt());
+    v8::Handle<v8::Integer> column = v8::Integer::New(scriptStartPosition.m_column.zeroBasedInt());
+    v8::ScriptOrigin origin(name, line, column);
     v8::Handle<v8::Script> script = v8::Script::Compile(code, &origin, scriptData);
     return script;
 }
@@ -394,7 +395,7 @@ v8::Local<v8::Value> V8Proxy::evaluate(const ScriptSourceCode& source, Node* nod
 
         // NOTE: For compatibility with WebCore, ScriptSourceCode's line starts at
         // 1, whereas v8 starts at 0.
-        v8::Handle<v8::Script> script = compileScript(code, source.url(), source.startLine() - 1, scriptData.get());
+        v8::Handle<v8::Script> script = compileScript(code, source.url(), WTF::toZeroBasedTextPosition(source.startPosition()), scriptData.get());
 #if PLATFORM(CHROMIUM)
         PlatformBridge::traceEventEnd("v8.compile", node, "");
 
@@ -426,7 +427,7 @@ v8::Local<v8::Value> V8Proxy::runScript(v8::Handle<v8::Script> script, bool isIn
         // FIXME: Ideally, we should be able to re-use the origin of the
         // script passed to us as the argument instead of using an empty string
         // and 0 baseLine.
-        script = compileScript(code, "", 0);
+        script = compileScript(code, "", TextPosition0::minimumPosition());
     }
 
     if (handleOutOfMemory())
index 8a0da72..80d4691 100644 (file)
@@ -279,7 +279,7 @@ namespace WebCore {
 
         static v8::Handle<v8::Value> checkNewLegal(const v8::Arguments&);
 
-        static v8::Handle<v8::Script> compileScript(v8::Handle<v8::String> code, const String& fileName, int baseLine, v8::ScriptData* = 0);
+        static v8::Handle<v8::Script> compileScript(v8::Handle<v8::String> code, const String& fileName, const TextPosition0& scriptStartPosition, v8::ScriptData* = 0);
 
         // If the exception code is different from zero, a DOM exception is
         // schedule to be thrown.
index 16e0b41..cefb2fa 100644 (file)
@@ -184,7 +184,7 @@ bool WorkerContextExecutionProxy::forgetV8EventObject(Event* event)
     return false;
 }
 
-ScriptValue WorkerContextExecutionProxy::evaluate(const String& script, const String& fileName, int baseLine, WorkerContextExecutionState* state)
+ScriptValue WorkerContextExecutionProxy::evaluate(const String& script, const String& fileName, const TextPosition0& scriptStartPosition, WorkerContextExecutionState* state)
 {
     v8::HandleScope hs;
 
@@ -196,7 +196,7 @@ ScriptValue WorkerContextExecutionProxy::evaluate(const String& script, const St
     v8::TryCatch exceptionCatcher;
 
     v8::Local<v8::String> scriptString = v8ExternalString(script);
-    v8::Handle<v8::Script> compiledScript = V8Proxy::compileScript(scriptString, fileName, baseLine);
+    v8::Handle<v8::Script> compiledScript = V8Proxy::compileScript(scriptString, fileName, scriptStartPosition);
     v8::Local<v8::Value> result = runScript(compiledScript);
 
     if (!exceptionCatcher.CanContinue())
@@ -227,7 +227,7 @@ v8::Local<v8::Value> WorkerContextExecutionProxy::runScript(v8::Handle<v8::Scrip
     // Compute the source string and prevent against infinite recursion.
     if (m_recursion >= kMaxRecursionDepth) {
         v8::Local<v8::String> code = v8ExternalString("throw RangeError('Recursion too deep')");
-        script = V8Proxy::compileScript(code, "", 0);
+        script = V8Proxy::compileScript(code, "", TextPosition0::minimumPosition());
     }
 
     if (V8Proxy::handleOutOfMemory())
index 58824b9..e70c3d2 100644 (file)
@@ -36,6 +36,7 @@
 
 #include "ScriptValue.h"
 #include <v8.h>
+#include <wtf/text/TextPosition.h>
 #include <wtf/OwnPtr.h>
 #include <wtf/Vector.h>
 
@@ -66,7 +67,7 @@ namespace WebCore {
         void trackEvent(Event*);
 
         // Evaluate a script file in the current execution environment.
-        ScriptValue evaluate(const String& script, const String& fileName, int baseLine, WorkerContextExecutionState*);
+        ScriptValue evaluate(const String& script, const String& fileName, const TextPosition0& scriptStartPosition, WorkerContextExecutionState*);
 
         // Returns a local handle of the context.
         v8::Local<v8::Context> context() { return v8::Local<v8::Context>::New(m_context); }
index 7db0d8d..b56d383 100644 (file)
@@ -75,7 +75,7 @@ ScriptValue WorkerScriptController::evaluate(const ScriptSourceCode& sourceCode,
     }
 
     WorkerContextExecutionState state;
-    ScriptValue result = m_proxy->evaluate(sourceCode.source(), sourceCode.url().string(), sourceCode.startLine() - 1, &state);
+    ScriptValue result = m_proxy->evaluate(sourceCode.source(), sourceCode.url().string(), WTF::toZeroBasedTextPosition(sourceCode.startPosition()), &state);
     if (state.hadException) {
         if (exception)
             *exception = state.exception;
index 42e225a..18f6071 100644 (file)
@@ -40,7 +40,7 @@ PendingScript::~PendingScript()
 PassRefPtr<Element> PendingScript::releaseElementAndClear()
 {
     setCachedScript(0);
-    m_startingLineNumber = 0;
+    m_startingPosition = TextPosition1::belowRangePosition();
     m_watchingForLoad = false;
     return m_element.release();
 }
index 44e1e49..083507a 100644 (file)
@@ -28,6 +28,7 @@
 
 #include "CachedResourceClient.h"
 #include "CachedResourceHandle.h"
+#include <wtf/text/TextPosition.h>
 #include <wtf/PassRefPtr.h>
 
 namespace WebCore {
@@ -43,14 +44,14 @@ class Element;
 class PendingScript : public CachedResourceClient {
 public:
     PendingScript()
-        : m_startingLineNumber(0)
+        : m_startingPosition(TextPosition1::belowRangePosition())
         , m_watchingForLoad(false)
     {
     }
 
     PendingScript(const PendingScript& other)
         : CachedResourceClient(other)
-        , m_startingLineNumber(other.m_startingLineNumber)
+        , m_startingPosition(other.m_startingPosition)
         , m_watchingForLoad(other.m_watchingForLoad)
         , m_element(other.m_element)
     {
@@ -64,7 +65,7 @@ public:
         if (this == &other)
             return *this;
 
-        m_startingLineNumber = other.m_startingLineNumber;
+        m_startingPosition = other.m_startingPosition;
         m_watchingForLoad = other.m_watchingForLoad;
         m_element = other.m_element;
         setCachedScript(other.cachedScript());
@@ -74,7 +75,7 @@ public:
 
     // FIXME: No setter means this is never set to anything other than 0.
     // This is either unnecessary or incorrect.
-    int startingLineNumber() const { return m_startingLineNumber; }
+    TextPosition1 startingPosition() const { return m_startingPosition; }
 
     bool watchingForLoad() const { return m_watchingForLoad; }
     void setWatchingForLoad(bool b) { m_watchingForLoad = b; }
@@ -89,7 +90,7 @@ public:
     virtual void notifyFinished(CachedResource*);
 
 private:
-    int m_startingLineNumber; // Only used for inline script tags.
+    TextPosition1 m_startingPosition; // Only used for inline script tags.
     bool m_watchingForLoad;
     RefPtr<Element> m_element;
     CachedResourceHandle<CachedScript> m_cachedScript;
index 8b16304..d9bf85c 100644 (file)
 #define ScriptableDocumentParser_h
 
 #include "DecodedDataDocumentParser.h"
+#include <wtf/text/TextPosition.h>
 
 namespace WebCore {
 
-class SegmentedString;
 class XSSAuditor;
 
 class ScriptableDocumentParser : public DecodedDataDocumentParser {
@@ -47,7 +47,7 @@ public:
 
     // These are used to expose the current line/column to the scripting system.
     virtual int lineNumber() const = 0;
-    virtual int columnNumber() const = 0;
+    virtual TextPosition0 textPosition() const = 0;
 
     XSSAuditor* xssAuditor() const { return m_xssAuditor; }
     void setXSSAuditor(XSSAuditor* auditor) { m_xssAuditor = auditor; }
index e0770ba..e3d3cc2 100644 (file)
@@ -102,7 +102,7 @@ namespace WebCore {
         // WMLErrorHandling uses these functions.
         virtual bool wellFormed() const { return !m_sawError; }
         virtual int lineNumber() const;
-        virtual int columnNumber() const;
+        TextPosition0 textPosition() const;
 
         static bool supportsXMLVersion(const String&);
 
@@ -129,6 +129,14 @@ namespace WebCore {
 
         bool appendFragmentSource(const String&);
 
+        int columnNumber() const;
+
+        // This method is introduced to temporary legalize existing line/column
+        // coordinate bug: it is believed that numbers that originally were zero-based
+        // eventually becomes one-based.
+        // FIXME: Investigate and get rid of this method.
+        TextPosition1 textPositionOneBased() const;
+
 #if USE(QXMLSTREAM)
 private:
         void parse();
@@ -208,7 +216,7 @@ public:
 
         CachedResourceHandle<CachedScript> m_pendingScript;
         RefPtr<Element> m_scriptElement;
-        int m_scriptStartLine;
+        TextPosition1 m_scriptStartPosition;
 
         bool m_parsingFragment;
         AtomicString m_defaultNamespaceURI;
index 77b0af6..ef5f3e4 100644 (file)
@@ -560,7 +560,7 @@ XMLDocumentParser::XMLDocumentParser(Document* document, FrameView* frameView)
     , m_lastErrorLine(0)
     , m_lastErrorColumn(0)
     , m_pendingScript(0)
-    , m_scriptStartLine(0)
+    , m_scriptStartPosition(TextPosition1::belowRangePosition())
     , m_parsingFragment(false)
     , m_scriptingPermission(FragmentScriptingAllowed)
 {
@@ -587,7 +587,7 @@ XMLDocumentParser::XMLDocumentParser(DocumentFragment* fragment, Element* parent
     , m_lastErrorLine(0)
     , m_lastErrorColumn(0)
     , m_pendingScript(0)
-    , m_scriptStartLine(0)
+    , m_scriptStartPosition(TextPosition1::belowRangePosition())
     , m_parsingFragment(true)
     , m_scriptingPermission(scriptingPermission)
 {
@@ -819,7 +819,7 @@ void XMLDocumentParser::startElementNs(const xmlChar* xmlLocalName, const xmlCha
 
     ScriptElement* scriptElement = toScriptElement(newElement.get());
     if (scriptElement)
-        m_scriptStartLine = lineNumber();
+        m_scriptStartPosition = textPositionOneBased();
 
     m_currentNode->deprecatedParserAddChild(newElement.get());
 
@@ -910,7 +910,7 @@ void XMLDocumentParser::endElementNs()
             } else
                 m_scriptElement = 0;
         } else
-            m_view->frame()->script()->executeScript(ScriptSourceCode(scriptElement->scriptContent(), document()->url(), m_scriptStartLine));
+            m_view->frame()->script()->executeScript(ScriptSourceCode(scriptElement->scriptContent(), document()->url(), m_scriptStartPosition));
 
         // JavaScript may have detached the parser
         if (isDetached())
@@ -1376,14 +1376,39 @@ void* xmlDocPtrForString(CachedResourceLoader* cachedResourceLoader, const Strin
 
 int XMLDocumentParser::lineNumber() const
 {
+    // FIXME: The implementation probably returns 1-based int, but method should return 0-based.
     return context() ? context()->input->line : 1;
 }
 
 int XMLDocumentParser::columnNumber() const
 {
+    // FIXME: The implementation probably returns 1-based int, but method should return 0-based.
     return context() ? context()->input->col : 1;
 }
 
+TextPosition0 XMLDocumentParser::textPosition() const
+{
+    xmlParserCtxtPtr context = this->context();
+    if (!context)
+        return TextPosition0::minimumPosition();
+    // FIXME: The context probably contains 1-based numbers, but we treat them as 0-based,
+    //        to be consistent with fixme's in lineNumber() and columnNumber
+    //        methods.
+    return TextPosition0(WTF::ZeroBasedNumber::fromZeroBasedInt(context->input->line),
+        WTF::ZeroBasedNumber::fromZeroBasedInt(context->input->col));
+}
+
+// This method has a correct implementation, in contrast to textPosition() method.
+// It should replace textPosition().
+TextPosition1 XMLDocumentParser::textPositionOneBased() const
+{
+    xmlParserCtxtPtr context = this->context();
+    if (!context)
+        return TextPosition1::minimumPosition();
+    return TextPosition1(WTF::OneBasedNumber::fromOneBasedInt(context->input->line),
+        WTF::OneBasedNumber::fromOneBasedInt(context->input->col));
+}
+
 void XMLDocumentParser::stopParsing()
 {
     DocumentParser::stopParsing();
index 974784c..48cf5de 100644 (file)
@@ -105,7 +105,7 @@ XMLDocumentParser::XMLDocumentParser(Document* document, FrameView* frameView)
     , m_lastErrorLine(0)
     , m_lastErrorColumn(0)
     , m_pendingScript(0)
-    , m_scriptStartLine(0)
+    , m_scriptStartPosition(TextPosition1::belowRangePosition())
     , m_parsingFragment(false)
     , m_scriptingPermission(FragmentScriptingAllowed)
 {
@@ -132,7 +132,7 @@ XMLDocumentParser::XMLDocumentParser(DocumentFragment* fragment, Element* parent
     , m_lastErrorLine(0)
     , m_lastErrorColumn(0)
     , m_pendingScript(0)
-    , m_scriptStartLine(0)
+    , m_scriptStartPosition(TextPosition1::belowRangePosition())
     , m_parsingFragment(true)
     , m_scriptingPermission(permission)
 {
@@ -238,6 +238,18 @@ int XMLDocumentParser::columnNumber() const
     return m_stream.columnNumber();
 }
 
+TextPosition0 XMLDocumentParser::textPosition() const
+{
+    return TextPosition0(WTF::ZeroBasedNumber::fromZeroBasedInt(lineNumber()), WTF::ZeroBasedNumber::fromZeroBasedInt(columnNumber()));
+}
+
+// This method incorrectly reinterprets zero-base lineNumber method as one-based number.
+// FIXME: This error is kept for compatibility. We should fix it eventually. 
+TextPosition1 XMLDocumentParser::textPositionOneBased() const
+{
+    return TextPosition1(WTF::OneBasedNumber::fromOneBasedInt(lineNumber()), WTF::OneBasedNumber::fromOneBasedInt(columnNumber()));
+}
+
 void XMLDocumentParser::stopParsing()
 {
     ScriptableDocumentParser::stopParsing();
@@ -522,7 +534,7 @@ void XMLDocumentParser::parseStartElement()
 
     ScriptElement* scriptElement = toScriptElement(newElement.get());
     if (scriptElement)
-        m_scriptStartLine = lineNumber();
+        m_scriptStartPosition = textPositionOneBased();
 
     m_currentNode->deprecatedParserAddChild(newElement.get());
 
@@ -599,7 +611,7 @@ void XMLDocumentParser::parseEndElement()
             } else
                 m_scriptElement = 0;
         } else
-            m_view->frame()->script()->executeScript(ScriptSourceCode(scriptElement->scriptContent(), document()->url(), m_scriptStartLine));
+            m_view->frame()->script()->executeScript(ScriptSourceCode(scriptElement->scriptContent(), document()->url(), m_scriptStartPosition));
     }
     m_requestingScript = false;
     popCurrentNode();
index 94cc2aa..d169417 100644 (file)
@@ -191,12 +191,12 @@ bool HTMLDocumentParser::runScriptsForPausedTreeBuilder()
 {
     ASSERT(m_treeBuilder->isPaused());
 
-    int scriptStartLine = 0;
-    RefPtr<Element> scriptElement = m_treeBuilder->takeScriptToProcess(scriptStartLine);
+    TextPosition1 scriptStartPosition = TextPosition1::belowRangePosition();
+    RefPtr<Element> scriptElement = m_treeBuilder->takeScriptToProcess(scriptStartPosition);
     // We will not have a scriptRunner when parsing a DocumentFragment.
     if (!m_scriptRunner)
         return true;
-    return m_scriptRunner->execute(scriptElement.release(), scriptStartLine);
+    return m_scriptRunner->execute(scriptElement.release(), scriptStartPosition);
 }
 
 void HTMLDocumentParser::pumpTokenizer(SynchronousMode mode)
@@ -396,9 +396,13 @@ int HTMLDocumentParser::lineNumber() const
     return m_tokenizer->lineNumber();
 }
 
-int HTMLDocumentParser::columnNumber() const
+TextPosition0 HTMLDocumentParser::textPosition() const
 {
-    return m_tokenizer->columnNumber();
+    int lineZeroBased = m_tokenizer->lineNumber();
+    int columnOneBased = m_tokenizer->columnNumber();
+
+    return TextPosition0(WTF::ZeroBasedNumber::fromZeroBasedInt(lineZeroBased),
+        WTF::OneBasedNumber::fromOneBasedInt(columnOneBased).convertToZeroBased());
 }
 
 bool HTMLDocumentParser::isWaitingForScripts() const
index d9625f1..05053df 100644 (file)
@@ -92,7 +92,7 @@ private:
     virtual bool isExecutingScript() const;
     virtual void executeScriptsWaitingForStylesheets();
     virtual int lineNumber() const;
-    virtual int columnNumber() const;
+    virtual TextPosition0 textPosition() const;
 
     // HTMLScriptRunnerHost
     virtual void watchForLoad(CachedResource*);
index 75db644..61f673a 100644 (file)
@@ -99,7 +99,7 @@ ScriptSourceCode HTMLScriptRunner::sourceFromPendingScript(const PendingScript&
         return ScriptSourceCode(script.cachedScript());
     }
     errorOccurred = false;
-    return ScriptSourceCode(script.element()->textContent(), documentURLForScriptExecution(m_document), script.startingLineNumber());
+    return ScriptSourceCode(script.element()->textContent(), documentURLForScriptExecution(m_document), script.startingPosition());
 }
 
 bool HTMLScriptRunner::isPendingScriptReady(const PendingScript& script)
@@ -172,13 +172,13 @@ void HTMLScriptRunner::stopWatchingForLoad(PendingScript& pendingScript)
 
 // This function should match 10.2.5.11 "An end tag whose tag name is 'script'"
 // Script handling lives outside the tree builder to keep the each class simple.
-bool HTMLScriptRunner::execute(PassRefPtr<Element> scriptElement, int startLine)
+bool HTMLScriptRunner::execute(PassRefPtr<Element> scriptElement, const TextPosition1& scriptStartPosition)
 {
     ASSERT(scriptElement);
     // FIXME: If scripting is disabled, always just return true;
 
     // Try to execute the script given to us.
-    runScript(scriptElement.get(), startLine);
+    runScript(scriptElement.get(), scriptStartPosition);
 
     if (haveParsingBlockingScript()) {
         if (m_scriptNestingLevel)
@@ -290,7 +290,7 @@ bool HTMLScriptRunner::requestPendingScript(PendingScript& pendingScript, Elemen
 
 // This method is meant to match the HTML5 definition of "running a script"
 // http://www.whatwg.org/specs/web-apps/current-work/multipage/scripting-1.html#running-a-script
-void HTMLScriptRunner::runScript(Element* script, int startingLineNumber)
+void HTMLScriptRunner::runScript(Element* script, const TextPosition1& scriptStartPosition)
 {
     ASSERT(m_document);
     ASSERT(!haveParsingBlockingScript());
@@ -317,7 +317,7 @@ void HTMLScriptRunner::runScript(Element* script, int startingLineNumber)
             // See https://bugs.webkit.org/show_bug.cgi?id=40047
             // ASSERT(document()->haveStylesheetsLoaded());
             ASSERT(isExecutingScript());
-            ScriptSourceCode sourceCode(script->textContent(), documentURLForScriptExecution(m_document), startingLineNumber);
+            ScriptSourceCode sourceCode(script->textContent(), documentURLForScriptExecution(m_document), scriptStartPosition);
             executeScript(sourceCode);
         }
     }
index be21dd2..2df295f 100644 (file)
@@ -28,6 +28,7 @@
 
 #include "PendingScript.h"
 #include <wtf/Deque.h>
+#include <wtf/text/TextPosition.h>
 #include <wtf/Noncopyable.h>
 #include <wtf/PassRefPtr.h>
 
@@ -52,7 +53,7 @@ public:
     void detach();
 
     // Processes the passed in script and any pending scripts if possible.
-    bool execute(PassRefPtr<Element> scriptToProcess, int scriptStartLine);
+    bool execute(PassRefPtr<Element> scriptToProcess, const TextPosition1& scriptStartPosition);
 
     bool executeScriptsWaitingForLoad(CachedResource*);
     bool hasScriptsWaitingForStylesheets() const { return m_hasScriptsWaitingForStylesheets; }
@@ -76,7 +77,7 @@ private:
     void requestDeferredScript(Element*);
     bool requestPendingScript(PendingScript&, Element*) const;
 
-    void runScript(Element*, int startingLineNumber);
+    void runScript(Element*, const TextPosition1& scriptStartPosition);
 
     // Helpers for dealing with HTMLScriptRunnerHost
     void watchForLoad(PendingScript&);
index 6134607..cd459c3 100644 (file)
@@ -56,6 +56,11 @@ using namespace HTMLNames;
 
 static const int uninitializedLineNumberValue = -1;
 
+static TextPosition1 uninitializedPositionValue1()
+{
+    return TextPosition1(WTF::OneBasedNumber::fromOneBasedInt(-1), WTF::OneBasedNumber::base());
+}
+
 namespace {
 
 inline bool isHTMLSpaceOrReplacementCharacter(UChar character)
@@ -340,8 +345,8 @@ HTMLTreeBuilder::HTMLTreeBuilder(HTMLTokenizer* tokenizer, HTMLDocument* documen
     , m_insertionMode(InitialMode)
     , m_originalInsertionMode(InitialMode)
     , m_tokenizer(tokenizer)
-    , m_scriptToProcessStartLine(uninitializedLineNumberValue)
-    , m_lastScriptElementStartLine(uninitializedLineNumberValue)
+    , m_scriptToProcessStartPosition(uninitializedPositionValue1())
+    , m_lastScriptElementStartPosition(TextPosition0::belowRangePosition())
     , m_usePreHTML5ParserQuirks(usePreHTML5ParserQuirks)
     , m_hasPendingForeignInsertionModeSteps(false)
 {
@@ -359,8 +364,8 @@ HTMLTreeBuilder::HTMLTreeBuilder(HTMLTokenizer* tokenizer, DocumentFragment* fra
     , m_insertionMode(InitialMode)
     , m_originalInsertionMode(InitialMode)
     , m_tokenizer(tokenizer)
-    , m_scriptToProcessStartLine(uninitializedLineNumberValue)
-    , m_lastScriptElementStartLine(uninitializedLineNumberValue)
+    , m_scriptToProcessStartPosition(uninitializedPositionValue1())
+    , m_lastScriptElementStartPosition(TextPosition0::belowRangePosition())
     , m_usePreHTML5ParserQuirks(usePreHTML5ParserQuirks)
     , m_hasPendingForeignInsertionModeSteps(false)
 {
@@ -423,15 +428,15 @@ HTMLTreeBuilder::FragmentParsingContext::~FragmentParsingContext()
 {
 }
 
-PassRefPtr<Element> HTMLTreeBuilder::takeScriptToProcess(int& scriptStartLine)
+PassRefPtr<Element> HTMLTreeBuilder::takeScriptToProcess(TextPosition1& scriptStartPosition)
 {
     // Unpause ourselves, callers may pause us again when processing the script.
     // The HTML5 spec is written as though scripts are executed inside the tree
     // builder.  We pause the parser to exit the tree builder, and then resume
     // before running scripts.
     m_isPaused = false;
-    scriptStartLine = m_scriptToProcessStartLine;
-    m_scriptToProcessStartLine = uninitializedLineNumberValue;
+    scriptStartPosition = m_scriptToProcessStartPosition;
+    m_scriptToProcessStartPosition = uninitializedPositionValue1();
     return m_scriptToProcess.release();
 }
 
@@ -2190,7 +2195,7 @@ void HTMLTreeBuilder::processEndTag(AtomicHTMLToken& token)
             m_isPaused = true;
             ASSERT(m_tree.currentElement()->hasTagName(scriptTag));
             m_scriptToProcess = m_tree.currentElement();
-            m_scriptToProcessStartLine = m_lastScriptElementStartLine + 1;
+            m_scriptToProcessStartPosition = WTF::toOneBasedTextPosition(m_lastScriptElementStartPosition);
             m_tree.openElements()->pop();
             if (isParsingFragment() && m_fragmentContext.scriptingPermission() == FragmentScriptingNotAllowed)
                 m_scriptToProcess->removeAllChildren();
@@ -2770,7 +2775,10 @@ void HTMLTreeBuilder::processScriptStartTag(AtomicHTMLToken& token)
     m_tree.insertScriptElement(token);
     m_tokenizer->setState(HTMLTokenizer::ScriptDataState);
     m_originalInsertionMode = m_insertionMode;
-    m_lastScriptElementStartLine = m_tokenizer->lineNumber();
+
+    TextPosition0 position = TextPosition0(WTF::ZeroBasedNumber::fromZeroBasedInt(m_tokenizer->lineNumber()), WTF::ZeroBasedNumber::base());
+    m_lastScriptElementStartPosition = position;
+
     setInsertionMode(TextMode);
 }
 
index c6fcdfd..0e7597c 100644 (file)
@@ -32,6 +32,7 @@
 #include "HTMLElementStack.h"
 #include "HTMLFormattingElementList.h"
 #include "HTMLTokenizer.h"
+#include <wtf/text/TextPosition.h>
 #include <wtf/Noncopyable.h>
 #include <wtf/OwnPtr.h>
 #include <wtf/PassOwnPtr.h>
@@ -71,7 +72,7 @@ public:
     void constructTreeFromAtomicToken(AtomicHTMLToken&);
 
     // Must be called when parser is paused before calling the parser again.
-    PassRefPtr<Element> takeScriptToProcess(int& scriptStartLine);
+    PassRefPtr<Element> takeScriptToProcess(TextPosition1& scriptStartPosition);
 
     // Done, close any open tags, etc.
     void finished();
@@ -248,12 +249,12 @@ private:
     HTMLTokenizer* m_tokenizer;
 
     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.
+    TextPosition1 m_scriptToProcessStartPosition; // 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;
+    TextPosition0 m_lastScriptElementStartPosition;
 
     bool m_usePreHTML5ParserQuirks;
 
index 5f31598..bd541e6 100644 (file)
@@ -1,3 +1,17 @@
+2010-11-10  Peter Rybin  <peter.rybin@gmail.com>
+
+        Reviewed by Adam Barth.
+
+        HTML parser should provide script column position within HTML document to JavaScript engine
+        https://bugs.webkit.org/show_bug.cgi?id=45271
+
+        Replaces script line number with TextPosition structure.
+
+        * src/WebFrameImpl.cpp:
+        (WebKit::WebFrameImpl::executeScript):
+        (WebKit::WebFrameImpl::executeScriptInIsolatedWorld):
+        (WebKit::WebFrameImpl::executeScriptAndReturnValue):
+
 2010-11-09  Kenneth Russell  <kbr@google.com>
 
         Reviewed by James Robinson.
index 41b8321..7dc1515 100644 (file)
@@ -753,8 +753,9 @@ void WebFrameImpl::bindToWindowObject(const WebString& name, NPObject* object)
 
 void WebFrameImpl::executeScript(const WebScriptSource& source)
 {
+    TextPosition1 position(WTF::OneBasedNumber::fromOneBasedInt(source.startLine), WTF::OneBasedNumber::base());
     m_frame->script()->executeScript(
-        ScriptSourceCode(source.code, source.url, source.startLine));
+        ScriptSourceCode(source.code, source.url, position));
 }
 
 void WebFrameImpl::executeScriptInIsolatedWorld(
@@ -764,8 +765,9 @@ void WebFrameImpl::executeScriptInIsolatedWorld(
     Vector<ScriptSourceCode> sources;
 
     for (unsigned i = 0; i < numSources; ++i) {
+        TextPosition1 position(WTF::OneBasedNumber::fromOneBasedInt(sourcesIn[i].startLine), WTF::OneBasedNumber::base());
         sources.append(ScriptSourceCode(
-            sourcesIn[i].code, sourcesIn[i].url, sourcesIn[i].startLine));
+            sourcesIn[i].code, sourcesIn[i].url, position));
     }
 
     m_frame->script()->evaluateInIsolatedWorld(worldId, sources, extensionGroup);
@@ -817,8 +819,9 @@ void WebFrameImpl::collectGarbage()
 v8::Handle<v8::Value> WebFrameImpl::executeScriptAndReturnValue(
     const WebScriptSource& source)
 {
+    TextPosition1 position(WTF::OneBasedNumber::fromOneBasedInt(source.startLine), WTF::OneBasedNumber::base());
     return m_frame->script()->executeScript(
-        ScriptSourceCode(source.code, source.url, source.startLine)).v8Value();
+        ScriptSourceCode(source.code, source.url, position)).v8Value();
 }
 
 // Returns the V8 context for this frame, or an empty handle if there is none.