chromium/third_party/blink/renderer/bindings/core/v8/window_proxy.h

/*
 * Copyright (C) 2009 Google Inc. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are
 * met:
 *
 *     * Redistributions of source code must retain the above copyright
 * notice, this list of conditions and the following disclaimer.
 *     * Redistributions in binary form must reproduce the above
 * copyright notice, this list of conditions and the following disclaimer
 * in the documentation and/or other materials provided with the
 * distribution.
 *     * Neither the name of Google Inc. nor the names of its
 * contributors may be used to endorse or promote products derived from
 * this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#ifndef THIRD_PARTY_BLINK_RENDERER_BINDINGS_CORE_V8_WINDOW_PROXY_H_
#define THIRD_PARTY_BLINK_RENDERER_BINDINGS_CORE_V8_WINDOW_PROXY_H_

#include "base/dcheck_is_on.h"
#include "base/memory/scoped_refptr.h"
#include "third_party/blink/renderer/core/core_export.h"
#include "third_party/blink/renderer/platform/bindings/dom_wrapper_world.h"
#include "third_party/blink/renderer/platform/bindings/trace_wrapper_v8_reference.h"
#include "third_party/blink/renderer/platform/heap/garbage_collected.h"
#include "v8/include/v8.h"

namespace blink {

class DOMWindow;
class Frame;

// WindowProxy implements the split window model of a window for a frame. In the
// HTML standard, the split window model is composed of the Window interface
// (the inner global object) and the WindowProxy interface (the outer global
// proxy).
//
// The Window interface is backed by the Blink DOMWindow C++ implementation.
// In contrast, the WindowProxy interface does not have a corresponding
// C++ implementation in Blink: the WindowProxy class defined here only manages
// context initialization and detach. Instead, the behavior of the WindowProxy
// interface is defined by JSGlobalProxy in v8 and the prototype chain set up
// during context initialization.
//
// ====== Inner Global Object ======
// The inner global object is the global for the script environment of a Frame.
// Since Window and Document also have a 1:1 relationship, this means that each
// inner global object has an associated Document which does not change. On
// navigation, the new Document receives a new inner global object.
//
// However, there is one exception to the 1:1 DOMWindow:Document rule. If:
// - the previous Document is the initial empty document
// - the new Document is same-origin to the previous Document
// then the inner global object will be reused for the new Document. This is the
// only case where the associated Document of an inner global object can change.
//
// All methods and attributes defined on the Window interface are exposed via
// the inner global object. Global variables defined by script running in the
// Document also live on the inner global object.
//
// ====== Outer Global Proxy ====
// The outer global proxy is reused across navigations. It implements the
// security checks for same-origin/cross-origin access to the Window interface.
// When the check passes (i.e. the access is same-origin), the access is
// forwarded to the inner global object of the active Document in this
// WindowProxy's Frame.
//
// When the security check fails, the access is delegated to the outer global
// proxy's cross-origin interceptors. The cross-origin interceptors may choose
// to return a value (if the property is exposed cross-origin) or throw an
// exception otherwise.
//
// Note that the cross-origin interceptors are only used for cross-origin
// accesses: a same-origin access to a method that is available cross-origin,
// such as Window.postMessage, will be delegated to the inner global object.
//
// ====== LocalWindowProxy vs RemoteWindowProxy ======
// WindowProxy has two concrete subclasses:
// - LocalWindowProxy: implements the split window model for a frame in the same
//   process, i.e. a LocalFrame.
// - RemoteWindowProxy: implements the split window model for a frame in a
//   different process, i.e. a RemoteFrame.
//
// While having a RemoteFrame implies the frame must be cross-origin, the
// opposite is not true: a LocalFrame can be same-origin or cross-origin. One
// additional complexity (which slightly violates the HTML standard): it is
// possible to have SecurityOrigin::CanAccess() return true for a RemoteFrame's
// security origin; however, it is important to still deny access as if the
// frame were cross-origin. This is due to complexities in the process
// allocation model for renderer processes. See https://crbug.com/601629.
//
// ====== LocalWindowProxy ======
// Since a LocalWindowProxy can represent a same-origin or cross-origin frame,
// the entire prototype chain must be available:
//
//   outer global proxy
//     -- has prototype --> inner global object
//     -- has prototype --> Window.prototype
//     -- has prototype --> WindowProperties [1]
//     -- has prototype --> EventTarget.prototype
//     -- has prototype --> Object.prototype
//     -- has prototype --> null
//
// [1] WindowProperties is the named properties object of the Window interface.
//
// ====== RemoteWindowProxy ======
// Since a RemoteWindowProxy only represents a cross-origin frame, it has a much
// simpler prototype chain.
//
//   outer global proxy
//     -- has prototype --> inner global object
//     -- has prototype --> null
//
// Property access to get/set attributes and methods on the outer global proxy
// are redirected through the cross-origin interceptors, since any access will
// fail the security check, by definition.
//
// However, note that method invocations still use the inner global object as
// the receiver object. Blink bindings use v8::Signature to perform a strict
// receiver check, which requires that the FunctionTemplate used to instantiate
// the receiver object matches exactly. However, when creating a new context,
// only inner global object is instantiated using Blink's global template, so by
// definition, it is the only receiver object in the prototype chain that will
// match.
//
//
// ====== References ======
// https://wiki.mozilla.org/Gecko:SplitWindow
// https://whatwg.org/C/browsers.html#the-windowproxy-exotic-object
class CORE_EXPORT WindowProxy : public GarbageCollected<WindowProxy> {};

}  // namespace blink

#endif  // THIRD_PARTY_BLINK_RENDERER_BINDINGS_CORE_V8_WINDOW_PROXY_H_