/*
 * Copyright 2015 Google Inc. All Rights Reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

// https://www.w3.org/TR/html5/browsers.html#the-window-object

// Note: Cobalt only supports one browsing context and one Window object.
[PrimaryGlobal]
/*sealed*/ interface Window : EventTarget {
  // the current browsing context
  [Unforgeable] readonly attribute Window window;
  [Replaceable] readonly attribute Window self;
  [Unforgeable] readonly attribute Document document;
  [PutForwards=href, Unforgeable] readonly attribute Location location;
  readonly attribute History history;
  void close();

  // other browsing contexts
  [Replaceable] readonly attribute Window frames;
  [Replaceable] readonly attribute unsigned long length;
  [Unforgeable] readonly attribute Window top;
  readonly attribute Window opener;
  readonly attribute Window parent;
  getter Window (unsigned long index);

  // the user agent
  readonly attribute Navigator navigator;

  // Custom, not in any spec.
  //
  readonly attribute Console console;
  [Conditional=ENABLE_TEST_RUNNER] readonly attribute TestRunner testRunner;
  [CallWith=EnvironmentSettings] void gc();
};
Window implements GlobalEventHandlers;
Window implements WindowEventHandlers;

