Changeset 205581 in webkit


Ignore:
Timestamp:
Sep 7, 2016 6:49:49 PM (8 years ago)
Author:
Yusuke Suzuki
Message:

Introduce abstract class LoadableScript for classic script and module graph
https://bugs.webkit.org/show_bug.cgi?id=161674

Reviewed by Ryosuke Niwa.

To prepare for ScriptModuleGraph, we introduce the abstract class over the classic script
and the module script, LoadableScript.

No behavior change.

  • CMakeLists.txt:
  • WebCore.xcodeproj/project.pbxproj:
  • dom/LoadableClassicScript.cpp: Added. LoadableClassicScript is the derived class from the

LoadableScript. In the module patch, we will introduce LoadableScriptModuleGraph which is also
the derived class from the LoadableScript. It is used for the external classic script.
A CachedResourceHandle used here alone does not prevent the underlying CachedResource from purging its
data buffer. This LoadableClassicScript holds a client until this class is destroyed in order to
guarantee that the data buffer will not be purged.
(WebCore::LoadableClassicScript::create):
(WebCore::LoadableClassicScript::LoadableClassicScript):
(WebCore::LoadableClassicScript::~LoadableClassicScript):
(WebCore::LoadableClassicScript::isLoaded):
(WebCore::LoadableClassicScript::wasErrored): Beyond the boolean value, this can return the detail
of the error. This detailed information will be used to report it to the inspector in the ScriptElement.
(WebCore::LoadableClassicScript::wasCanceled):
(WebCore::LoadableClassicScript::notifyFinished): Nosniff and cross-origin loading errors are handled here,
instead of exposing CachedScript*.
(WebCore::LoadableClassicScript::execute): Execute the cached script by using the given ScriptElement.

  • dom/LoadableClassicScript.h: Copied from Source/WebCore/dom/PendingScript.h.

(isType):

  • dom/LoadableScript.cpp: Copied from Source/WebCore/dom/ScriptRunner.h. New wrapper for CachedScript

and ScriptModuleGraph. We introduce a new wrapper to handle the above 2 things in the same way.
We take the way to introduce a new wrapper instead of introducing a new interface that is inherited by
CachedScript and ScriptModuleGraph. This is because ScriptModuleGraph is ref-counted while CachedScript
is managed by CachedResourceHandle. While this patch does not contain ScriptModuleGraph part, this
should be added in the module patch and at that time, this should be managed by this LoadableScript's
subclass. And we introduce TypeCasts traits for LoadableScript to allow is<> and downcast<>.
(WebCore::LoadableScript::addClient):
(WebCore::LoadableScript::removeClient):
(WebCore::LoadableScript::notifyClientFinished):

  • dom/LoadableScript.h: Copied from Source/WebCore/dom/ScriptRunner.h.

(WebCore::LoadableScript::~LoadableScript):
(WebCore::LoadableScript::isClassicScript):
(WebCore::LoadableScript::isModuleGraph):

  • dom/LoadableScriptClient.h: Copied from Source/WebCore/dom/ScriptRunner.h.

(WebCore::LoadableScriptClient::~LoadableScriptClient):

  • dom/PendingScript.cpp: Use LoadableScript instead of CachedScript.

(WebCore::PendingScript::create):
(WebCore::PendingScript::PendingScript):
(WebCore::PendingScript::~PendingScript):
(WebCore::PendingScript::loadableScript):
(WebCore::PendingScript::notifyFinished):
(WebCore::PendingScript::isLoaded):
(WebCore::PendingScript::wasErrored):
(WebCore::PendingScript::cachedScript): Deleted.

  • dom/PendingScript.h:
  • dom/ScriptElement.cpp:

