// Copyright (c) 2012 Intel Corp
// Copyright (c) 2012 The Chromium Authors
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
//  in the Software without restriction, including without limitation the rights
//  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell co
// pies of the Software, and to permit persons to whom the Software is furnished
//  to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in al
// l copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IM
// PLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNES
// S FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS
//  OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WH
// ETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
//  CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

#include "content/nw/src/shell_browser_main_parts.h"

#include "base/bind.h"
#include "base/command_line.h"
#include "base/message_loop.h"
#include "base/string_number_conversions.h"
#include "base/threading/thread_restrictions.h"
#include "base/utf_string_conversions.h"
#include "base/values.h"
#include "content/nw/src/api/app/app.h"
#include "content/nw/src/browser/shell_devtools_delegate.h"
#include "content/nw/src/common/shell_switches.h"
#include "content/nw/src/nw_package.h"
#include "content/nw/src/nw_shell.h"
#include "content/nw/src/shell_browser_context.h"
#include "content/public/common/content_switches.h"
#include "content/public/common/main_function_params.h"
#include "grit/net_resources.h"
#include "net/base/net_module.h"
#include "ui/base/resource/resource_bundle.h"

namespace {

base::StringPiece PlatformResourceProvider(int key) {
  if (key == IDR_DIR_HEADER_HTML) {
    base::StringPiece html_data =
        ui::ResourceBundle::GetSharedInstance().GetRawDataResource(
            IDR_DIR_HEADER_HTML);
    return html_data;
  }
  return base::StringPiece();
}

}  // namespace

namespace content {

ShellBrowserMainParts::ShellBrowserMainParts(
    const MainFunctionParams& parameters)
    : BrowserMainParts(),
      parameters_(parameters),
      run_message_loop_(true),
      devtools_delegate_(NULL) {
}

ShellBrowserMainParts::~ShellBrowserMainParts() {
}

#if !defined(OS_MACOSX)
void ShellBrowserMainParts::PreMainMessageLoopStart() {
}
#endif

void ShellBrowserMainParts::PreMainMessageLoopRun() {
#if !defined(OS_MACOSX)
  Init();
#endif

  if (parameters_.ui_task) {
    parameters_.ui_task->Run();
    delete parameters_.ui_task;
    run_message_loop_ = false;
  }
}

bool ShellBrowserMainParts::MainMessageLoopRun(int* result_code)  {
  return !run_message_loop_;
}

void ShellBrowserMainParts::PostMainMessageLoopRun() {
  if (devtools_delegate_)
    devtools_delegate_->Stop();
  browser_context_.reset();
  off_the_record_browser_context_.reset();
}

void ShellBrowserMainParts::Init() {
  package_.reset(new nw::Package());

  browser_context_.reset(new ShellBrowserContext(false, package()));
  off_the_record_browser_context_.reset(
      new ShellBrowserContext(true, package()));

  // OS X automatically handles multi process issue for us, so we don't need
  // to check for other instances of node-webkit on Mac.
#if !defined(MAC_OSX)
  process_singleton_.reset(new ProcessSingleton(browser_context_->GetPath()));
  ProcessSingleton::NotifyResult result =
      process_singleton_->NotifyOtherProcessOrCreate(
        base::Bind(&ShellBrowserMainParts::ProcessSingletonNotificationCallback,
                   base::Unretained(this)));

  // Quit if the other existing instance want to handle it.
  if (result == ProcessSingleton::PROCESS_NOTIFIED) {
    MessageLoop::current()->PostTask(FROM_HERE, MessageLoop::QuitClosure());
    return;
  }
#endif

  net::NetModule::SetResourceProvider(PlatformResourceProvider);

  int port = 0;
  // See if the user specified a port on the command line (useful for
  // automation). If not, use an ephemeral port by specifying 0.
  CommandLine& command_line = *CommandLine::ForCurrentProcess();
  if (command_line.HasSwitch(switches::kRemoteDebuggingPort)) {
    int temp_port;
    std::string port_str =
        command_line.GetSwitchValueASCII(switches::kRemoteDebuggingPort);
    if (base::StringToInt(port_str, &temp_port) &&
        temp_port > 0 && temp_port < 65535) {
      port = temp_port;
    } else {
      DLOG(WARNING) << "Invalid http debugger port number " << temp_port;
    }
  }
  devtools_delegate_ = new ShellDevToolsDelegate(browser_context_.get(), port);

  Shell::Create(browser_context_.get(),
                package()->GetStartupURL(),
                NULL,
                MSG_ROUTING_NONE,
                NULL);
}

bool ShellBrowserMainParts::ProcessSingletonNotificationCallback(
    const CommandLine& command_line,
    const FilePath& current_directory) {
  if (!package_->self_extract()) {
    // We're in runtime mode, create the new app.
    return false;
  }

  // Don't reuse current instance if 'single-instance' is specified to false.
  bool single_instance;
  if (package_->root()->GetBoolean(switches::kmSingleInstance,
                                   &single_instance) &&
      !single_instance)
    return false;

  CommandLine::StringVector args = command_line.GetArgs();

  // Send open event one by one.
  for (size_t i = 0; i < args.size(); ++i) {
#if defined(OS_WIN)
    api::App::EmitOpenEvent(UTF16ToUTF8(args[i]));
#else
    api::App::EmitOpenEvent(args[i]);
#endif
  }

  return true;
}

}  // namespace content


// Read flags for v8 engine.
ReadJsFlags();

// Copyright (c) 2012 Intel Corp
// Copyright (c) 2012 The Chromium Authors
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
//  in the Software without restriction, including without limitation the rights
//  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell co
// pies of the Software, and to permit persons to whom the Software is furnished
//  to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in al
// l copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IM
// PLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNES
// S FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS
//  OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WH
// ETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
//  CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

#include "content/nw/src/nw_package.h"

#include <vector>

#include "base/command_line.h"
#include "base/file_util.h"
#include "base/files/scoped_temp_dir.h"
#include "base/json/json_file_value_serializer.h"
#include "base/string_split.h"
#include "base/string_util.h"
#include "base/threading/thread_restrictions.h"
#include "base/values.h"
#include "chrome/common/zip.h"
#include "content/nw/src/common/shell_switches.h"
#include "googleurl/src/gurl.h"
#include "grit/nw_resources.h"
#include "net/base/escape.h"
#include "third_party/node/deps/uv/include/uv.h"
#include "ui/base/resource/resource_bundle.h"
#include "ui/gfx/image/image.h"
#include "ui/gfx/image/image_skia_rep.h"
#include "webkit/glue/image_decoder.h"