(WebCore::ScriptElement::ScriptElement):
(WebCore::ScriptElement::handleSourceAttribute): Change sourceUrl to sourceURL to be consistent.
(WebCore::ScriptElement::prepareScript):
(WebCore::ScriptElement::requestClassicScript): requestScript is renamed to requestClassicScript.
(WebCore::ScriptElement::requestScriptWithCache): Extract the code requesting the
CachedScript from requestScript. This will also be used by the module fetcher.
(WebCore::ScriptElement::executeScript): Now inspector error reporting is also done in this function.
When an error occurs, LoadableScript::wasErrored() returns the error which may include the information
to report the error to the inspector. nosniff and cross-origin loading errors are now detected by the
LoadableClassicScript and reported through this wasErrored().
(WebCore::ScriptElement::stopLoadRequest):
(WebCore::ScriptElement::executeScriptAndDispatchEvent):
(WebCore::ScriptElement::executeScriptForScriptRunner): Move the code from ScriptRunner. This function
calls removeClient(*this) because ScriptRunner is driven by the ScriptElement's notification. Only when using
ScriptRunner, we call addClient(*this) for ScriptElement. This is tricky, we should refactor this in the separated
bug (https://bugs.webkit.org/show_bug.cgi?id=161726).
(WebCore::ScriptElement::executeScriptForHTMLScriptRunner): Move the code from HTMLScriptRunner.
(WebCore::ScriptElement::notifyFinished):
(WebCore::ScriptElement::requestScript): Deleted.
(WebCore::ScriptElement::execute): Deleted.

  • dom/ScriptElement.h:

(WebCore::ScriptElement::loadableScript):
(WebCore::ScriptElement::cachedScript): Deleted.

  • dom/ScriptRunner.cpp:

(WebCore::ScriptRunner::queueScriptForExecution):
(WebCore::ScriptRunner::timerFired): Use ScriptElement::executeScriptForScriptRunner.

  • dom/ScriptRunner.h:
  • html/parser/HTMLScriptRunner.cpp:

(WebCore::HTMLScriptRunner::executePendingScriptAndDispatchEvent):
(WebCore::requestPendingScript):
(WebCore::HTMLScriptRunner::requestParsingBlockingScript):
(WebCore::HTMLScriptRunner::sourceFromPendingScript): Deleted.

  • html/parser/HTMLScriptRunner.h: Use ScriptElement::executeScriptForHTMLScriptRunner.
  • xml/parser/XMLDocumentParserLibxml2.cpp: Currently, we do nothing about XMLDocument in this patch.

We should support the module script, but before that, we should refactor this pending script handling.
(WebCore::XMLDocumentParser::endElementNs):

Location:
trunk/Source/WebCore
Files:
1 added
12 edited
4 copied

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebCore/CMakeLists.txt

    r205551 r205581  
    14381438    dom/KeyboardEvent.cpp
    14391439    dom/LiveNodeList.cpp
     1440    dom/LoadableClassicScript.cpp
     1441    dom/LoadableScript.cpp
    14401442    dom/MessageChannel.cpp
    14411443    dom/MessageEvent.cpp
  • trunk/Source/WebCore/ChangeLog

    r205580 r205581  
     12016-09-07  Yusuke Suzuki  <utatane.tea@gmail.com>
     2
     3        Introduce abstract class LoadableScript for classic script and module graph
     4        https://bugs.webkit.org/show_bug.cgi?id=161674
     5
     6        Reviewed by Ryosuke Niwa.
     7
     8        To prepare for ScriptModuleGraph, we introduce the abstract class over the classic script
     9        and the module script, LoadableScript.
     10
     11        No behavior change.
     12
     13        * CMakeLists.txt:
     14        * WebCore.xcodeproj/project.pbxproj:
     15        * dom/LoadableClassicScript.cpp: Added. LoadableClassicScript is the derived class from the
     16        LoadableScript. In the module patch, we will introduce LoadableScriptModuleGraph which is also
     17        the derived class from the LoadableScript. It is used for the external classic script.
     18        A CachedResourceHandle used here alone does not prevent the underlying CachedResource from purging its
     19        data buffer. This LoadableClassicScript holds a client until this class is destroyed in order to
     20        guarantee that the data buffer will not be purged.
     21        (WebCore::LoadableClassicScript::create):
     22        (WebCore::LoadableClassicScript::LoadableClassicScript):
     23        (WebCore::LoadableClassicScript::~LoadableClassicScript):
     24        (WebCore::LoadableClassicScript::isLoaded):
     25        (WebCore::LoadableClassicScript::wasErrored): Beyond the boolean value, this can return the detail
     26        of the error. This detailed information will be used to report it to the inspector in the ScriptElement.
     27        (WebCore::LoadableClassicScript::wasCanceled):
     28        (WebCore::LoadableClassicScript::notifyFinished): Nosniff and cross-origin loading errors are handled here,
     29        instead of exposing CachedScript*.
     30        (WebCore::LoadableClassicScript::execute): Execute the cached script by using the given ScriptElement.
     31        * dom/LoadableClassicScript.h: Copied from Source/WebCore/dom/PendingScript.h.
     32        (isType):
     33        * dom/LoadableScript.cpp: Copied from Source/WebCore/dom/ScriptRunner.h. New wrapper for CachedScript
     34        and ScriptModuleGraph. We introduce a new wrapper to handle the above 2 things in the same way.
     35        We take the way to introduce a new wrapper instead of introducing a new interface that is inherited by
     36        CachedScript and ScriptModuleGraph. This is because ScriptModuleGraph is ref-counted while CachedScript
     37        is managed by CachedResourceHandle. While this patch does not contain ScriptModuleGraph part, this
     38        should be added in the module patch and at that time, this should be managed by this LoadableScript's
     39        subclass. And we introduce TypeCasts traits for LoadableScript to allow `is<>` and `downcast<>`.
     40        (WebCore::LoadableScript::addClient):
     41        (WebCore::LoadableScript::removeClient):
     42        (WebCore::LoadableScript::notifyClientFinished):
     43        * dom/LoadableScript.h: Copied from Source/WebCore/dom/ScriptRunner.h.
     44        (WebCore::LoadableScript::~LoadableScript):
     45        (WebCore::LoadableScript::isClassicScript):
     46        (WebCore::LoadableScript::isModuleGraph):
     47        * dom/LoadableScriptClient.h: Copied from Source/WebCore/dom/ScriptRunner.h.
     48        (WebCore::LoadableScriptClient::~LoadableScriptClient):
     49        * dom/PendingScript.cpp: Use LoadableScript instead of CachedScript.
     50        (WebCore::PendingScript::create):
     51        (WebCore::PendingScript::PendingScript):
     52        (WebCore::PendingScript::~PendingScript):
     53        (WebCore::PendingScript::loadableScript):
     54        (WebCore::PendingScript::notifyFinished):
     55        (WebCore::PendingScript::isLoaded):
     56        (WebCore::PendingScript::wasErrored):
     57        (WebCore::PendingScript::cachedScript): Deleted.
     58        * dom/PendingScript.h:
     59        * dom/ScriptElement.cpp:
     60        (WebCore::ScriptElement::ScriptElement):
     61        (WebCore::ScriptElement::handleSourceAttribute): Change sourceUrl to sourceURL to be consistent.
     62        (WebCore::ScriptElement::prepareScript):
     63        (WebCore::ScriptElement::requestClassicScript): requestScript is renamed to requestClassicScript.
     64        (WebCore::ScriptElement::requestScriptWithCache): Extract the code requesting the
     65        CachedScript from requestScript. This will also be used by the module fetcher.
     66        (WebCore::ScriptElement::executeScript): Now inspector error reporting is also done in this function.
     67        When an error occurs, LoadableScript::wasErrored() returns the error which may include the information
     68        to report the error to the inspector. nosniff and cross-origin loading errors are now detected by the
     69        LoadableClassicScript and reported through this wasErrored().
     70        (WebCore::ScriptElement::stopLoadRequest):
     71        (WebCore::ScriptElement::executeScriptAndDispatchEvent):
     72        (WebCore::ScriptElement::executeScriptForScriptRunner): Move the code from ScriptRunner. This function
     73        calls removeClient(*this) because ScriptRunner is driven by the ScriptElement's notification. Only when using
     74        ScriptRunner, we call addClient(*this) for ScriptElement. This is tricky, we should refactor this in the separated
     75        bug (https://bugs.webkit.org/show_bug.cgi?id=161726).
     76        (WebCore::ScriptElement::executeScriptForHTMLScriptRunner): Move the code from HTMLScriptRunner.
     77        (WebCore::ScriptElement::notifyFinished):
     78        (WebCore::ScriptElement::requestScript): Deleted.
     79        (WebCore::ScriptElement::execute): Deleted.
     80        * dom/ScriptElement.h:
     81        (WebCore::ScriptElement::loadableScript):
     82        (WebCore::ScriptElement::cachedScript): Deleted.
     83        * dom/ScriptRunner.cpp:
     84        (WebCore::ScriptRunner::queueScriptForExecution):
     85        (WebCore::ScriptRunner::timerFired): Use ScriptElement::executeScriptForScriptRunner.
     86        * dom/ScriptRunner.h:
     87        * html/parser/HTMLScriptRunner.cpp:
     88        (WebCore::HTMLScriptRunner::executePendingScriptAndDispatchEvent):
     89        (WebCore::requestPendingScript):
     90        (WebCore::HTMLScriptRunner::requestParsingBlockingScript):
     91        (WebCore::HTMLScriptRunner::sourceFromPendingScript): Deleted.
     92        * html/parser/HTMLScriptRunner.h: Use ScriptElement::executeScriptForHTMLScriptRunner.
     93        * xml/parser/XMLDocumentParserLibxml2.cpp: Currently, we do nothing about XMLDocument in this patch.
     94        We should support the module script, but before that, we should refactor this pending script handling.
     95        (WebCore::XMLDocumentParser::endElementNs):
     96
    1972016-09-07  Alex Christensen  <achristensen@webkit.org>
    298
  • trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj

    r205551 r205581  
    61016101                E38838981BAD145F00D62EE3 /* ScriptModuleLoader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E38838941BAD145F00D62EE3 /* ScriptModuleLoader.cpp */; };
    61026102                E38838991BAD145F00D62EE3 /* ScriptModuleLoader.h in Headers */ = {isa = PBXBuildFile; fileRef = E38838951BAD145F00D62EE3 /* ScriptModuleLoader.h */; };
     6103                E3B2F0EB1D7F4C9D00B0C9D1 /* LoadableClassicScript.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E3B2F0E31D7F35EC00B0C9D1 /* LoadableClassicScript.cpp */; };
     6104                E3B2F0EC1D7F4CA100B0C9D1 /* LoadableScript.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E3B2F0E91D7F3D3C00B0C9D1 /* LoadableScript.cpp */; };
     6105                E3B2F0ED1D7F4CA300B0C9D1 /* LoadableScript.h in Headers */ = {isa = PBXBuildFile; fileRef = E3B2F0E71D7F35EC00B0C9D1 /* LoadableScript.h */; settings = {ATTRIBUTES = (Private, ); }; };
     6106                E3B2F0EE1D7F4CA900B0C9D1 /* LoadableScriptClient.h in Headers */ = {isa = PBXBuildFile; fileRef = E3B2F0E81D7F35EC00B0C9D1 /* LoadableScriptClient.h */; settings = {ATTRIBUTES = (Private, ); }; };
     6107                E3B2F0F01D7F4CB500B0C9D1 /* LoadableClassicScript.h in Headers */ = {isa = PBXBuildFile; fileRef = E3B2F0E41D7F35EC00B0C9D1 /* LoadableClassicScript.h */; settings = {ATTRIBUTES = (Private, ); }; };
    61036108                E3FA38641D71812D00AA5950 /* PendingScriptClient.h in Headers */ = {isa = PBXBuildFile; fileRef = E3FA38611D716E7600AA5950 /* PendingScriptClient.h */; };
    61046109                E401C27517CE53EC00C41A35 /* ElementIteratorAssertions.h in Headers */ = {isa = PBXBuildFile; fileRef = E401C27417CE53EC00C41A35 /* ElementIteratorAssertions.h */; settings = {ATTRIBUTES = (Private, ); }; };
     
    1367813683                E38838941BAD145F00D62EE3 /* ScriptModuleLoader.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ScriptModuleLoader.cpp; sourceTree = "<group>"; };
    1367913684                E38838951BAD145F00D62EE3 /* ScriptModuleLoader.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ScriptModuleLoader.h; sourceTree = "<group>"; };
     13685                E3B2F0E31D7F35EC00B0C9D1 /* LoadableClassicScript.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = LoadableClassicScript.cpp; sourceTree = "<group>"; };
     13686                E3B2F0E41D7F35EC00B0C9D1 /* LoadableClassicScript.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LoadableClassicScript.h; sourceTree = "<group>"; };
     13687                E3B2F0E71D7F35EC00B0C9D1 /* LoadableScript.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LoadableScript.h; sourceTree = "<group>"; };
     13688                E3B2F0E81D7F35EC00B0C9D1 /* LoadableScriptClient.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LoadableScriptClient.h; sourceTree = "<group>"; };
     13689                E3B2F0E91D7F3D3C00B0C9D1 /* LoadableScript.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = LoadableScript.cpp; sourceTree = "<group>"; };
    1368013690                E3FA38611D716E7600AA5950 /* PendingScriptClient.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PendingScriptClient.h; sourceTree = "<group>"; };
    1368113691                E401C27417CE53EC00C41A35 /* ElementIteratorAssertions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ElementIteratorAssertions.h; sourceTree = "<group>"; };
     
    2303823048                                BC7FA61E0D1F0CBD00DB22A9 /* LiveNodeList.cpp */,
    2303923049                                BC7FA61F0D1F0CBD00DB22A9 /* LiveNodeList.h */,
     23050                                E3B2F0E31D7F35EC00B0C9D1 /* LoadableClassicScript.cpp */,
     23051                                E3B2F0E41D7F35EC00B0C9D1 /* LoadableClassicScript.h */,
     23052                                E3B2F0E91D7F3D3C00B0C9D1 /* LoadableScript.cpp */,
     23053                                E3B2F0E71D7F35EC00B0C9D1 /* LoadableScript.h */,
     23054                                E3B2F0E81D7F35EC00B0C9D1 /* LoadableScriptClient.h */,
    2304023055                                BC9A6144146859D9006057FD /* make_dom_exceptions.pl */,
    2304123056                                BC9A6145146859D9006057FD /* make_event_factory.pl */,
     
    2494524960                                BC64649811D82349006455B0 /* JSDOMStringMap.h in Headers */,
    2494624961                                7694563D1214D97C0007CBAE /* JSDOMTokenList.h in Headers */,
     24962                                E3B2F0F01D7F4CB500B0C9D1 /* LoadableClassicScript.h in Headers */,
    2494724963                                2E37E00612DBC5A400A6B233 /* JSDOMURL.h in Headers */,
    2494824964                                BC6932740D7E293900AE44D1 /* JSDOMWindowBase.h in Headers */,
     
    2533125347                                B2FA3DF30AB75A6F000E5AC4 /* JSSVGScriptElement.h in Headers */,
    2533225348                                B2FA3DF50AB75A6F000E5AC4 /* JSSVGSetElement.h in Headers */,
     25349                                E3B2F0EE1D7F4CA900B0C9D1 /* LoadableScriptClient.h in Headers */,
    2533325350                                B2FA3DF70AB75A6F000E5AC4 /* JSSVGStopElement.h in Headers */,
    2533425351                                B2FA3DF90AB75A6F000E5AC4 /* JSSVGStringList.h in Headers */,
     
    2694226959                                44A20DB90F84166C00B3E1FE /* WebCoreURLResponseIOS.h in Headers */,
    2694326960                                93F199F008245E59001E9ABC /* WebCoreView.h in Headers */,
     26961                                E3B2F0ED1D7F4CA300B0C9D1 /* LoadableScript.h in Headers */,
    2694426962                                A5E616741894581F009ADF50 /* WebDebuggerAgent.h in Headers */,
    2694526963                                FE0D84E910484348001A179E /* WebEvent.h in Headers */,
     
    2766727685                                26E944D81AC4B2DD007B85B5 /* CombinedURLFilters.cpp in Sources */,
    2766827686                                A584FE341864D5AF00843B10 /* CommandLineAPIHost.cpp in Sources */,
     27687                                E3B2F0EB1D7F4C9D00B0C9D1 /* LoadableClassicScript.cpp in Sources */,
    2766927688                                A584FE2B1863870F00843B10 /* CommandLineAPIModule.cpp in Sources */,
    2767027689                                6550B6A1099DF0270090D781 /* Comment.cpp in Sources */,
     
    2776527784                                BC274B31140EBED800EADFA6 /* CSSBorderImageSliceValue.cpp in Sources */,
    2776627785                                49AE2D8E134EE50C0072920A /* CSSCalculationValue.cpp in Sources */,
     27786                                E3B2F0EC1D7F4CA100B0C9D1 /* LoadableScript.cpp in Sources */,
    2776727787                                BC604A430DB5634E00204739 /* CSSCanvasValue.cpp in Sources */,
    2776827788                                E1EBBBD40AAC9B87001FE8E2 /* CSSCharsetRule.cpp in Sources */,
  • trunk/Source/WebCore/dom/LoadableClassicScript.h

    r205580 r205581  
    11/*
    2  * Copyright (C) 2010 Google, Inc. All Rights Reserved.
     2 * Copyright (C) 2016 Apple, Inc. All Rights Reserved.
    33 *
    44 * Redistribution and use in source and binary forms, with or without
     
    2121 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
    2222 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
    23  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
     23 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
    2424 */
    2525
     
    2828#include "CachedResourceClient.h"
    2929#include "CachedResourceHandle.h"
    30 #include <wtf/Ref.h>
    31 #include <wtf/RefCounted.h>
    32 #include <wtf/text/TextPosition.h>
     30#include "CachedScript.h"
     31#include "LoadableScript.h"
     32#include "LoadableScriptClient.h"
     33#include "SecurityOrigin.h"
     34#include <wtf/TypeCasts.h>
    3335
    3436namespace WebCore {
    3537
    36 class CachedScript;
    37 class Element;
    38 class PendingScriptClient;
     38// A CachedResourceHandle alone does not prevent the underlying CachedResource
     39// from purging its data buffer. This class holds a client until this class is
     40// destroyed in order to guarantee that the data buffer will not be purged.
     41class LoadableClassicScript final : public LoadableScript, private CachedResourceClient {
     42public:
     43    ~LoadableClassicScript();
    3944
    40 // A container for an external script which may be loaded and executed.
    41 //
    42 // A CachedResourceHandle alone does not prevent the underlying CachedResource
    43 // from purging its data buffer. This class holds a dummy client open for its
    44 // lifetime in order to guarantee that the data buffer will not be purged.
    45 class PendingScript final : public RefCounted<PendingScript>, public CachedResourceClient {
    46 public:
    47     static Ref<PendingScript> create(Element&, CachedScript&);
    48     static Ref<PendingScript> create(Element&, TextPosition scriptStartPosition);
     45    static Ref<LoadableClassicScript> create(CachedResourceHandle<CachedScript>&&, const String& crossOriginMode, SecurityOrigin&);
     46    bool isLoaded() const override;
     47    Optional<Error> wasErrored() const override;
     48    bool wasCanceled() const override;
    4949
    50     virtual ~PendingScript();
     50    CachedScript& cachedScript() { return *m_cachedScript; }
     51    bool isClassicScript() const final { return true; }
    5152
    52     TextPosition startingPosition() const { return m_startingPosition; }
    53     void setStartingPosition(const TextPosition& position) { m_startingPosition = position; }
     53    void execute(ScriptElement&) override;
    5454
    55     bool watchingForLoad() const { return needsLoading() && m_client; }
    56 
    57     Element& element() { return m_element.get(); }
    58     const Element& element() const { return m_element.get(); }
    59 
    60     CachedScript* cachedScript() const;
    61     bool needsLoading() const { return cachedScript(); }
    62 
    63     bool isLoaded() const;
     55private:
     56    LoadableClassicScript(CachedResourceHandle<CachedScript>&&, const String& crossOriginMode, SecurityOrigin&);
    6457
    6558    void notifyFinished(CachedResource*) override;
    6659
    67     void setClient(PendingScriptClient*);
    68     void clearClient();
    69 
    70 private:
    71     PendingScript(Element&, CachedScript&);
    72     PendingScript(Element&, TextPosition startingPosition);
    73 
    74     void notifyClientFinished();
    75 
    76     Ref<Element> m_element;
    77     TextPosition m_startingPosition; // Only used for inline script tags.
    7860    CachedResourceHandle<CachedScript> m_cachedScript;
    79     PendingScriptClient* m_client { nullptr };
     61    Ref<SecurityOrigin> m_securityOrigin;
     62    Optional<Error> m_error { Nullopt };
     63    bool m_requestUsesAccessControl;
    8064};
    8165
    8266}
     67
     68SPECIALIZE_TYPE_TRAITS_BEGIN(WebCore::LoadableClassicScript)
     69    static bool isType(const WebCore::LoadableScript& script) { return script.isClassicScript(); }
     70SPECIALIZE_TYPE_TRAITS_END()
  • trunk/Source/WebCore/dom/LoadableScript.cpp

    r205580 r205581  
    11/*
    2  * Copyright (C) 2010 Google, Inc. All Rights Reserved.
     2 * Copyright (C) 2016 Apple, Inc. All Rights Reserved.
    33 *
    44 * Redistribution and use in source and binary forms, with or without
     
    2121 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
    2222 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
    23  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
     23 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
    2424 */
    2525
    26 #ifndef ScriptRunner_h
    27 #define ScriptRunner_h
     26#include "config.h"
     27#include "LoadableScript.h"
    2828
    29 #include "CachedResourceHandle.h"
    30 #include "Timer.h"
    31 #include <wtf/HashMap.h>
    32 #include <wtf/Noncopyable.h>
    33 #include <wtf/Vector.h>
     29#include "LoadableScriptClient.h"
    3430
    3531namespace WebCore {
    3632
    37 class CachedScript;
    38 class Document;
    39 class PendingScript;
    40 class ScriptElement;
     33void LoadableScript::addClient(LoadableScriptClient& client)
     34{
     35    m_clients.add(&client);
     36    if (isLoaded()) {
     37        Ref<LoadableScript> protectedThis(*this);
     38        client.notifyFinished(*this);
     39    }
     40}
    4141
    42 class ScriptRunner {
    43     WTF_MAKE_NONCOPYABLE(ScriptRunner); WTF_MAKE_FAST_ALLOCATED;
    44 public:
    45     explicit ScriptRunner(Document&);
    46     ~ScriptRunner();
     42void LoadableScript::removeClient(LoadableScriptClient& client)
     43{
     44    m_clients.remove(&client);
     45}
    4746
    48     enum ExecutionType { ASYNC_EXECUTION, IN_ORDER_EXECUTION };
    49     void queueScriptForExecution(ScriptElement*, CachedResourceHandle<CachedScript>, ExecutionType);
    50     bool hasPendingScripts() const { return !m_scriptsToExecuteSoon.isEmpty() || !m_scriptsToExecuteInOrder.isEmpty() || !m_pendingAsyncScripts.isEmpty(); }
    51     void suspend();
    52     void resume();
    53     void notifyScriptReady(ScriptElement*, ExecutionType);
     47void LoadableScript::notifyClientFinished()
     48{
     49    RefPtr<LoadableScript> protectedThis(this);
    5450
    55 private:
    56     void timerFired();
    57 
    58     Document& m_document;
    59     Vector<Ref<PendingScript>> m_scriptsToExecuteInOrder;
    60     Vector<RefPtr<PendingScript>> m_scriptsToExecuteSoon; // http://www.whatwg.org/specs/web-apps/current-work/#set-of-scripts-that-will-execute-as-soon-as-possible
    61     HashMap<ScriptElement*, Ref<PendingScript>> m_pendingAsyncScripts;
    62     Timer m_timer;
    63 };
     51    Vector<LoadableScriptClient*> vector;
     52    for (auto& pair : m_clients)
     53        vector.append(pair.key);
     54    for (auto& client : vector)
     55        client->notifyFinished(*this);
     56}
    6457
    6558}
    66 
    67 #endif
  • trunk/Source/WebCore/dom/LoadableScript.h

    r205580 r205581  
    11/*
    2  * Copyright (C) 2010 Google, Inc. All Rights Reserved.
     2 * Copyright (C) 2016 Apple, Inc. All Rights Reserved.
    33 *
    44 * Redistribution and use in source and binary forms, with or without
     
    2121 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
    2222 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
    23  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
     23 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
    2424 */
    2525
    26 #ifndef ScriptRunner_h
    27 #define ScriptRunner_h
     26#pragma once
    2827
    29 #include "CachedResourceHandle.h"
    30 #include "Timer.h"
    31 #include <wtf/HashMap.h>
    32 #include <wtf/Noncopyable.h>
    33 #include <wtf/Vector.h>
     28#include <runtime/ConsoleTypes.h>
     29#include <wtf/HashCountedSet.h>
     30#include <wtf/RefCounted.h>
     31#include <wtf/text/WTFString.h>
    3432
    3533namespace WebCore {
    3634
    37 class CachedScript;
    38 class Document;
    39 class PendingScript;
     35class LoadableScriptClient;
    4036class ScriptElement;
    4137
    42 class ScriptRunner {
    43     WTF_MAKE_NONCOPYABLE(ScriptRunner); WTF_MAKE_FAST_ALLOCATED;
     38class LoadableScript : public RefCounted<LoadableScript> {
    4439public:
    45     explicit ScriptRunner(Document&);
    46     ~ScriptRunner();
     40    enum class ErrorType {
     41        CachedScript,
     42        CrossOriginLoad,
     43        Nosniff,
     44    };
    4745
    48     enum ExecutionType { ASYNC_EXECUTION, IN_ORDER_EXECUTION };
    49     void queueScriptForExecution(ScriptElement*, CachedResourceHandle<CachedScript>, ExecutionType);
    50     bool hasPendingScripts() const { return !m_scriptsToExecuteSoon.isEmpty() || !m_scriptsToExecuteInOrder.isEmpty() || !m_pendingAsyncScripts.isEmpty(); }
    51     void suspend();
    52     void resume();
    53     void notifyScriptReady(ScriptElement*, ExecutionType);
     46    struct ConsoleMessage {
     47        MessageSource source;
     48        MessageLevel level;
     49        String message;
     50    };
     51
     52    struct Error {
     53        ErrorType type;
     54        Optional<ConsoleMessage> consoleMessage;
     55    };
     56
     57    virtual ~LoadableScript() { }
     58
     59    virtual bool isLoaded() const = 0;
     60    virtual Optional<Error> wasErrored() const = 0;
     61    virtual bool wasCanceled() const = 0;
     62
     63    virtual void execute(ScriptElement&) = 0;
     64
     65    void addClient(LoadableScriptClient&);
     66    void removeClient(LoadableScriptClient&);
     67
     68    virtual bool isClassicScript() const { return false; }
     69    virtual bool isModuleGraph() const { return false; }
     70
     71protected:
     72    void notifyClientFinished();
    5473
    5574private:
    56     void timerFired();
    57 
    58     Document& m_document;
    59     Vector<Ref<PendingScript>> m_scriptsToExecuteInOrder;
    60     Vector<RefPtr<PendingScript>> m_scriptsToExecuteSoon; // http://www.whatwg.org/specs/web-apps/current-work/#set-of-scripts-that-will-execute-as-soon-as-possible
    61     HashMap<ScriptElement*, Ref<PendingScript>> m_pendingAsyncScripts;
    62     Timer m_timer;
     75    HashCountedSet<LoadableScriptClient*> m_clients;
    6376};
    6477
    6578}
    66 
    67 #endif
  • trunk/Source/WebCore/dom/LoadableScriptClient.h

    r205580 r205581  
    11/*
    2  * Copyright (C) 2010 Google, Inc. All Rights Reserved.
     2 * Copyright (C) 2016 Apple, Inc. All Rights Reserved.
    33 *
    44 * Redistribution and use in source and binary forms, with or without
     
    2121 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
    2222 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
    23  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
     23 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
    2424 */
    2525
    26 #ifndef ScriptRunner_h
    27 #define ScriptRunner_h
    28 
    29 #include "CachedResourceHandle.h"
    30 #include "Timer.h"
    31 #include <wtf/HashMap.h>
    32 #include <wtf/Noncopyable.h>
    33 #include <wtf/Vector.h>
     26#pragma once
    3427
    3528namespace WebCore {
    3629
    37 class CachedScript;
    38 class Document;
    39 class PendingScript;
    40 class ScriptElement;
     30class LoadableScript;
    4131
    42 class ScriptRunner {
    43     WTF_MAKE_NONCOPYABLE(ScriptRunner); WTF_MAKE_FAST_ALLOCATED;
     32class LoadableScriptClient {
    4433public:
    45     explicit ScriptRunner(Document&);
    46     ~ScriptRunner();
     34    virtual ~LoadableScriptClient() { }
    4735
    48     enum ExecutionType { ASYNC_EXECUTION, IN_ORDER_EXECUTION };
    49     void queueScriptForExecution(ScriptElement*, CachedResourceHandle<CachedScript>, ExecutionType);
    50     bool hasPendingScripts() const { return !m_scriptsToExecuteSoon.isEmpty() || !m_scriptsToExecuteInOrder.isEmpty() || !m_pendingAsyncScripts.isEmpty(); }
    51     void suspend();
    52     void resume();
    53     void notifyScriptReady(ScriptElement*, ExecutionType);
    54 
    55 private:
    56     void timerFired();
    57 
    58     Document& m_document;
    59     Vector<Ref<PendingScript>> m_scriptsToExecuteInOrder;
    60     Vector<RefPtr<PendingScript>> m_scriptsToExecuteSoon; // http://www.whatwg.org/specs/web-apps/current-work/#set-of-scripts-that-will-execute-as-soon-as-possible
    61     HashMap<ScriptElement*, Ref<PendingScript>> m_pendingAsyncScripts;
    62     Timer m_timer;
     36    virtual void notifyFinished(LoadableScript&) = 0;
    6337};
    6438
    6539}
    66 
    67 #endif
  • trunk/Source/WebCore/dom/PendingScript.cpp

    r205218 r205581  
    2727#include "PendingScript.h"
    2828
    29 #include "CachedScript.h"
    3029#include "Element.h"
    3130#include "PendingScriptClient.h"
     
    3332namespace WebCore {
    3433
    35 Ref<PendingScript> PendingScript::create(Element& element, CachedScript& cachedScript)
     34Ref<PendingScript> PendingScript::create(Element& element, LoadableScript& loadableScript)
    3635{
    37     Ref<PendingScript> pendingScript = adoptRef(*new PendingScript(element, cachedScript));
    38     cachedScript.addClient(&pendingScript.get());
     36    Ref<PendingScript> pendingScript = adoptRef(*new PendingScript(element, loadableScript));
     37    loadableScript.addClient(pendingScript.get());
    3938    return pendingScript;
    4039}
     
    5150}
    5251
    53 PendingScript::PendingScript(Element& element, CachedScript& cachedScript)
     52PendingScript::PendingScript(Element& element, LoadableScript& loadableScript)
    5453    : m_element(element)
    55     , m_cachedScript(&cachedScript)
     54    , m_loadableScript(&loadableScript)
    5655{
    5756}
     
    5958PendingScript::~PendingScript()
    6059{
    61     if (m_cachedScript)
    62         m_cachedScript->removeClient(this);
     60    if (m_loadableScript)
     61        m_loadableScript->removeClient(*this);
    6362}
    6463
    65 CachedScript* PendingScript::cachedScript() const
     64LoadableScript* PendingScript::loadableScript() const
    6665{
    67     return m_cachedScript.get();
     66    return m_loadableScript.get();
    6867}
    6968
     
    7574}
    7675
    77 void PendingScript::notifyFinished(CachedResource*)
     76void PendingScript::notifyFinished(LoadableScript&)
    7877{
    7978    notifyClientFinished();
     
    8281bool PendingScript::isLoaded() const
    8382{
    84     return m_cachedScript && m_cachedScript->isLoaded();
     83    return m_loadableScript && m_loadableScript->isLoaded();
     84}
     85
     86bool PendingScript::wasErrored() const
     87{
     88    return m_loadableScript && m_loadableScript->wasErrored();
    8589}
    8690
  • trunk/Source/WebCore/dom/PendingScript.h

    r205218 r205581  
    2626#pragma once
    2727
    28 #include "CachedResourceClient.h"
    29 #include "CachedResourceHandle.h"
     28#include "LoadableScript.h"
     29#include "LoadableScriptClient.h"
    3030#include <wtf/Ref.h>
    3131#include <wtf/RefCounted.h>
     
    3838class PendingScriptClient;
    3939
    40 // A container for an external script which may be loaded and executed.
    41 //
    42 // A CachedResourceHandle alone does not prevent the underlying CachedResource
    43 // from purging its data buffer. This class holds a dummy client open for its
    44 // lifetime in order to guarantee that the data buffer will not be purged.
    45 class PendingScript final : public RefCounted<PendingScript>, public CachedResourceClient {
     40// A container for scripts which may be loaded and executed.
     41// This can hold LoadableScript and non external inline script.
     42class PendingScript final : public RefCounted<PendingScript>, public LoadableScriptClient {
    4643public:
    47     static Ref<PendingScript> create(Element&, CachedScript&);
     44    static Ref<PendingScript> create(Element&, LoadableScript&);
    4845    static Ref<PendingScript> create(Element&, TextPosition scriptStartPosition);
    4946
     
    5855    const Element& element() const { return m_element.get(); }
    5956
    60     CachedScript* cachedScript() const;
    61     bool needsLoading() const { return cachedScript(); }
     57    LoadableScript* loadableScript() const;
     58    bool needsLoading() const { return loadableScript(); }
    6259
    6360    bool isLoaded() const;
     61    bool wasErrored() const;
    6462
    65     void notifyFinished(CachedResource*) override;
     63    void notifyFinished(LoadableScript&) override;
    6664
    6765    void setClient(PendingScriptClient*);
     
    6967
    7068private:
    71     PendingScript(Element&, CachedScript&);
     69    PendingScript(Element&, LoadableScript&);
    7270    PendingScript(Element&, TextPosition startingPosition);
    7371
     
    7674    Ref<Element> m_element;
    7775    TextPosition m_startingPosition; // Only used for inline script tags.
    78     CachedResourceHandle<CachedScript> m_cachedScript;
     76    RefPtr<LoadableScript> m_loadableScript;
    7977    PendingScriptClient* m_client { nullptr };
    8078};
  • trunk/Source/WebCore/dom/ScriptElement.cpp

    r204221 r205581  
    3838#include "HTMLParserIdioms.h"
    3939#include "IgnoreDestructiveWriteCountIncrementer.h"
     40#include "LoadableClassicScript.h"
    4041#include "MIMETypeRegistry.h"
    4142#include "Page.h"
     43#include "PendingScript.h"
    4244#include "SVGNames.h"
    4345#include "SVGScriptElement.h"
     
    6971    , m_forceAsync(!parserInserted)
    7072    , m_willExecuteInOrder(false)
    71     , m_requestUsesAccessControl(false)
    7273{
    7374    if (parserInserted && m_element.document().scriptableDocumentParser() && !m_element.document().isInDocumentWrite())
     
    9798}
    9899
    99 void ScriptElement::handleSourceAttribute(const String& sourceUrl)
    100 {
    101     if (ignoresLoadRequest() || sourceUrl.isEmpty())
     100void ScriptElement::handleSourceAttribute(const String& sourceURL)
     101{
     102    if (ignoresLoadRequest() || sourceURL.isEmpty())
    102103        return;
    103104
     
    228229        m_characterEncoding = document.charset();
    229230
    230     if (hasSourceAttribute())
    231         if (!requestScript(sourceAttributeValue()))
     231    if (hasSourceAttribute()) {
     232        if (!requestClassicScript(sourceAttributeValue()))
    232233            return false;
     234    }
    233235
    234236    if (hasSourceAttribute() && deferAttributeValue() && m_parserInserted && !asyncAttributeValue()) {
     
    241243        m_readyToBeParserExecuted = true;
    242244    } else if (hasSourceAttribute() && !asyncAttributeValue() && !m_forceAsync) {
     245        ASSERT(m_loadableScript);
    243246        m_willExecuteInOrder = true;
    244         document.scriptRunner()->queueScriptForExecution(this, m_cachedScript, ScriptRunner::IN_ORDER_EXECUTION);
    245         m_cachedScript->addClient(this);
     247        document.scriptRunner()->queueScriptForExecution(this, *m_loadableScript, ScriptRunner::IN_ORDER_EXECUTION);
     248        m_loadableScript->addClient(*this);
    246249    } else if (hasSourceAttribute()) {
    247         m_element.document().scriptRunner()->queueScriptForExecution(this, m_cachedScript, ScriptRunner::ASYNC_EXECUTION);
    248         m_cachedScript->addClient(this);
     250        ASSERT(m_loadableScript);
     251        m_element.document().scriptRunner()->queueScriptForExecution(this, *m_loadableScript, ScriptRunner::ASYNC_EXECUTION);
     252        m_loadableScript->addClient(*this);
    249253    } else {
    250254        // Reset line numbering for nested writes.
     
    256260}
    257261
    258 bool ScriptElement::requestScript(const String& sourceUrl)
     262bool ScriptElement::requestClassicScript(const String& sourceURL)
    259263{
    260264    Ref<Document> originalDocument(m_element.document());
    261     if (!m_element.dispatchBeforeLoadEvent(sourceUrl))
    262         return false;
    263     if (!m_element.inDocument() || &m_element.document() != originalDocument.ptr())
    264         return false;
    265 
    266     ASSERT(!m_cachedScript);
    267     if (!stripLeadingAndTrailingHTMLSpaces(sourceUrl).isEmpty()) {
    268         bool hasKnownNonce = m_element.document().contentSecurityPolicy()->allowScriptWithNonce(m_element.attributeWithoutSynchronization(HTMLNames::nonceAttr), m_element.isInUserAgentShadowTree());
    269         ResourceLoaderOptions options = CachedResourceLoader::defaultCachedResourceOptions();
    270         options.contentSecurityPolicyImposition = hasKnownNonce ? ContentSecurityPolicyImposition::SkipPolicyCheck : ContentSecurityPolicyImposition::DoPolicyCheck;
    271 
    272         CachedResourceRequest request(ResourceRequest(m_element.document().completeURL(sourceUrl)), options);
    273 
    274         m_element.document().contentSecurityPolicy()->upgradeInsecureRequestIfNeeded(request.mutableResourceRequest(), ContentSecurityPolicy::InsecureRequestType::Load);
    275 
     265    if (!m_element.dispatchBeforeLoadEvent(sourceURL))
     266        return false;
     267    bool didEventListenerDisconnectThisElement = !m_element.inDocument() || &m_element.document() != originalDocument.ptr();
     268    if (didEventListenerDisconnectThisElement)
     269        return false;
     270
     271    ASSERT(!m_loadableScript);
     272    if (!stripLeadingAndTrailingHTMLSpaces(sourceURL).isEmpty()) {
    276273        String crossOriginMode = m_element.attributeWithoutSynchronization(HTMLNames::crossoriginAttr);
    277         if (!crossOriginMode.isNull()) {
    278             m_requestUsesAccessControl = true;
    279             StoredCredentials allowCredentials = equalLettersIgnoringASCIICase(crossOriginMode, "use-credentials") ? AllowStoredCredentials : DoNotAllowStoredCredentials;
    280             ASSERT(m_element.document().securityOrigin());
    281             updateRequestForAccessControl(request.mutableResourceRequest(), *m_element.document().securityOrigin(), allowCredentials);
     274        auto request = requestScriptWithCache(m_element.document().completeURL(sourceURL), m_element.attributeWithoutSynchronization(HTMLNames::nonceAttr), crossOriginMode);
     275        if (request) {
     276            m_loadableScript = LoadableClassicScript::create(WTFMove(request), crossOriginMode, *m_element.document().securityOrigin());
     277            m_isExternalScript = true;
    282278        }
    283         request.setCharset(scriptCharset());
    284         request.setInitiator(&element());
    285 
    286         m_cachedScript = m_element.document().cachedResourceLoader().requestScript(request);
    287         m_isExternalScript = true;
    288     }
    289 
    290     if (m_cachedScript)
     279    }
     280
     281    if (m_loadableScript)
    291282        return true;
    292283
     
    295286    });
    296287    return false;
     288}
     289
     290CachedResourceHandle<CachedScript> ScriptElement::requestScriptWithCache(const URL& sourceURL, const String& nonceAttribute, const String& crossOriginMode)
     291{
     292    bool hasKnownNonce = m_element.document().contentSecurityPolicy()->allowScriptWithNonce(nonceAttribute, m_element.isInUserAgentShadowTree());
     293    ResourceLoaderOptions options = CachedResourceLoader::defaultCachedResourceOptions();
     294    options.contentSecurityPolicyImposition = hasKnownNonce ? ContentSecurityPolicyImposition::SkipPolicyCheck : ContentSecurityPolicyImposition::DoPolicyCheck;
     295
     296    CachedResourceRequest request(ResourceRequest(sourceURL), options);
     297
     298    m_element.document().contentSecurityPolicy()->upgradeInsecureRequestIfNeeded(request.mutableResourceRequest(), ContentSecurityPolicy::InsecureRequestType::Load);
     299
     300    if (!crossOriginMode.isNull()) {
     301        StoredCredentials allowCredentials = equalLettersIgnoringASCIICase(crossOriginMode, "use-credentials") ? AllowStoredCredentials : DoNotAllowStoredCredentials;
     302        ASSERT(m_element.document().securityOrigin());
     303        updateRequestForAccessControl(request.mutableResourceRequest(), *m_element.document().securityOrigin(), allowCredentials);
     304    }
     305
     306    request.setCharset(scriptCharset());
     307    request.setInitiator(&element());
     308
     309    return m_element.document().cachedResourceLoader().requestScript(request);
    297310}
    298311
     
    312325    }
    313326
    314 #if ENABLE(NOSNIFF)
    315     if (m_isExternalScript && m_cachedScript && !m_cachedScript->mimeTypeAllowedByNosniff()) {
    316         m_element.document().addConsoleMessage(MessageSource::Security, MessageLevel::Error, "Refused to execute script from '" + m_cachedScript->url().stringCenterEllipsizedToLength() + "' because its MIME type ('" + m_cachedScript->mimeType() + "') is not executable, and strict MIME type checking is enabled.");
    317         return;
    318     }
    319 #endif
    320 
    321327    Ref<Document> document(m_element.document());
    322328    if (Frame* frame = document->frame()) {
     
    333339void ScriptElement::stopLoadRequest()
    334340{
    335     if (m_cachedScript) {
     341    if (m_loadableScript) {
    336342        if (!m_willBeParserExecuted)
    337             m_cachedScript->removeClient(this);
    338         m_cachedScript = nullptr;
    339     }
    340 }
    341 
    342 void ScriptElement::execute(CachedScript* cachedScript)
     343            m_loadableScript->removeClient(*this);
     344        m_loadableScript = nullptr;
     345    }
     346}
     347
     348void ScriptElement::executeScriptAndDispatchEvent(LoadableScript& loadableScript)
     349{
     350    if (Optional<LoadableScript::Error> error = loadableScript.wasErrored()) {
     351        if (Optional<LoadableScript::ConsoleMessage> message = error->consoleMessage)
     352            m_element.document().addConsoleMessage(message->source, message->level, message->message);
     353        dispatchErrorEvent();
     354    } else if (!loadableScript.wasCanceled()) {
     355        ASSERT(!loadableScript.wasErrored());
     356        loadableScript.execute(*this);
     357        dispatchLoadEvent();
     358    }
     359}
     360
     361void ScriptElement::executeScriptForScriptRunner(LoadableScript& loadableScript)
    343362{
    344363    ASSERT(!m_willBeParserExecuted);
    345     ASSERT(cachedScript);
    346     if (cachedScript->errorOccurred())
    347         dispatchErrorEvent();
    348     else if (!cachedScript->wasCanceled()) {
    349         executeScript(ScriptSourceCode(cachedScript));
     364    executeScriptAndDispatchEvent(loadableScript);
     365    loadableScript.removeClient(*this);
     366}
     367
     368void ScriptElement::executeScriptForHTMLScriptRunner(PendingScript& pendingScript)
     369{
     370    IgnoreDestructiveWriteCountIncrementer ignoreDestructiveWriteCountIncrementer(&m_element.document());
     371    if (auto* loadableScript = pendingScript.loadableScript())
     372        executeScriptAndDispatchEvent(*loadableScript);
     373    else {
     374        ASSERT(!pendingScript.wasErrored());
     375        executeScript(ScriptSourceCode(scriptContent(), m_element.document().url(), pendingScript.startingPosition()));
    350376        dispatchLoadEvent();
    351377    }
    352     cachedScript->removeClient(this);
    353 }
    354 
    355 void ScriptElement::notifyFinished(CachedResource* resource)
     378}
     379
     380void ScriptElement::notifyFinished(LoadableScript&)
    356381{
    357382    ASSERT(!m_willBeParserExecuted);
    358383
    359     // CachedResource possibly invokes this notifyFinished() more than
     384    // LoadableScript possibly invokes this notifyFinished() more than
    360385    // once because ScriptElement doesn't unsubscribe itself from
    361     // CachedResource here and does it in execute() instead.
    362     // We use m_cachedScript to check if this function is already called.
    363     ASSERT_UNUSED(resource, resource == m_cachedScript);
    364     if (!m_cachedScript)
     386    // LoadableScript here and does it in execute() instead.
     387    // We use m_loadableScript to check if this function is already called.
     388    if (!m_loadableScript)
    365389        return;
    366 
    367     if (m_requestUsesAccessControl && !m_cachedScript->passesSameOriginPolicyCheck(*m_element.document().securityOrigin())) {
    368         dispatchErrorEvent();
    369         static NeverDestroyed<String> consoleMessage(ASCIILiteral("Cross-origin script load denied by Cross-Origin Resource Sharing policy."));
    370         m_element.document().addConsoleMessage(MessageSource::JS, MessageLevel::Error, consoleMessage);
    371         return;
    372     }
    373390
    374391    if (m_willExecuteInOrder)
     
    377394        m_element.document().scriptRunner()->notifyScriptReady(this, ScriptRunner::ASYNC_EXECUTION);
    378395
    379     m_cachedScript = nullptr;
     396    m_loadableScript = nullptr;
    380397}
    381398
  • trunk/Source/WebCore/dom/ScriptElement.h

    r204717 r205581  
    1919 */
    2020
    21 #ifndef ScriptElement_h
    22 #define ScriptElement_h
     21#pragma once
    2322
    2423#include "CachedResourceClient.h"
    2524#include "CachedResourceHandle.h"
     25#include "LoadableScript.h"
     26#include "LoadableScriptClient.h"
    2627#include "Timer.h"
     28#include "URL.h"
    2729#include <wtf/text/TextPosition.h>
    2830#include <wtf/text/WTFString.h>
     
    3335class ContainerNode;
    3436class Element;
     37class PendingScript;
    3538class ScriptElement;
    3639class ScriptSourceCode;
    3740
    38 class ScriptElement : private CachedResourceClient {
     41class ScriptElement : private LoadableScriptClient {
    3942public:
    4043    virtual ~ScriptElement();
     
    4952    WEBCORE_EXPORT String scriptContent() const;
    5053    void executeScript(const ScriptSourceCode&);
    51     void execute(CachedScript*);
     54
     55    void executeScriptForScriptRunner(LoadableScript&);
     56    void executeScriptForHTMLScriptRunner(PendingScript&);
    5257
    5358    // XML parser calls these
     
    5964    bool readyToBeParserExecuted() const { return m_readyToBeParserExecuted; }
    6065    bool willExecuteWhenDocumentFinishedParsing() const { return m_willExecuteWhenDocumentFinishedParsing; }
    61     CachedResourceHandle<CachedScript> cachedScript() { return m_cachedScript; }
     66    LoadableScript* loadableScript() { return m_loadableScript.get(); }
    6267
    6368protected:
     
    7378    void finishedInsertingSubtree();
    7479    void childrenChanged();
    75     void handleSourceAttribute(const String& sourceUrl);
     80    void handleSourceAttribute(const String& sourceURL);
    7681    void handleAsyncAttribute();
    7782
    7883private:
     84    void executeScriptAndDispatchEvent(LoadableScript&);
     85
    7986    // https://html.spec.whatwg.org/multipage/scripting.html#concept-script-type
    8087    enum class ScriptType { Classic, Module };
     
    8390    bool isScriptForEventSupported() const;
    8491
    85     bool requestScript(const String& sourceUrl);
     92    CachedResourceHandle<CachedScript> requestScriptWithCache(const URL&, const String& nonceAttribute, const String& crossoriginAttribute);
     93
     94    bool requestClassicScript(const String& sourceURL);
    8695    void stopLoadRequest();
    8796
    88     void notifyFinished(CachedResource*) override;
     97    void notifyFinished(LoadableScript&) override;
    8998
    9099    virtual String sourceAttributeValue() const = 0;
     
    99108
    100109    Element& m_element;
    101     CachedResourceHandle<CachedScript> m_cachedScript;
    102110    WTF::OrdinalNumber m_startLineNumber;
    103111    bool m_parserInserted : 1;
     
    110118    bool m_forceAsync : 1;
    111119    bool m_willExecuteInOrder : 1;
    112     bool m_requestUsesAccessControl : 1;
    113120    String m_characterEncoding;
    114121    String m_fallbackCharacterEncoding;
     122    RefPtr<LoadableScript> m_loadableScript;
    115123};
    116124
     
    119127
    120128}
    121 
    122 #endif
  • trunk/Source/WebCore/dom/ScriptRunner.cpp

    r205218 r205581  
    2727#include "ScriptRunner.h"
    2828
    29 #include "CachedScript.h"
    3029#include "Element.h"
    3130#include "PendingScript.h"
     
    5049}
    5150
    52 void ScriptRunner::queueScriptForExecution(ScriptElement* scriptElement, CachedResourceHandle<CachedScript> cachedScript, ExecutionType executionType)
     51void ScriptRunner::queueScriptForExecution(ScriptElement* scriptElement, LoadableScript& loadableScript, ExecutionType executionType)
    5352{
    5453    ASSERT(scriptElement);
    55     ASSERT(cachedScript.get());
    5654
    5755    Element& element = scriptElement->element();
     
    6260    switch (executionType) {
    6361    case ASYNC_EXECUTION:
    64         m_pendingAsyncScripts.add(scriptElement, PendingScript::create(element, *cachedScript));
     62        m_pendingAsyncScripts.add(scriptElement, PendingScript::create(element, loadableScript));
    6563        break;
    6664
    6765    case IN_ORDER_EXECUTION:
    68         m_scriptsToExecuteInOrder.append(PendingScript::create(element, *cachedScript));
     66        m_scriptsToExecuteInOrder.append(PendingScript::create(element, loadableScript));
    6967        break;
    7068    }
     
    118116        auto* scriptElement = toScriptElementIfPossible(&script->element());
    119117        ASSERT(scriptElement);
    120         scriptElement->execute(script->cachedScript());
     118        ASSERT(script->needsLoading());
     119        scriptElement->executeScriptForScriptRunner(*script->loadableScript());
    121120        m_document.decrementLoadEventDelayCount();
    122121    }
  • trunk/Source/WebCore/dom/ScriptRunner.h

    r205218 r205581  
    2424 */
    2525
    26 #ifndef ScriptRunner_h
    27 #define ScriptRunner_h
     26#pragma once
    2827
    29 #include "CachedResourceHandle.h"
    3028#include "Timer.h"
    3129#include <wtf/HashMap.h>
     
    3533namespace WebCore {
    3634
    37 class CachedScript;
    3835class Document;
    3936class PendingScript;
    4037class ScriptElement;
     38class LoadableScript;
    4139
    4240class ScriptRunner {
     
    4745
    4846    enum ExecutionType { ASYNC_EXECUTION, IN_ORDER_EXECUTION };
    49     void queueScriptForExecution(ScriptElement*, CachedResourceHandle<CachedScript>, ExecutionType);
     47    void queueScriptForExecution(ScriptElement*, LoadableScript&, ExecutionType);
    5048    bool hasPendingScripts() const { return !m_scriptsToExecuteSoon.isEmpty() || !m_scriptsToExecuteInOrder.isEmpty() || !m_pendingAsyncScripts.isEmpty(); }
    5149    void suspend();
     
    6462
    6563}
    66 
    67 #endif
  • trunk/Source/WebCore/html/parser/HTMLScriptRunner.cpp

    r205218 r205581  
    2727#include "HTMLScriptRunner.h"
    2828
    29 #include "CachedScript.h"
    30 #include "CachedResourceLoader.h"
    3129#include "Element.h"
    3230#include "Event.h"
     
    9088}
    9189
    92 ScriptSourceCode HTMLScriptRunner::sourceFromPendingScript(const PendingScript& script, bool& errorOccurred) const
    93 {
    94     if (script.cachedScript()) {
    95         errorOccurred = script.cachedScript()->errorOccurred();
    96         ASSERT(script.cachedScript()->isLoaded());
    97         return ScriptSourceCode(script.cachedScript());
    98     }
    99     errorOccurred = false;
    100     return ScriptSourceCode(script.element().textContent(), documentURLForScriptExecution(m_document), script.startingPosition());
    101 }
    102 
    10390bool HTMLScriptRunner::isPendingScriptReady(const PendingScript& script)
    10491{
     
    126113void HTMLScriptRunner::executePendingScriptAndDispatchEvent(RefPtr<PendingScript> pendingScript)
    127114{
    128     bool errorOccurred = false;
    129     ScriptSourceCode sourceCode = sourceFromPendingScript(*pendingScript, errorOccurred);
    130 
    131115    // Stop watching loads before executeScript to prevent recursion if the script reloads itself.
    132116    if (pendingScript->watchingForLoad())
     
    138122    if (auto* scriptElement = toScriptElementIfPossible(&pendingScript->element())) {
    139123        NestingLevelIncrementer nestingLevelIncrementer(m_scriptNestingLevel);
    140         IgnoreDestructiveWriteCountIncrementer ignoreDestructiveWriteCountIncrementer(m_document);
    141         if (errorOccurred)
    142             scriptElement->dispatchErrorEvent();
    143         else {
    144             ASSERT(isExecutingScript());
    145             scriptElement->executeScript(sourceCode);
    146             pendingScript->element().dispatchEvent(createScriptLoadEvent());
    147         }
     124        scriptElement->executeScriptForHTMLScriptRunner(*pendingScript);
    148125    }
    149126    ASSERT(!isExecutingScript());
     
    237214    auto& scriptElement = *toScriptElementIfPossible(script);
    238215    ASSERT(scriptElement.willBeParserExecuted());
    239     ASSERT(scriptElement.cachedScript());
    240     return PendingScript::create(*script, *scriptElement.cachedScript());
     216    ASSERT(scriptElement.loadableScript());
     217    return PendingScript::create(*script, *scriptElement.loadableScript());
    241218}
    242219
     
    247224    ASSERT(m_parserBlockingScript->needsLoading());
    248225
    249     // We only care about a load callback if cachedScript is not already
     226    // We only care about a load callback if LoadableScript is not already
    250227    // in the cache. Callers will attempt to run the m_parserBlockingScript
    251228    // if possible before returning control to the parser.
  • trunk/Source/WebCore/html/parser/HTMLScriptRunner.h

    r205218 r205581  
    3333namespace WebCore {
    3434
    35 class CachedResource;
    36 class CachedScript;
    3735class Document;
    3836class Element;
  • trunk/Source/WebCore/xml/parser/XMLDocumentParserLibxml2.cpp

    r205411 r205581  
    4646#include "HTMLStyleElement.h"
    4747#include "HTMLTemplateElement.h"
     48#include "LoadableClassicScript.h"
    4849#include "Page.h"
    4950#include "ProcessingInstruction.h"
     
    921922        if (scriptElement->readyToBeParserExecuted())
    922923            scriptElement->executeScript(ScriptSourceCode(scriptElement->scriptContent(), document()->url(), m_scriptStartPosition));
    923         else if (scriptElement->willBeParserExecuted()) {
    924             m_pendingScript = scriptElement->cachedScript();
     924        else if (scriptElement->willBeParserExecuted() && scriptElement->loadableScript() && is<LoadableClassicScript>(*scriptElement->loadableScript())) {
     925            // FIXME: Allow "module" scripts for XML documents.
     926            // https://bugs.webkit.org/show_bug.cgi?id=161651
     927            m_pendingScript = &downcast<LoadableClassicScript>(*scriptElement->loadableScript()).cachedScript();
    925928            m_scriptElement = &element;
    926929            m_pendingScript->addClient(this);
Note: See TracChangeset for help on using the changeset viewer.