namespace nw {

namespace {

#ifndef PATH_MAX
#define PATH_MAX MAX_PATH
#endif

bool MakePathAbsolute(FilePath* file_path) {
  DCHECK(file_path);

  FilePath current_directory;
  if (!file_util::GetCurrentDirectory(&current_directory))
    return false;

  if (file_path->IsAbsolute())
    return true;

  if (current_directory.empty())
    return file_util::AbsolutePath(file_path);

  if (!current_directory.IsAbsolute())
    return false;

  *file_path = current_directory.Append(*file_path);
  return true;
}

FilePath GetSelfPath() {
  CommandLine* command_line = CommandLine::ForCurrentProcess();

  FilePath path;

  size_t size = 2*PATH_MAX;
  char* execPath = new char[size];
  if (uv_exepath(execPath, &size) == 0) {
    path = FilePath::FromUTF8Unsafe(std::string(execPath, size));
  } else {
    path = FilePath(command_line->GetProgram());
  }

#if defined(OS_MACOSX)
  // Find if we have node-webkit.app/Resources/app.nw.
  path = path.DirName().DirName().Append("Resources").Append("app.nw");
#endif

  return path;
}

void RelativePathToURI(FilePath root, base::DictionaryValue* manifest) {
  std::string old;
  if (!manifest->GetString(switches::kmMain, &old))
    return;

  // Don't append path if there is already a prefix
  if (MatchPattern(old, "*://*"))
    return;

  FilePath main_path = root.Append(FilePath::FromUTF8Unsafe(old));
  manifest->SetString(switches::kmMain,
                      std::string("file://") + main_path.AsUTF8Unsafe());
}

std::wstring ASCIIToWide(const std::string& ascii) {
  DCHECK(IsStringASCII(ascii)) << ascii;
  return std::wstring(ascii.begin(), ascii.end());
}

}  // namespace

Package::Package()
    : path_(GetSelfPath()),
      self_extract_(true) {
  // First try to extract self.
  if (InitFromPath())
    return;

  // Then see if we have arguments and extract it.
  CommandLine* command_line = CommandLine::ForCurrentProcess();
  const CommandLine::StringVector& args = command_line->GetArgs();
  if (args.size() > 0) {
    self_extract_ = false;
    path_ = FilePath(args[0]);
  } else {
    // Try to load from the folder where the exe resides.
    // Note: self_extract_ is true here, otherwise a 'Invalid Package' error
    // would be triggered.
    path_ = GetSelfPath().DirName();
#if defined(OS_MACOSX)
    path_ = path_.DirName().DirName().DirName();
#endif
  }
  if (InitFromPath())
    return;

  // Finally we init with default settings.
  self_extract_ = false;
  InitWithDefault();
}

Package::Package(FilePath path)
    : path_(path),
      self_extract_(false) {
  if (!InitFromPath())
    InitWithDefault();
}

Package::~Package() {
}

FilePath Package::ConvertToAbsoutePath(const FilePath& path) {
  if (path.IsAbsolute())
    return path;

  return this->path().Append(path);
}

bool Package::GetImage(const FilePath& icon_path, gfx::Image* image) {
  FilePath path = ConvertToAbsoutePath(icon_path);

  // Read the file from disk.
  std::string file_contents;
  if (path.empty() || !file_util::ReadFileToString(path, &file_contents))
    return false;

  // Decode the bitmap using WebKit's image decoder.
  const unsigned char* data =
      reinterpret_cast<const unsigned char*>(file_contents.data());
  webkit_glue::ImageDecoder decoder;
  scoped_ptr<SkBitmap> decoded(new SkBitmap());
  // Note: This class only decodes bitmaps from extension resources. Chrome
  // doesn't (for security reasons) directly load extension resources provided
  // by the extension author, but instead decodes them in a separate
  // locked-down utility process. Only if the decoding succeeds is the image
  // saved from memory to disk and subsequently used in the Chrome UI.
  // Chrome is therefore decoding bitmaps here that were generated by Chrome.
  *decoded = decoder.Decode(data, file_contents.length());
  if (decoded->empty())
    return false;  // Unable to decode.

  *image = gfx::Image(*decoded.release());
  return true;
}

GURL Package::GetStartupURL() {
  std::string url;
  // Specify URL in --url
  CommandLine* command_line = CommandLine::ForCurrentProcess();
  if (command_line->HasSwitch(switches::kUrl)) {
    url = command_line->GetSwitchValueASCII(switches::kUrl);
    GURL gurl(url);
    if (!gurl.has_scheme())
      return GURL(std::string("http://") + url);

    return gurl;
  }

  // Report if encountered errors.
  if (!error_page_url_.empty())
    return GURL(error_page_url_);

  // Read from manifest.
  if (root()->GetString(switches::kmMain, &url))
    return GURL(url);
  else
    return GURL("nw:blank");
}

std::string Package::GetName() {
  std::string name("node-webkit");
  root()->GetString(switches::kmName, &name);
  return name;
}

bool Package::GetUseNode() {
  bool use_node = true;
  root()->GetBoolean(switches::kmNodejs, &use_node);
  return use_node;
}

base::DictionaryValue* Package::window() {
  base::DictionaryValue* window;
  root()->GetDictionaryWithoutPathExpansion(switches::kmWindow, &window);
  return window;
}

bool Package::InitFromPath() {
  base::ThreadRestrictions::SetIOAllowed(true);

  if (!ExtractPath())
    return false;

  // path_/package.json
  FilePath manifest_path = path_.AppendASCII("package.json");
  if (!file_util::PathExists(manifest_path)) {
    if (!self_extract())
      ReportError("Invalid package",
                  "There is no 'package.json' in the package, please make "
                  "sure the 'package.json' is in the root of the package.");
    return false;
  }

  // Parse file.
  std::string error;
  JSONFileValueSerializer serializer(manifest_path);
  scoped_ptr<Value> root(serializer.Deserialize(NULL, &error));
  if (!root.get()) {
    ReportError("Unable to parse package.json",
                error.empty() ?
                    "Failed to read the manifest file: " +
                        manifest_path.AsUTF8Unsafe() :
                    error);
    return false;
  } else if (!root->IsType(Value::TYPE_DICTIONARY)) {
    ReportError("Invalid package.json",
                "package.json's content should be a object type.");
    return false;
  }

  // Save result in global
  root_.reset(static_cast<DictionaryValue*>(root.release()));

  // Check fields
  const char* required_fields[] = {
    switches::kmMain,
    switches::kmName
  };
  for (unsigned i = 0; i < arraysize(required_fields); i++)
    if (!root_->HasKey(required_fields[i])) {
      ReportError("Invalid package.json",
                  std::string("Field '") + required_fields[i] + "'"
                      " is required.");
      return false;
    }

  // Force window field no empty.
  if (!root_->HasKey(switches::kmWindow)) {
    base::DictionaryValue* window = new base::DictionaryValue();
    window->SetString(switches::kmPosition, "center");
    root_->Set(switches::kmWindow, window);
  }

  // Read chromium command line args.
  ReadChromiumArgs();

  RelativePathToURI(path_, this->root());
  return true;
}

void Package::InitWithDefault() {
  root_.reset(new base::DictionaryValue());
  root()->SetString(switches::kmName, "node-webkit");
  root()->SetString(switches::kmMain, "nw:blank");
  base::DictionaryValue* window = new base::DictionaryValue();
  root()->Set(switches::kmWindow, window);

  // Hide toolbar if specifed in the command line.
  if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kNoToolbar))
    window->SetBoolean(switches::kmToolbar, false);

  // Window should show in center by default.
  window->SetString(switches::kmPosition, "center");
}

bool Package::ExtractPath() {
  // Convert to absoulute path.
  if (!MakePathAbsolute(&path_)) {
    ReportError("Cannot extract package",
                "Path is invalid: " + path_.AsUTF8Unsafe());
    return false;
  }

  // Read symbolic link.
#if defined(OS_POSIX)
  FilePath target;
  if (file_util::ReadSymbolicLink(path_, &target))
    path_ = target;
#endif

  // If it's a file then try to extract from it.
  if (!file_util::DirectoryExists(path_)) {
    FilePath extracted_path;
    if (ExtractPackage(path_, &extracted_path)) {
      path_ = extracted_path;
    } else if (!self_extract()) {
      ReportError("Cannot extract package",
                  "Failed to unzip the package file: " + path_.AsUTF8Unsafe());
      return false;
    }
  }

  return true;
}

bool Package::ExtractPackage(const FilePath& zip_file, FilePath* where) {
  // Auto clean our temporary directory
  static scoped_ptr<base::ScopedTempDir> scoped_temp_dir;

#if defined(OS_WIN)
  if (!file_util::CreateNewTempDirectory(L"nw", where)) {
#else
  if (!file_util::CreateNewTempDirectory("nw", where)) {
#endif
    ReportError("Cannot extract package",
                "Unable to create temporary directory.");
    return false;
  }

  scoped_temp_dir.reset(new base::ScopedTempDir());
  if (!scoped_temp_dir->Set(*where)) {
    ReportError("Cannot extract package",
                "Unable to set temporary directory.");
    return false;
  }

  return zip::Unzip(zip_file, *where);
}

void Package::ReadChromiumArgs() {
  if (!root()->HasKey(switches::kmChromiumArgs))
    return;

  std::string args;
  if (!root()->GetStringASCII(switches::kmChromiumArgs, &args))
    return;

  std::vector<std::string> chromium_args;
  base::SplitString(args, ' ', &chromium_args);

  CommandLine* command_line = CommandLine::ForCurrentProcess();

  for (unsigned i = 0; i < chromium_args.size(); ++i) {
    CommandLine::StringType key, value;
#if defined(OS_WIN)
    // Note:: On Windows, the |CommandLine::StringType| will be |std::wstring|,
    // so the chromium_args[i] is not compatible. We convert the wstring to
    // string here is safe beacuse we use ASCII only.
    if (!IsSwitch(ASCIIToWide(chromium_args[i]), &key, &value))
      continue;
    command_line->AppendSwitchASCII(WideToASCII(key),
                                    WideToASCII(value));
#else
    if (!IsSwitch(chromium_args[i], &key, &value))
      continue;
    command_line->AppendSwitchASCII(key, value);
#endif
  }
}

void Package::ReportError(const std::string& title,
                          const std::string& content) {
  if (!error_page_url_.empty())
    return;

  const base::StringPiece template_html(
      ResourceBundle::GetSharedInstance().GetRawDataResource(
          IDR_NW_PACKAGE_ERROR));

  if (template_html.empty()) {
    // Print hand written error info if nw.pak doesn't exist.
    NOTREACHED() << "Unable to load error template.";
    error_page_url_ = "data:text/html;base64,VW5hYmxlIHRvIGZpbmQgbncucGFrLgo=";
    return;
  }

  std::vector<std::string> subst;
  subst.push_back(title);
  subst.push_back(content);
  error_page_url_ = "data:text/html;charset=utf-8," +
      net::EscapeQueryParamValue(
          ReplaceStringPlaceholders(template_html, subst, NULL), false);
}

}  // namespace nw


/**
 * Module dependencies.
 */

var Base = require('./node_modules/mocha/lib/reporters/base.js')
  , cursor = Base.cursor
  , color = Base.color;

/**
 * Expose `JSON`.
 */

exports = module.exports = JSONReporter;

/**
 * Initialize a new `JSON` reporter.
 *
 * @param {Runner} runner
 * @api public
 */

function JSONReporter(runner) {
  var self = this;
  Base.call(this, runner);

  var tests = []
    , failures = []
    , passes = [];

  runner.on('test end', function(test){
    tests.push(test);
  });

  runner.on('pass', function(test){
    passes.push(test);
  });

  runner.on('fail', function(test){
    failures.push(test);
  });

  runner.on('end', function(){
    var obj = {
        stats: self.stats
      , tests: tests.map(clean)
      , failures: failures.map(clean)
      , passes: passes.map(clean)
    };

    process.stdout.write(JSON.stringify(obj));
  });
}

/**
 * Return a plain-object representation of `test`
 * free of cyclic properties etc.
 *
 * @param {Object} test
 * @return {Object}
 * @api private
 */

function clean(test) {
  return {
      title: test.title
    , fullTitle: test.fullTitle()
    , duration: test.duration
  }
}


// Copyright (c) 2012 Intel Corp
// Copyright (c) 2012 The Chromium Authors
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
//  in the Software without restriction, including without limitation the rights
//  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell co
// pies of the Software, and to permit persons to whom the Software is furnished
//  to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in al
// l copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IM
// PLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNES
// S FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS
//  OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WH
// ETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
//  CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

#include "content/nw/src/api/menu/menu_delegate_win.h"

#include "base/logging.h"
#include "base/string16.h"
#include "content/nw/src/api/dispatcher_host.h"
#include "content/nw/src/api/menuitem/menuitem.h"

namespace api {

MenuDelegate::MenuDelegate(DispatcherHost* dispatcher_host)
    : dispatcher_host_(dispatcher_host) {
}

MenuDelegate::~MenuDelegate() {
}

bool MenuDelegate::IsCommandIdChecked(int command_id) const {
  if (command_id < 0)
    return false;

  MenuItem* item = dispatcher_host_->GetApiObject<MenuItem>(command_id);
  return item->is_checked_;
}

bool MenuDelegate::IsCommandIdEnabled(int command_id) const {
  if (command_id < 0)
    return false;

  MenuItem* item = dispatcher_host_->GetApiObject<MenuItem>(command_id);
  return item->is_enabled_;
}

bool MenuDelegate::IsItemForCommandIdDynamic(int command_id) const {
  if (command_id < 0)
    return false;

  MenuItem* item = dispatcher_host_->GetApiObject<MenuItem>(command_id);
  return item->is_modified_;
}

string16 MenuDelegate::GetLabelForCommandId(int command_id) const {
  MenuItem* item = dispatcher_host_->GetApiObject<MenuItem>(command_id);
  return item->label_;
}

bool MenuDelegate::GetIconForCommandId(int command_id,
                                       gfx::Image* icon) const {
  MenuItem* item = dispatcher_host_->GetApiObject<MenuItem>(command_id);
  if (item->icon_.IsEmpty())
    return false;

  *icon = item->icon_;
  return true;
}

void MenuDelegate::ExecuteCommand(int command_id) {
  if (command_id < 0)
    return;

  MenuItem* item = dispatcher_host_->GetApiObject<MenuItem>(command_id);
  item->OnClick();
}

bool MenuDelegate::HasIcon(int command_id) {
  if (command_id < 0)
    return false;

  MenuItem* item = dispatcher_host_->GetApiObject<MenuItem>(command_id);
  return !item->icon_.IsEmpty();
}

}  // namespace api


// Copyright (c) 2012 Intel Corp
// Copyright (c) 2012 The Chromium Authors
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
//  in the Software without restriction, including without limitation the rights
//  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell co
// pies of the Software, and to permit persons to whom the Software is furnished
//  to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in al
// l copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IM
// PLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNES
// S FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS
//  OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WH
// ETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
//  CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

#include "content/nw/src/browser/shell_resource_context.h"

#include "content/nw/src/net/shell_url_request_context_getter.h"

namespace content {

ShellResourceContext::ShellResourceContext(
    ShellURLRequestContextGetter* getter)
    : getter_(getter) {
}

ShellResourceContext::~ShellResourceContext() {
}

net::HostResolver* ShellResourceContext::GetHostResolver() {
  return getter_->host_resolver();
}

net::URLRequestContext* ShellResourceContext::GetRequestContext() {
  return getter_->GetURLRequestContext();
}

}  // namespace content


base::SplitString(args, ' ', &chromium_args);

CommandLine* command_line = CommandLine::ForCurrentProcess();

for (unsigned i = 0; i < chromium_args.size(); ++i) {

keep keep keep replace keep keep keep keep


// Copyright (c) 2012 Intel Corp
// Copyright (c) 2012 The Chromium Authors
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
//  in the Software without restriction, including without limitation the rights
//  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell co
// pies of the Software, and to permit persons to whom the Software is furnished
//  to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in al
// l copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IM
// PLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNES
// S FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS
//  OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WH
// ETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
//  CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

#include "content/nw/src/api/menu/menu.h"

#include "base/values.h"
#include "content/nw/src/api/dispatcher_host.h"
#include "content/nw/src/api/menuitem/menuitem.h"
#include "content/nw/src/nw_shell.h"

namespace api {

Menu::Menu(int id,
           DispatcherHost* dispatcher_host,
           const base::DictionaryValue& option)
    : Base(id, dispatcher_host, option) {
  Create(option);
}

Menu::~Menu() {
  Destroy();
}

void Menu::Call(const std::string& method,
                const base::ListValue& arguments) {
  if (method == "Append") {
    int object_id = 0;
    arguments.GetInteger(0, &object_id);
    Append(dispatcher_host()->GetApiObject<MenuItem>(object_id));
  } else if (method == "Insert") {
    int object_id = 0;
    arguments.GetInteger(0, &object_id);
    int pos = 0;
    arguments.GetInteger(1, &pos);
    Insert(dispatcher_host()->GetApiObject<MenuItem>(object_id), pos);
  } else if (method == "Remove") {
    int object_id = 0;
    arguments.GetInteger(0, &object_id);
    int pos = 0;
    arguments.GetInteger(1, &pos);
    Remove(dispatcher_host()->GetApiObject<MenuItem>(object_id), pos);
  } else if (method == "Popup") {
    int x = 0;
    arguments.GetInteger(0, &x);
    int y = 0;
    arguments.GetInteger(1, &y);
    Popup(x, y, content::Shell::FromRenderViewHost(
          dispatcher_host()->render_view_host()));
  } else {
    NOTREACHED() << "Invalid call to Menu method:" << method
                 << " arguments:" << arguments;
  }
}

}  // namespace api


// Copyright (c) 2012 Intel Corp
// Copyright (c) 2012 The Chromium Authors
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
//  in the Software without restriction, including without limitation the rights
//  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell co
// pies of the Software, and to permit persons to whom the Software is furnished
//  to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in al
// l copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IM
// PLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNES
// S FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS
//  OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WH
// ETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
//  CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

#include "content/nw/src/api/menuitem/menuitem.h"

#include "base/file_path.h"
#include "base/utf_string_conversions.h"
#include "base/values.h"
#include "content/nw/src/api/dispatcher_host.h"
#include "content/nw/src/api/menu/menu.h"
#include "content/nw/src/nw_package.h"
#include "content/nw/src/nw_shell.h"

namespace api {

void MenuItem::Create(const base::DictionaryValue& option) {
  is_modified_ = false;
  is_checked_ = false;
  is_enabled_ = true;
  type_ = "normal";
  submenu_ = NULL;

  option.GetString("type", &type_);
  option.GetString("label", &label_);
  option.GetString("tooltip", &tooltip_);
  option.GetBoolean("checked", &is_checked_);
  option.GetBoolean("enabled", &is_enabled_);

  std::string icon;
  if (option.GetString("icon", &icon) && !icon.empty())
    SetIcon(icon);

  int menu_id;
  if (option.GetInteger("submenu", &menu_id))
    SetSubmenu(dispatcher_host()->GetApiObject<Menu>(menu_id));
}

void MenuItem::Destroy() {
}

void MenuItem::OnClick() {
  // Automatically flip checkbox.
  if (type_ == "checkbox")
    is_checked_ = !is_checked_;

  // Send event.
  base::ListValue args;
  dispatcher_host()->SendEvent(this, "click", args);
}

void MenuItem::SetLabel(const std::string& label) {
  is_modified_ = true;
  label_ = UTF8ToUTF16(label);
}

void MenuItem::SetIcon(const std::string& icon) {
  is_modified_ = true;
  if (icon.empty()) {
    icon_ = gfx::Image();
    return;
  }

  content::Shell* shell = content::Shell::FromRenderViewHost(
      dispatcher_host()->render_view_host());
  nw::Package* package = shell->GetPackage();
  package->GetImage(FilePath::FromUTF8Unsafe(icon), &icon_);
}

void MenuItem::SetTooltip(const std::string& tooltip) {
  tooltip_ = UTF8ToUTF16(tooltip);
}

void MenuItem::SetEnabled(bool enabled) {
  is_enabled_ = enabled;
}

void MenuItem::SetChecked(bool checked) {
  is_checked_ = checked;
}

void MenuItem::SetSubmenu(Menu* menu) {
  submenu_ = menu;
}

}  // namespace api


<?xml version="1.0" encoding="UTF-8"?>
<archive type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="7.10">
  <data>
    <int key="IBDocument.SystemTarget">1060</int>
    <string key="IBDocument.SystemVersion">11D50b</string>
    <string key="IBDocument.InterfaceBuilderVersion">851</string>
    <string key="IBDocument.AppKitVersion">1138.32</string>
    <string key="IBDocument.HIToolboxVersion">568.00</string>
    <object class="NSMutableDictionary" key="IBDocument.PluginVersions">
      <string key="NS.key.0">com.apple.InterfaceBuilder.CocoaPlugin</string>
      <string key="NS.object.0">851</string>
    </object>
    <object class="NSMutableArray" key="IBDocument.EditedObjectIDs">
      <bool key="EncodedWithXMLCoder">YES</bool>
      <integer value="1"/>
    </object>
    <object class="NSArray" key="IBDocument.PluginDependencies">
      <bool key="EncodedWithXMLCoder">YES</bool>
      <string>com.apple.InterfaceBuilder.CocoaPlugin</string>
    </object>
    <object class="NSMutableDictionary" key="IBDocument.Metadata">
      <bool key="EncodedWithXMLCoder">YES</bool>
      <object class="NSArray" key="dict.sortedKeys" id="0">
        <bool key="EncodedWithXMLCoder">YES</bool>
      </object>
      <object class="NSMutableArray" key="dict.values">
        <bool key="EncodedWithXMLCoder">YES</bool>
      </object>
    </object>
    <object class="NSMutableArray" key="IBDocument.RootObjects" id="1000">
      <bool key="EncodedWithXMLCoder">YES</bool>
      <object class="NSCustomObject" id="1001">
        <string key="NSClassName">NSObject</string>
      </object>
      <object class="NSCustomObject" id="1003">
        <string key="NSClassName">FirstResponder</string>
      </object>
      <object class="NSCustomObject" id="1004">
        <string key="NSClassName">NSApplication</string>
      </object>
      <object class="NSCustomView" id="1005">
        <reference key="NSNextResponder"/>
        <int key="NSvFlags">268</int>
        <object class="NSMutableArray" key="NSSubviews">
          <bool key="EncodedWithXMLCoder">YES</bool>
          <object class="NSSecureTextField" id="870871897">
            <reference key="NSNextResponder" ref="1005"/>
            <int key="NSvFlags">268</int>
            <string key="NSFrame">{{99, 20}, {156, 22}}</string>
            <reference key="NSSuperview" ref="1005"/>
            <string key="NSReuseIdentifierKey">_NS:3407</string>
            <int key="NSTag">2</int>
            <bool key="NSEnabled">YES</bool>
            <object class="NSSecureTextFieldCell" key="NSCell" id="789371868">
              <int key="NSCellFlags">343014976</int>
              <int key="NSCellFlags2">272630848</int>
              <string key="NSContents"/>
              <object class="NSFont" key="NSSupport" id="749592131">
                <string key="NSName">LucidaGrande</string>
                <double key="NSSize">13</double>
                <int key="NSfFlags">1040</int>
              </object>
              <string key="NSCellIdentifier">_NS:3407</string>
              <reference key="NSControlView" ref="870871897"/>
              <bool key="NSDrawsBackground">YES</bool>
              <object class="NSColor" key="NSBackgroundColor" id="359621337">
                <int key="NSColorSpace">6</int>
                <string key="NSCatalogName">System</string>
                <string key="NSColorName">textBackgroundColor</string>
                <object class="NSColor" key="NSColor">
                  <int key="NSColorSpace">3</int>
                  <bytes key="NSWhite">MQA</bytes>
                </object>
              </object>
              <object class="NSColor" key="NSTextColor" id="1064189586">
                <int key="NSColorSpace">6</int>
                <string key="NSCatalogName">System</string>
                <string key="NSColorName">textColor</string>
                <object class="NSColor" key="NSColor" id="976070126">
                  <int key="NSColorSpace">3</int>
                  <bytes key="NSWhite">MAA</bytes>
                </object>
              </object>
              <object class="NSArray" key="NSAllowedInputLocales">
                <bool key="EncodedWithXMLCoder">YES</bool>
                <string>NSAllRomanInputSourcesLocaleIdentifier</string>
              </object>
            </object>
          </object>
          <object class="NSTextField" id="249141654">
            <reference key="NSNextResponder" ref="1005"/>
            <int key="NSvFlags">268</int>
            <string key="NSFrame">{{99, 52}, {156, 22}}</string>
            <reference key="NSSuperview" ref="1005"/>
            <string key="NSReuseIdentifierKey">_NS:817</string>
            <int key="NSTag">1</int>
            <bool key="NSEnabled">YES</bool>
            <object class="NSTextFieldCell" key="NSCell" id="270667430">
              <int key="NSCellFlags">-1804468671</int>
              <int key="NSCellFlags2">272630784</int>
              <string key="NSContents"/>
              <reference key="NSSupport" ref="749592131"/>
              <string key="NSCellIdentifier">_NS:817</string>
              <reference key="NSControlView" ref="249141654"/>
              <bool key="NSDrawsBackground">YES</bool>
              <reference key="NSBackgroundColor" ref="359621337"/>
              <reference key="NSTextColor" ref="1064189586"/>
            </object>
          </object>
          <object class="NSTextField" id="298854538">
            <reference key="NSNextResponder" ref="1005"/>
            <int key="NSvFlags">268</int>
            <string key="NSFrame">{{17, 22}, {77, 17}}</string>
            <reference key="NSSuperview" ref="1005"/>
            <string key="NSReuseIdentifierKey">_NS:4068</string>
            <bool key="NSEnabled">YES</bool>
            <object class="NSTextFieldCell" key="NSCell" id="212881775">
              <int key="NSCellFlags">68288064</int>
              <int key="NSCellFlags2">71304192</int>
              <string key="NSContents">Password:</string>
              <reference key="NSSupport" ref="749592131"/>
              <string key="NSCellIdentifier">_NS:4068</string>
              <reference key="NSControlView" ref="298854538"/>
              <object class="NSColor" key="NSBackgroundColor" id="818604237">
                <int key="NSColorSpace">6</int>
                <string key="NSCatalogName">System</string>
                <string key="NSColorName">controlColor</string>
                <object class="NSColor" key="NSColor">
                  <int key="NSColorSpace">3</int>
                  <bytes key="NSWhite">MC42NjY2NjY2NjY3AA</bytes>
                </object>
              </object>
              <object class="NSColor" key="NSTextColor" id="1040089286">
                <int key="NSColorSpace">6</int>
                <string key="NSCatalogName">System</string>
                <string key="NSColorName">controlTextColor</string>
                <reference key="NSColor" ref="976070126"/>
              </object>
            </object>
          </object>
          <object class="NSTextField" id="881326141">
            <reference key="NSNextResponder" ref="1005"/>
            <int key="NSvFlags">268</int>
            <string key="NSFrame">{{17, 54}, {77, 17}}</string>
            <reference key="NSSuperview" ref="1005"/>
            <string key="NSReuseIdentifierKey">_NS:4068</string>
            <bool key="NSEnabled">YES</bool>
            <object class="NSTextFieldCell" key="NSCell" id="509864529">
              <int key="NSCellFlags">68288064</int>
              <int key="NSCellFlags2">71304192</int>
              <string key="NSContents">Username:</string>
              <reference key="NSSupport" ref="749592131"/>
              <string key="NSCellIdentifier">_NS:4068</string>
              <reference key="NSControlView" ref="881326141"/>
              <reference key="NSBackgroundColor" ref="818604237"/>
              <reference key="NSTextColor" ref="1040089286"/>
            </object>
          </object>
        </object>
        <string key="NSFrameSize">{275, 94}</string>
        <reference key="NSSuperview"/>
        <string key="NSClassName">NSView</string>
      </object>
    </object>
    <object class="IBObjectContainer" key="IBDocument.Objects">
      <object class="NSMutableArray" key="connectionRecords">
        <bool key="EncodedWithXMLCoder">YES</bool>
      </object>
      <object class="IBMutableOrderedSet" key="objectRecords">
        <object class="NSArray" key="orderedObjects">
          <bool key="EncodedWithXMLCoder">YES</bool>
          <object class="IBObjectRecord">
            <int key="objectID">0</int>
            <reference key="object" ref="0"/>
            <reference key="children" ref="1000"/>
            <nil key="parent"/>
          </object>
          <object class="IBObjectRecord">
            <int key="objectID">-2</int>
            <reference key="object" ref="1001"/>
            <reference key="parent" ref="0"/>
            <string key="objectName">File's Owner</string>
          </object>
          <object class="IBObjectRecord">
            <int key="objectID">-1</int>
            <reference key="object" ref="1003"/>
            <reference key="parent" ref="0"/>
            <string key="objectName">First Responder</string>
          </object>
          <object class="IBObjectRecord">
            <int key="objectID">-3</int>
            <reference key="object" ref="1004"/>
            <reference key="parent" ref="0"/>
            <string key="objectName">Application</string>
          </object>
          <object class="IBObjectRecord">
            <int key="objectID">1</int>
            <reference key="object" ref="1005"/>
            <object class="NSMutableArray" key="children">
              <bool key="EncodedWithXMLCoder">YES</bool>
              <reference ref="249141654"/>
              <reference ref="870871897"/>
              <reference ref="298854538"/>
              <reference ref="881326141"/>
            </object>
            <reference key="parent" ref="0"/>
          </object>
          <object class="IBObjectRecord">
            <int key="objectID">2</int>
            <reference key="object" ref="881326141"/>
            <object class="NSMutableArray" key="children">
              <bool key="EncodedWithXMLCoder">YES</bool>
              <reference ref="509864529"/>
            </object>
            <reference key="parent" ref="1005"/>
          </object>
          <object class="IBObjectRecord">
            <int key="objectID">3</int>
            <reference key="object" ref="509864529"/>
            <reference key="parent" ref="881326141"/>
          </object>
          <object class="IBObjectRecord">
            <int key="objectID">4</int>
            <reference key="object" ref="298854538"/>
            <object class="NSMutableArray" key="children">
              <bool key="EncodedWithXMLCoder">YES</bool>
              <reference ref="212881775"/>
            </object>
            <reference key="parent" ref="1005"/>
          </object>
          <object class="IBObjectRecord">
            <int key="objectID">5</int>
            <reference key="object" ref="212881775"/>
            <reference key="parent" ref="298854538"/>
          </object>
          <object class="IBObjectRecord">
            <int key="objectID">6</int>
            <reference key="object" ref="249141654"/>
            <object class="NSMutableArray" key="children">
              <bool key="EncodedWithXMLCoder">YES</bool>
              <reference ref="270667430"/>
            </object>
            <reference key="parent" ref="1005"/>
          </object>
          <object class="IBObjectRecord">
            <int key="objectID">7</int>
            <reference key="object" ref="270667430"/>
            <reference key="parent" ref="249141654"/>
          </object>
          <object class="IBObjectRecord">
            <int key="objectID">8</int>
            <reference key="object" ref="870871897"/>
            <object class="NSMutableArray" key="children">
              <bool key="EncodedWithXMLCoder">YES</bool>
              <reference ref="789371868"/>
            </object>
            <reference key="parent" ref="1005"/>
          </object>
          <object class="IBObjectRecord">
            <int key="objectID">9</int>
            <reference key="object" ref="789371868"/>
            <reference key="parent" ref="870871897"/>
          </object>
        </object>
      </object>
      <object class="NSMutableDictionary" key="flattenedProperties">
        <bool key="EncodedWithXMLCoder">YES</bool>
        <object class="NSArray" key="dict.sortedKeys">
          <bool key="EncodedWithXMLCoder">YES</bool>
          <string>-1.IBPluginDependency</string>
          <string>-2.IBPluginDependency</string>
          <string>-3.IBPluginDependency</string>
          <string>1.IBEditorWindowLastContentRect</string>
          <string>1.IBPluginDependency</string>
          <string>1.WindowOrigin</string>
          <string>1.editorWindowContentRectSynchronizationRect</string>
          <string>2.IBPluginDependency</string>
          <string>2.IBViewBoundsToFrameTransform</string>
          <string>3.IBPluginDependency</string>
          <string>4.IBPluginDependency</string>
          <string>4.IBViewBoundsToFrameTransform</string>
          <string>5.IBPluginDependency</string>
          <string>6.IBPluginDependency</string>
          <string>6.IBViewBoundsToFrameTransform</string>
          <string>7.IBPluginDependency</string>
          <string>8.IBPluginDependency</string>
          <string>8.IBViewBoundsToFrameTransform</string>
          <string>9.IBPluginDependency</string>
        </object>
        <object class="NSMutableArray" key="dict.values">
          <bool key="EncodedWithXMLCoder">YES</bool>
          <string>com.apple.InterfaceBuilder.CocoaPlugin</string>
          <string>com.apple.InterfaceBuilder.CocoaPlugin</string>
          <string>com.apple.InterfaceBuilder.CocoaPlugin</string>
          <string>{{969, 1048}, {275, 94}}</string>
          <string>com.apple.InterfaceBuilder.CocoaPlugin</string>
          <string>{628, 654}</string>
          <string>{{357, 416}, {480, 272}}</string>
          <string>com.apple.InterfaceBuilder.CocoaPlugin</string>
          <object class="NSAffineTransform">
            <bytes key="NSTransformStruct">P4AAAL+AAABBiAAAwpAAAA</bytes>
          </object>
          <string>com.apple.InterfaceBuilder.CocoaPlugin</string>
          <string>com.apple.InterfaceBuilder.CocoaPlugin</string>
          <object class="NSAffineTransform">
            <bytes key="NSTransformStruct">P4AAAL+AAABBiAAAwiAAAA</bytes>
          </object>
          <string>com.apple.InterfaceBuilder.CocoaPlugin</string>
          <string>com.apple.InterfaceBuilder.CocoaPlugin</string>
          <object class="NSAffineTransform">
            <bytes key="NSTransformStruct">P4AAAL+AAABCxgAAwpAAAA</bytes>
          </object>
          <string>com.apple.InterfaceBuilder.CocoaPlugin</string>
          <string>com.apple.InterfaceBuilder.CocoaPlugin</string>
          <object class="NSAffineTransform">
            <bytes key="NSTransformStruct">P4AAAL+AAABCxgAAwiAAAA</bytes>
          </object>
          <string>com.apple.InterfaceBuilder.CocoaPlugin</string>
        </object>
      </object>
      <object class="NSMutableDictionary" key="unlocalizedProperties">
        <bool key="EncodedWithXMLCoder">YES</bool>
        <reference key="dict.sortedKeys" ref="0"/>
        <object class="NSMutableArray" key="dict.values">
          <bool key="EncodedWithXMLCoder">YES</bool>
        </object>
      </object>
      <nil key="activeLocalization"/>
      <object class="NSMutableDictionary" key="localizations">
        <bool key="EncodedWithXMLCoder">YES</bool>
        <reference key="dict.sortedKeys" ref="0"/>
        <object class="NSMutableArray" key="dict.values">
          <bool key="EncodedWithXMLCoder">YES</bool>
        </object>
      </object>
      <nil key="sourceID"/>
      <int key="maxID">9</int>
    </object>
    <object class="IBClassDescriber" key="IBDocument.Classes"/>
    <int key="IBDocument.localizationMode">0</int>
    <string key="IBDocument.TargetRuntimeIdentifier">IBCocoaFramework</string>
    <object class="NSMutableDictionary" key="IBDocument.PluginDeclaredDevelopmentDependencies">
      <string key="NS.key.0">com.apple.InterfaceBuilder.CocoaPlugin.InterfaceBuilder3</string>
      <integer value="3000" key="NS.object.0"/>
    </object>
    <bool key="IBDocument.PluginDeclaredDependenciesTrackSystemTargetVersion">YES</bool>
    <nil key="IBDocument.LastKnownRelativeProjectPath"/>
    <int key="IBDocument.defaultPropertyAccessControl">3</int>
  </data>
</archive>


void Package::ReportError(const std::string& title,

keep keep keep keep add keep keep keep keep keep

CommandLine* command_line = CommandLine::ForCurrentProcess();

// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

// Defines all the "content_shell" command-line switches.

#ifndef CONTENT_NW_SRC_SHELL_SWITCHES_H_
#define CONTENT_NW_SRC_SHELL_SWITCHES_H_

namespace switches {

extern const char kContentShellDataPath[];
extern const char kDeveloper[];
extern const char kNoToolbar[];
extern const char kUrl[];
extern const char kWorkingDirectory[];
extern const char kNodeMain[];

// Manifest settings
extern const char kmMain[];
extern const char kmName[];
extern const char kmWebkit[];
extern const char kmNodejs[];
extern const char kmWindow[];
extern const char kmChromiumArgs[];

extern const char kmSingleInstance[];

extern const char kmTitle[];
extern const char kmToolbar[];
extern const char kmIcon[];
extern const char kmFrame[];
extern const char kmShow[];
extern const char kmPosition[];
extern const char kmX[];
extern const char kmY[];
extern const char kmWidth[];
extern const char kmHeight[];
extern const char kmMinWidth[];
extern const char kmMinHeight[];
extern const char kmMaxWidth[];
extern const char kmMaxHeight[];
extern const char kmResizable[];
extern const char kmAsDesktop[];
extern const char kmFullscreen[];
extern const char kmKiosk[];
extern const char kmAlwaysOnTop[];

extern const char kmWebgl[];
extern const char kmJava[];
extern const char kmPlugin[];
extern const char kmPageCache[];
extern const char kmUserAgent[];
extern const char kmRemotePages[];
extern const char kmNewInstance[];
}  // namespace switches

#endif  // CONTENT_NW_SRC_SHELL_SWITCHES_H_


// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef CONTENT_SHELL_GEOLOCATION_SHELL_ACCESS_TOKEN_STORE_H_
#define CONTENT_SHELL_GEOLOCATION_SHELL_ACCESS_TOKEN_STORE_H_

#include "content/public/browser/access_token_store.h"

// Dummy access token store used to initialise the network location provider.
class ShellAccessTokenStore : public content::AccessTokenStore {
 public:
  explicit ShellAccessTokenStore(net::URLRequestContextGetter* request_context);

 private:
  virtual ~ShellAccessTokenStore();

  // AccessTokenStore
  virtual void LoadAccessTokens(
      const LoadAccessTokensCallbackType& callback) OVERRIDE;

  virtual void SaveAccessToken(
      const GURL& server_url, const string16& access_token) OVERRIDE;

  static void DidLoadAccessTokens(
      net::URLRequestContextGetter* request_context,
      const LoadAccessTokensCallbackType& callback);

  net::URLRequestContextGetter* request_context_;

  DISALLOW_COPY_AND_ASSIGN(ShellAccessTokenStore);
};

#endif  // CONTENT_SHELL_GEOLOCATION_SHELL_ACCESS_TOKEN_STORE_H_


// Copyright (c) 2012 Intel Corp
// Copyright (c) 2012 The Chromium Authors
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
//  in the Software without restriction, including without limitation the rights
//  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell co
// pies of the Software, and to permit persons to whom the Software is furnished
//  to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in al
// l copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IM
// PLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNES
// S FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS
//  OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WH
// ETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
//  CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

#ifndef CONTENT_NW_SRC_API_MENU_MENU_H_
#define CONTENT_NW_SRC_API_MENU_MENU_H_

#include "base/compiler_specific.h"
#include "base/memory/scoped_ptr.h"
#include "content/nw/src/api/base/base.h"

#include <string>
#include <vector>

#if defined(OS_MACOSX)
#if __OBJC__
@class NSMenu;
#else
class NSMenu;
#endif  // __OBJC__

namespace nw {
class NativeWindowCocoa;
}
#elif defined(TOOLKIT_GTK)
#include <gtk/gtk.h>

namespace nw {
class NativeWindowGtk;
}
#elif defined(OS_WIN)
#include "content/nw/src/api/menu/menu_delegate_win.h"
#include "ui/views/controls/menu/native_menu_win.h"

namespace nw {
class NativeWindowWin;
}

namespace ui {

// A derived class to override |HasIcons| to prevent the |NativeMenuWin| from
// being a owner-draw control.
// Note: this method maybe confused when the menuitem has an icon. I always
// return |false| here, and set the icon by using |SetMenuItemBitmaps|.
class NwMenuModel : public SimpleMenuModel {
 public:
  NwMenuModel(Delegate* delegate);

  // Overridden from MenuModel:
  virtual bool HasIcons() const OVERRIDE;
};

} // namespace ui

#endif

namespace content {
class Shell;
}

namespace api {

class MenuItem;

class Menu : public Base {
 public:
  Menu(int id,
       DispatcherHost* dispatcher_host,
       const base::DictionaryValue& option);
  virtual ~Menu();

  virtual void Call(const std::string& method,
                    const base::ListValue& arguments) OVERRIDE;

 private:
  friend class MenuItem;
  friend class Tray;

  // Platform-independent implementations
  void Create(const base::DictionaryValue& option);
  void Destroy();
  void Append(MenuItem* menu_item);
  void Insert(MenuItem* menu_item, int pos);
  void Remove(MenuItem* menu_item, int pos);
  void Popup(int x, int y, content::Shell*);

#if defined(OS_MACOSX)
  friend class nw::NativeWindowCocoa;
  NSMenu* menu_;
#elif defined(TOOLKIT_GTK)
  friend class nw::NativeWindowGtk;
  GtkWidget* menu_;
#elif defined(OS_WIN)
  friend class nw::NativeWindowWin;

  void Rebuild(const gfx::NativeMenu *parent_menu = NULL);

  // Flag to indicate the menu has been modified since last show, so we should
  // rebuild the menu before next show.
  bool is_menu_modified_;

  scoped_ptr<MenuDelegate> menu_delegate_;
  scoped_ptr<ui::NwMenuModel> menu_model_;
  scoped_ptr<views::NativeMenuWin> menu_;

  // A container for the handles of the icon bitmap.
  std::vector<HBITMAP> icon_bitmaps_;
#endif

  DISALLOW_COPY_AND_ASSIGN(Menu);
};

}  // namespace api

#endif  // CONTENT_NW_SRC_API_MENU_MENU_H_


// Copyright (c) 2012 Intel Corp
// Copyright (c) 2012 The Chromium Authors
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
//  in the Software without restriction, including without limitation the rights
//  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell co
// pies of the Software, and to permit persons to whom the Software is furnished
//  to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in al
// l copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IM
// PLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNES
// S FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS
//  OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WH
// ETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
//  CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

var argv, fullArgv;

function App() {
}
require('util').inherits(App, exports.Base);

App.filteredArgv = [
  /--no-toolbar/,
  /--url=.*/,
  /--remote-debugging-port=.*/,
  /--renderer-cmd-prefix.*/,
];

App.prototype.quit = function() {
  nw.callStaticMethod('App', 'Quit', [ ]);
}

App.prototype.closeAllWindows = function() {
  nw.callStaticMethod('App', 'CloseAllWindows', [ ]);
}

App.prototype.__defineGetter__('argv', function() {
  if (!argv) {
    var fullArgv = this.fullArgv;
    argv = [];
    for (var i = 0; i < fullArgv.length; ++i) {
      var matched = false;
      for (var j = 0; j < App.filteredArgv.length; ++j) {
        if (App.filteredArgv[j].test(fullArgv[i])) {
          matched = true;
          break;;
        }
      }
      if (matched)
        continue;

      argv.push(fullArgv[i]);
    }
  }

  return argv;
});

App.prototype.__defineGetter__('fullArgv', function() {
  if (!fullArgv)
    fullArgv = nw.callStaticMethodSync('App', 'GetArgv', [ ]);

  return fullArgv;
});

// Store App object in node's context.
if (process['_nw_app']) {
  exports.App = process['_nw_app'];
} else {
  exports.App = process['_nw_app'] = new App();
}


// Read js flags from the package.json if specifed.

// Copyright (c) 2012 Intel Corp
// Copyright (c) 2012 The Chromium Authors
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
//  in the Software without restriction, including without limitation the rights
//  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell co
// pies of the Software, and to permit persons to whom the Software is furnished
//  to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in al
// l copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IM
// PLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNES
// S FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS
//  OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WH
// ETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
//  CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

#ifndef CONTENT_NW_SRC_NW_PACKAGE_H
#define CONTENT_NW_SRC_NW_PACKAGE_H

#include "base/basictypes.h"
#include "base/file_path.h"
#include "base/memory/scoped_ptr.h"

#include <string>

class GURL;

namespace base {
class DictionaryValue;
}

namespace gfx {
class Image;
}

namespace nw {

class Package {
 public:
  // Init package from command line parameters.
  Package();

  // Init package from specifed path.
  Package(FilePath path);
  ~Package();

  // Convert path to absoulte path.
  FilePath ConvertToAbsoutePath(const FilePath& path);

  // Get image from icon path.
  bool GetImage(const FilePath& path, gfx::Image* image);

  // Get startup url.
  GURL GetStartupURL();

  // Get app's name.
  std::string GetName();

  // Return if we enable node.js.
  bool GetUseNode();

  // Root path of package.
  FilePath path() const { return path_; }

  // If the package is extracting itself.
  bool self_extract() const { return self_extract_; }

  // Manifest root.
  base::DictionaryValue* root() { return root_.get(); }

  // Window field of manifest.
  base::DictionaryValue* window();

 private:
  bool InitFromPath();
  void InitWithDefault();
  bool ExtractPath();
  bool ExtractPackage(const FilePath& zip_file, FilePath* where);

  // Read chromium command line args from the package.json if specifed.
  void ReadChromiumArgs();

  // Convert error info into data url.
  void ReportError(const std::string& title, const std::string& content);

  // Root path of the package.
  FilePath path_;

  // Is it a standalone and self-extractable app?
  bool self_extract_;

  // The parsed package.json.
  scoped_ptr<base::DictionaryValue> root_;

  // Stored url for error page.
  std::string error_page_url_;

  DISALLOW_COPY_AND_ASSIGN(Package);
};

}  // namespae nw

#endif  // CONTENT_NW_SRC_NW_PACKAGE_H


// Copyright (c) 2012 Intel Corp
// Copyright (c) 2012 The Chromium Authors
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
//  in the Software without restriction, including without limitation the rights
//  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell co
// pies of the Software, and to permit persons to whom the Software is furnished
//  to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in al
// l copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IM
// PLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNES
// S FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS
//  OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WH
// ETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
//  CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

#include "content/nw/src/api/base/base.h"

#include "base/logging.h"
#include "base/values.h"

namespace api {

Base::Base(int id,
           DispatcherHost* dispatcher_host,
           const base::DictionaryValue& option)
    : id_(id),
      dispatcher_host_(dispatcher_host) {
}

Base::~Base() {
}

void Base::Call(const std::string& method, const base::ListValue& arguments) {
  NOTREACHED() << "Uncatched call in Base"
               << " method:" << method
               << " arguments:" << arguments;
}

void Base::CallSync(const std::string& method,
                    const base::ListValue& arguments,
                    base::ListValue* result) {
  NOTREACHED() << "Uncatched callAsync in Base"
               << " method:" << method
               << " arguments:" << arguments;
}

}  // namespace api


// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "content/nw/src/media/media_stream_devices_controller.h"

#include "base/values.h"
#include "content/nw/src/media/media_capture_devices_dispatcher.h"
#include "content/nw/src/media/media_internals.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/common/media_stream_request.h"

using content::BrowserThread;

namespace {

bool HasAnyAvailableDevice() {
  MediaCaptureDevicesDispatcher* dispatcher =
      MediaInternals::GetInstance()->GetMediaCaptureDevicesDispatcher();
  const content::MediaStreamDevices& audio_devices =
      dispatcher->GetAudioCaptureDevices();
  const content::MediaStreamDevices& video_devices =
      dispatcher->GetVideoCaptureDevices();

  return !audio_devices.empty() || !video_devices.empty();
};

const char kAudioKey[] = "audio";
const char kVideoKey[] = "video";

}  // namespace

MediaStreamDevicesController::MediaStreamDevicesController(
    const content::MediaStreamRequest& request,
    const content::MediaResponseCallback& callback)
    :
      request_(request),
      callback_(callback),
      has_audio_(content::IsAudioMediaType(request.audio_type) &&
                 !IsAudioDeviceBlockedByPolicy()),
      has_video_(content::IsVideoMediaType(request.video_type) &&
                 !IsVideoDeviceBlockedByPolicy()) {
}

MediaStreamDevicesController::~MediaStreamDevicesController() {}

#if 0
// static
void MediaStreamDevicesController::RegisterUserPrefs(
    PrefServiceSyncable* prefs) {
  prefs->RegisterBooleanPref(prefs::kVideoCaptureAllowed,
                             true,
                             PrefServiceSyncable::UNSYNCABLE_PREF);
  prefs->RegisterBooleanPref(prefs::kAudioCaptureAllowed,
                             true,
                             PrefServiceSyncable::UNSYNCABLE_PREF);
}
#endif

bool MediaStreamDevicesController::DismissInfoBarAndTakeActionOnSettings() {
  // If this is a no UI check for policies only go straight to accept - policy
  // check will be done automatically on the way.
  if (request_.request_type == content::MEDIA_OPEN_DEVICE) {
    Accept(false);
    return true;
  }

  if (request_.audio_type == content::MEDIA_TAB_AUDIO_CAPTURE ||
      request_.video_type == content::MEDIA_TAB_VIDEO_CAPTURE) {
    HandleTapMediaRequest();
    return true;
  }

#if 0
  // Deny the request if the security origin is empty, this happens with
  // file access without |--allow-file-access-from-files| flag.
  if (request_.security_origin.is_empty()) {
    Deny(false);
    return true;
  }
#endif
  // Deny the request if there is no device attached to the OS.
  if (!HasAnyAvailableDevice()) {
    Deny(false);
    return true;
  }

  // Check if any allow exception has been made for this request.
  if (IsRequestAllowedByDefault()) {
    Accept(false);
    return true;
  }
#if 0
  // Check if any block exception has been made for this request.
  if (IsRequestBlockedByDefault()) {
    Deny(false);
    return true;
  }

  // Check if the media default setting is set to block.
  if (IsDefaultMediaAccessBlocked()) {
    Deny(false);
    return true;
  }
#endif
  // Don't show the infobar.
  return true;
}

const std::string& MediaStreamDevicesController::GetSecurityOriginSpec() const {
  return request_.security_origin.spec();
}

void MediaStreamDevicesController::Accept(bool update_content_setting) {
  // Get the default devices for the request.
  content::MediaStreamDevices devices;
  media::GetDefaultDevicesForProfile(
                                     has_audio_,
                                     has_video_,
                                     &devices);

  callback_.Run(devices);
}

void MediaStreamDevicesController::Deny(bool update_content_setting) {
  callback_.Run(content::MediaStreamDevices());
}

bool MediaStreamDevicesController::IsAudioDeviceBlockedByPolicy() const {
  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
  return false;
}

bool MediaStreamDevicesController::IsVideoDeviceBlockedByPolicy() const {
  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
  return false;
}

bool MediaStreamDevicesController::IsRequestAllowedByDefault() const {
  return true;
}

bool MediaStreamDevicesController::IsRequestBlockedByDefault() const {
  return false;
}

bool MediaStreamDevicesController::IsDefaultMediaAccessBlocked() const {
  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
  return false;
}

void MediaStreamDevicesController::HandleTapMediaRequest() {
  content::MediaStreamDevices devices;

  if (request_.audio_type == content::MEDIA_TAB_AUDIO_CAPTURE) {
    devices.push_back(content::MediaStreamDevice(
          content::MEDIA_TAB_VIDEO_CAPTURE, "", ""));
  }
  if (request_.video_type == content::MEDIA_TAB_VIDEO_CAPTURE) {
    devices.push_back(content::MediaStreamDevice(
          content::MEDIA_TAB_AUDIO_CAPTURE, "", ""));
  }

  callback_.Run(devices);
}

bool MediaStreamDevicesController::IsSchemeSecure() const {
  return (request_.security_origin.SchemeIsSecure());
}

bool MediaStreamDevicesController::ShouldAlwaysAllowOrigin() const {
  return true;
}


// Copyright (c) 2012 Intel Corp
// Copyright (c) 2012 The Chromium Authors
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
//  in the Software without restriction, including without limitation the rights
//  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell co
// pies of the Software, and to permit persons to whom the Software is furnished
//  to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in al
// l copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IM
// PLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNES
// S FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS
//  OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WH
// ETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
//  CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

#include "content/nw/src/api/menu/menu.h"

#include "base/logging.h"
#include "base/values.h"
#include "content/nw/src/api/menuitem/menuitem.h"
#include "content/nw/src/nw_shell.h"
#include "content/public/browser/web_contents.h"
#include "content/public/browser/render_widget_host_view.h"
#include "ui/gfx/point.h"

namespace api {

namespace {

// Popup menus may get squished if they open up too close to the bottom of the
// screen. This function takes the size of the screen, the size of the menu,
// an optional widget, the Y position of the mouse click, and adjusts the popup
// menu's Y position to make it fit if it's possible to do so.
// Returns the new Y position of the popup menu.
int CalculateMenuYPosition(const GdkRectangle* screen_rect,
                           const GtkRequisition* menu_req,
                           GtkWidget* widget, const int y) {
  CHECK(screen_rect);
  CHECK(menu_req);
  // If the menu would run off the bottom of the screen, and there is enough
  // screen space upwards to accommodate the menu, then pop upwards. If there
  // is a widget, then also move the anchor point to the top of the widget
  // rather than the bottom.
  const int screen_top = screen_rect->y;
  const int screen_bottom = screen_rect->y + screen_rect->height;
  const int menu_bottom = y + menu_req->height;
  int alternate_y = y - menu_req->height;
  if (widget) {
    GtkAllocation allocation;
    gtk_widget_get_allocation(widget, &allocation);
    alternate_y -= allocation.height;
  }
  if (menu_bottom >= screen_bottom && alternate_y >= screen_top)
    return alternate_y;
  return y;
}

void PointMenuPositionFunc(GtkMenu* menu,
                           int* x,
                           int* y,
                           gboolean* push_in,
                           gpointer userdata) {
  *push_in = TRUE;

  gfx::Point* point = reinterpret_cast<gfx::Point*>(userdata);
  *x = point->x();
  *y = point->y();

  GtkRequisition menu_req;
  gtk_widget_size_request(GTK_WIDGET(menu), &menu_req);
  GdkScreen* screen;
  gdk_display_get_pointer(gdk_display_get_default(), &screen, NULL, NULL, NULL);
  gint monitor = gdk_screen_get_monitor_at_point(screen, *x, *y);

  GdkRectangle screen_rect;
  gdk_screen_get_monitor_geometry(screen, monitor, &screen_rect);

  *y = CalculateMenuYPosition(&screen_rect, &menu_req, NULL, *y);
}

}  // namespace

void Menu::Create(const base::DictionaryValue& option) {
  std::string type;
  if (option.GetString("type", &type) && type == "menubar")
    menu_ = gtk_menu_bar_new();
  else
    menu_ = gtk_menu_new();

  gtk_widget_show(menu_);
  g_object_ref_sink(G_OBJECT(menu_));
}

void Menu::Destroy() {
  gtk_widget_destroy(menu_);
  g_object_unref(G_OBJECT(menu_));
}

void Menu::Append(MenuItem* menu_item) {
  gtk_menu_shell_append(GTK_MENU_SHELL(menu_), menu_item->menu_item_);
}

void Menu::Insert(MenuItem* menu_item, int pos) {
  gtk_menu_shell_insert(GTK_MENU_SHELL(menu_), menu_item->menu_item_, pos);
}

void Menu::Remove(MenuItem* menu_item, int pos) {
  gtk_container_remove(GTK_CONTAINER(menu_), menu_item->menu_item_);
}

void Menu::Popup(int x, int y, content::Shell* shell) {
  GdkEventButton* event = shell->web_contents()->GetRenderWidgetHostView()->
      GetLastMouseDown();
  uint32_t triggering_event_time = event ? event->time : GDK_CURRENT_TIME;
  gfx::Point point(event->x_root, event->y_root);
  gtk_menu_popup(GTK_MENU(menu_), NULL, NULL,
                 PointMenuPositionFunc, &point,
                 3, triggering_event_time);
}

}  // namespace api


.option('--attach', 'attach logging after your start/restart/stop/reload')

.option('--sort <field_name:sort>', 'sort process according to field\'s name')

.option('--v8', 'enable v8 data collecting')

.option('--event-loop-inspector', 'enable event-loop-inspector dump in pmx')

/**
 * Copyright 2013 the PM2 project authors. All rights reserved.
 * Use of this source code is governed by a license that
 * can be found in the LICENSE file.
 *
 * This file wrap target application
 * - redirect stdin, stderr to bus + log files
 * - rename process
 * - pid
 */

var p       = require('path');
var cst     = require('../constants');
var Utility = require('./Utility.js');

// Load all env-vars from master.
var pm2_env = JSON.parse(process.env.pm2_env);
for(var k in pm2_env) {
  process.env[k] = pm2_env[k];
}

// Rename process
process.title = process.env.PROCESS_TITLE || 'node ' + pm2_env.pm_exec_path;

delete process.env.pm2_env;

/**
 * Main entrance to wrap the desired code
 */
(function ProcessContainer() {
  var fs          = require('fs');

  if (process.env.pmx !== 'false')
    require('pmx').init({
      transactions: process.env.km_link == 'true' && process.env.trace == 'true' || false,
      http: process.env.km_link == 'true' || false,
      v8: process.env.v8 === 'true' || false
    });

  var stdFile     = pm2_env.pm_log_path;
  var outFile     = pm2_env.pm_out_log_path;
  var errFile     = pm2_env.pm_err_log_path;
  var pmId        = pm2_env.pm_id;
  var pidFile     = pm2_env.pm_pid_path;
  var script      = pm2_env.pm_exec_path;
  var cronRestart = pm2_env.cron_restart;

  var original_send = process.send;

  if (typeof(process.env.source_map_support) != 'undefined' &&
      process.env.source_map_support !== 'false') {
    require('source-map-support').install();
  }

  process.send = function() {
    if (process.connected)
      original_send.apply(this, arguments);
  };

  //send node version
  if (process.versions && process.versions.node) {
    process.send({
      'node_version': process.versions.node
    });
  }

  if (cst.MODIFY_REQUIRE)
    require.main.filename = pm2_env.pm_exec_path;

  // Resets global paths for require()
  require('module')._initPaths();

  try {
    fs.writeFileSync(pidFile, process.pid);
  } catch (e) {
    console.error(e.stack || e);
  }

  // Add args to process if args specified on start
  if (process.env.args != null)
    process.argv = process.argv.concat(pm2_env.args);

  // stdio, including: out, err and entire (both out and err if necessary).
  var stds = {
    out: outFile,
    err: errFile
  };
  stdFile && (stds.std = stdFile);

  // uid/gid management
  if (pm2_env.uid || pm2_env.gid) {
    try {
      if (pm2_env.uid)
        process.setuid(pm2_env.uid);
      if (process.env.gid)
        process.setgid(pm2_env.gid);
    } catch(e) {
      setTimeout(function() {
        console.error('%s on call %s', e.message, e.syscall);
        console.error('%s is not accessible', pm2_env.uid);
        return process.exit(1);
      }, 100);
    }
  }

  exec(script, stds);

  if (cronRestart)
    cronize(cronRestart);
})();

/**
 * Cron restart
 */
function cronize(cron_pattern) {
  var cronJob = require('cron').CronJob;
  var job = new cronJob({
    cronTime: cron_pattern,
    onTick  : function() {
      if (process.connected && process.send) {
        process.send({
          'cron_restart': 1
        });
      } else {
        process.emit('disconnect');
        process.nextTick(function() {
          process.exit(0);
        });
      }
    },
    start: false
  });
  job.start();
}

/**
 * Description
 * @method exec
 * @param {} script
 * @param {} stds
 * @return
 */
function exec(script, stds) {
  if (p.extname(script) == '.coffee') {
    try {
      require('coffee-script/register');
    } catch (e) {
      console.error('Failed to load CoffeeScript interpreter:', e.message || e);
    }
  }

  if (p.extname(script) == '.ls') {
    try {
      require('livescript');
    } catch (e) {
      console.error('Failed to load LiveScript interpreter:', e.message || e);
    }
  }

  if (p.extname(script) == '.ts' || p.extname(script) == '.tsx') {
    try {
      require('ts-node/register');
    } catch (e) {
      console.error('Failed to load Typescript interpreter:', e.message || e);
    }
  }

  process.on('message', function (msg) {
    if (msg.type === 'log:reload') {
      for (var k in stds){
        if (typeof stds[k] == 'object' && !isNaN(stds[k].fd)){
          if (stds[k].destroy) stds[k].destroy();
          else if (stds[k].end) stds[k].end();
          else if (stds[k].close) stds[k].close();
          stds[k] = stds[k]._file;
        }
      }
      Utility.startLogging(stds, function (err) {
        if (err)
          return console.error('Failed to reload logs:', err.stack);
        console.log('Reloading log...');
      });
    }
  });

  var moment = null;

  if (pm2_env.log_date_format)
    moment = require('moment');

  Utility.startLogging(stds, function (err) {
    if (err) {
      process.send({
        type    : 'process:exception',
        data    : {
          message: err.message,
          syscall: 'ProcessContainer.startLogging'
        }
      });
      throw err;
      return;
    }

    process.stderr.write = (function(write) {
      return function(string, encoding, cb) {
        var log_data = null;

        // Disable logs if specified
        if (pm2_env.disable_logs === true) {
          return cb ? cb() : false;
        }

        if (pm2_env.log_type && pm2_env.log_type === 'json') {
          log_data = JSON.stringify({
            message : string.toString(),
            timestamp : pm2_env.log_date_format && moment ?
              moment().format(pm2_env.log_date_format) : new Date().toISOString(),
            type : 'err',
            process_id : pm2_env.pm_id,
            app_name : pm2_env.name
          }) + '\n';
        }
        else if (pm2_env.log_date_format && moment)
          log_data = moment().format(pm2_env.log_date_format) + ': ' + string.toString();
        else
          log_data = string.toString();

        process.send({
          type : 'log:err',
          data : log_data
        });

        if (Utility.checkPathIsNull(pm2_env.pm_err_log_path) &&
          (!pm2_env.pm_log_path || Utility.checkPathIsNull(pm2_env.pm_log_path)))
          return cb ? cb() : false;

        stds.std && stds.std.write && stds.std.write(log_data, encoding);
        stds.err && stds.err.write && stds.err.write(log_data, encoding, cb);
      };
    })(process.stderr.write);

    process.stdout.write = (function(write) {
      return function(string, encoding, cb) {
        var log_data = null;

        // Disable logs if specified
        if (pm2_env.disable_logs === true) {
          return cb ? cb() : false;
        }

        if (pm2_env.log_type && pm2_env.log_type === 'json') {
          log_data = JSON.stringify({
            message : string.toString(),
            timestamp : pm2_env.log_date_format && moment ?
              moment().format(pm2_env.log_date_format) : new Date().toISOString(),
            type : 'out',
            process_id : pm2_env.pm_id,
            app_name : pm2_env.name
          }) + '\n';
        }
        else if (pm2_env.log_date_format && moment)
          log_data = moment().format(pm2_env.log_date_format) + ': ' + string.toString();
        else
          log_data = string.toString();

        process.send({
          type : 'log:out',
          data : log_data
        });

        if (Utility.checkPathIsNull(pm2_env.pm_out_log_path) &&
          (!pm2_env.pm_log_path || Utility.checkPathIsNull(pm2_env.pm_log_path)))
          return cb ? cb() : null;

        stds.std && stds.std.write && stds.std.write(log_data, encoding);
        stds.out && stds.out.write && stds.out.write(log_data, encoding, cb);
      };
    })(process.stdout.write);

    function getUncaughtExceptionListener(listener) {
      return function uncaughtListener(err) {
        var error = err && err.stack ? err.stack : err;

        if (listener === 'unhandledRejection') {
          error = 'You have triggered an unhandledRejection, you may have forgotten to catch a Promise rejection:\n' + error;
        }

        logError(['std', 'err'], error);

        // Notify master that an uncaughtException has been catched
        try {
          if (err) {
            var errObj = {};

            Object.getOwnPropertyNames(err).forEach(function(key) {
              errObj[key] = err[key];
            });
          }

          process.send({
            type : 'log:err',
            data : '\n' + error + '\n'
          });
          process.send({
            type    : 'process:exception',
            data    : errObj !== undefined ? errObj : {message: 'No error but ' + listener + ' was caught!'}
          });
        } catch(e) {
          logError(['std', 'err'], 'Channel is already closed can\'t broadcast error:\n' + e.stack);
        }

        if (!process.listeners(listener).filter(function (listener) {
            return listener !== uncaughtListener;
        }).length) {
          if (listener == 'uncaughtException') {
            process.emit('disconnect');
            process.exit(cst.CODE_UNCAUGHTEXCEPTION);
          }
        }
      }
    }

    process.on('uncaughtException', getUncaughtExceptionListener('uncaughtException'));
    process.on('unhandledRejection', getUncaughtExceptionListener('unhandledRejection'));

    // Change dir to fix process.cwd
    process.chdir(pm2_env.pm_cwd || process.env.PWD || p.dirname(script));

    require('module')._load(script, null, true);

    function logError(types, error){
      try {
        types.forEach(function(type){
          stds[type] && typeof stds[type].write == 'function' && stds[type].write(error + '\n');
        });
      } catch(e) { }
    }
  });

}


#!/bin/sh

set -ex

#npm run build
npm pack
rm -rf dist
mkdir dist
mv pm2-*.tgz dist/pack.tgz

cd dist
tar -xzf pack.tgz --strip 1
rm -rf pack.tgz
npm install --production
cd ..

# First run that print a banner
node dist/bin/pm2 --version

# cleanup
find -name "*~" -delete

# fix chmod
chmod 755 `find -name LICENSE`
chmod a+x `find -name "*.sh"`

tar -cvzf dist/pm2-v`node dist/bin/pm2 --version`.tar.gz dist/*
shasum -a 256 dist/pm2-*.tar.gz


var PM2 = require('../..');
var should = require('should');

describe('Call PM2 inside PM2', function() {
  var pm2 = new PM2.custom({
    independent : true,
    cwd : __dirname + '/../fixtures/inside'
  });

  after(function(done) {
    pm2.destroy(function(){
      done();
    });
  });

  it('should start script that starts a script', function(done) {
    pm2.start('start_inside.js', function(err) {
      should(err).be.null();
      setTimeout(done, 1500);
    });
  });

  it('should list 2 processes and apps stabilized', function(done) {
    pm2.list(function(err, list) {
      should(err).be.null();
      should(list.length).eql(2);
      list.forEach(function(proc) {
        should(proc.pm2_env.restart_time).eql(0);
        should(proc.pm2_env.status).eql('online');
      });
      done();
    });
  });

  it('should start script that restart script', function(done) {
    pm2.start('restart_inside.js', function(err) {
      should(err).be.null();
      setTimeout(done, 1500);
    });
  });

  it('should list 3 processes and apps stabilized', function(done) {
    pm2.list(function(err, list) {
      should(err).be.null();
      should(list.length).eql(3);
      list.forEach(function(proc) {
        if (proc.name == 'echo') {
          should(proc.pm2_env.restart_time).eql(1);
          should(proc.pm2_env.status).eql('online');
        }
        else {
          should(proc.pm2_env.restart_time).eql(0);
          should(proc.pm2_env.status).eql('online');
        }
      });
      done();
    });
  });

  it('should start script that reload script', function(done) {
    pm2.start('reload_inside.js', function(err) {
      should(err).be.null();
      setTimeout(done, 1500);
    });
  });

  it('should list 4 processes and apps stabilized', function(done) {
    pm2.list(function(err, list) {
      should(err).be.null();
      should(list.length).eql(4);
      list.forEach(function(proc) {
        if (proc.name == 'echo') {
          should(proc.pm2_env.restart_time).eql(2);
          should(proc.pm2_env.status).eql('online');
        }
        else {
          should(proc.pm2_env.restart_time).eql(0);
          should(proc.pm2_env.status).eql('online');
        }
      });
      done();
    });
  });

});


#!/bin/bash

userdel pm2 || true
groupdel pm2 || true


if (module_name.indexOf('typescript') > -1) {

return installLangModule(module_name, function(e) {

if (module_name === 'event-loop-inspector') {

Common.printError(cst.PREFIX_MSG_MOD_ERR + chalk.bold.green('event-loop-inspector installation has FAILED (checkout previous logs)'));

Common.printOut(cst.PREFIX_MSG + chalk.bold.green('event-loop-inspector ENABLED'));


console.log('outmsg');

console.error('errmsg');

setInterval(function() {}, 100);