<commit_before>// Copyright (c) 2008 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 "chrome/browser/extensions/user_script_master.h"

#include <vector>

#include "base/file_path.h"
#include "base/file_util.h"
#include "base/logging.h"
#include "base/path_service.h"
#include "base/pickle.h"
#include "base/string_util.h"
#include "chrome/common/notification_service.h"
#include "chrome/common/stl_util-inl.h"
#include "net/base/net_util.h"

// Defined in extension.h.
extern const char kExtensionURLScheme[];
extern const char kUserScriptURLScheme[];

// static
void UserScriptMaster::ScriptReloader::ParseMetadataHeader(
      const StringPiece& script_text, std::vector<std::string> *includes) {
  // http://wiki.greasespot.net/Metadata_block
  StringPiece line;
  size_t line_start = 0;
  size_t line_end = 0;
  bool in_metadata = false;

  static const StringPiece kUserScriptBegin("// ==UserScript==");
  static const StringPiece kUserScriptEng("// ==/UserScript==");
  static const StringPiece kIncludeDeclaration("// @include ");

  while (line_start < script_text.length()) {
    line_end = script_text.find('\n', line_start);

    // Handle the case where there is no trailing newline in the file.
    if (line_end == std::string::npos) {
      line_end = script_text.length() - 1;
    }

    line.set(script_text.data() + line_start, line_end - line_start);

    if (!in_metadata) {
      if (line.starts_with(kUserScriptBegin)) {
        in_metadata = true;
      }
    } else {
      if (line.starts_with(kUserScriptEng)) {
        break;
      }

      if (line.starts_with(kIncludeDeclaration)) {
        std::string pattern(line.data() + kIncludeDeclaration.length(),
                            line.length() - kIncludeDeclaration.length());
        std::string pattern_trimmed;
        TrimWhitespace(pattern, TRIM_ALL, &pattern_trimmed);
        includes->push_back(pattern_trimmed);
      }

      // TODO(aa): Handle more types of metadata.
    }

    line_start = line_end + 1;
  }

  // If no @include patterns were specified, default to @include *.
  // This is what Greasemonkey does.
  if (includes->size() == 0) {
    includes->push_back("*");
  }
}

void UserScriptMaster::ScriptReloader::StartScan(
    MessageLoop* work_loop, const FilePath& script_dir,
    const UserScriptList& lone_scripts) {
  // Add a reference to ourselves to keep ourselves alive while we're running.
  // Balanced by NotifyMaster().
  AddRef();
  work_loop->PostTask(FROM_HERE,
      NewRunnableMethod(this,
                        &UserScriptMaster::ScriptReloader::RunScan,
                        script_dir, lone_scripts));
}

void UserScriptMaster::ScriptReloader::NotifyMaster(
    base::SharedMemory* memory) {
  if (!master_) {
    // The master went away, so these new scripts aren't useful anymore.
    delete memory;
  } else {
    master_->NewScriptsAvailable(memory);
  }

  // Drop our self-reference.
  // Balances StartScan().
  Release();
}

void UserScriptMaster::ScriptReloader::RunScan(
    const FilePath script_dir, const UserScriptList lone_scripts) {
  base::SharedMemory* shared_memory = GetNewScripts(script_dir, lone_scripts);

  // Post the new scripts back to the master's message loop.
  master_message_loop_->PostTask(FROM_HERE,
      NewRunnableMethod(this,
                        &UserScriptMaster::ScriptReloader::NotifyMaster,
                        shared_memory));
}

base::SharedMemory* UserScriptMaster::ScriptReloader::GetNewScripts(
    const FilePath& script_dir, const UserScriptList& lone_scripts) {
  UserScriptList all_scripts;

  // Find all the scripts in |script_dir|.
  if (!script_dir.value().empty()) {
    file_util::FileEnumerator enumerator(script_dir, false,
                                         file_util::FileEnumerator::FILES,
                                         FILE_PATH_LITERAL("*.user.js"));
    for (FilePath file = enumerator.Next(); !file.value().empty();
         file = enumerator.Next()) {
      all_scripts.push_back(UserScriptInfo());
      UserScriptInfo& info = all_scripts.back();
      info.url = GURL(std::string(kUserScriptURLScheme) + ":/" + 
          net::FilePathToFileURL(file.ToWStringHack()).ExtractFileName());
      info.path = file;
    }
  }

  if (all_scripts.empty() && lone_scripts.empty())<commit_msg>Fix DCHECK when handling NOTIFY_USER_SCRIPTS_LOADED by not broadcasting the message if we don't have any scripts.<commit_after>// Copyright (c) 2008 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 "chrome/browser/extensions/user_script_master.h"

#include <vector>

#include "base/file_path.h"
#include "base/file_util.h"
#include "base/logging.h"
#include "base/path_service.h"
#include "base/pickle.h"
#include "base/string_util.h"
#include "chrome/common/notification_service.h"
#include "chrome/common/stl_util-inl.h"
#include "net/base/net_util.h"

// Defined in extension.h.
extern const char kExtensionURLScheme[];
extern const char kUserScriptURLScheme[];

// static
void UserScriptMaster::ScriptReloader::ParseMetadataHeader(
      const StringPiece& script_text, std::vector<std::string> *includes) {
  // http://wiki.greasespot.net/Metadata_block
  StringPiece line;
  size_t line_start = 0;
  size_t line_end = 0;
  bool in_metadata = false;

  static const StringPiece kUserScriptBegin("// ==UserScript==");
  static const StringPiece kUserScriptEng("// ==/UserScript==");
  static const StringPiece kIncludeDeclaration("// @include ");

  while (line_start < script_text.length()) {
    line_end = script_text.find('\n', line_start);

    // Handle the case where there is no trailing newline in the file.
    if (line_end == std::string::npos) {
      line_end = script_text.length() - 1;
    }

    line.set(script_text.data() + line_start, line_end - line_start);

    if (!in_metadata) {
      if (line.starts_with(kUserScriptBegin)) {
        in_metadata = true;
      }
    } else {
      if (line.starts_with(kUserScriptEng)) {
        break;
      }

      if (line.starts_with(kIncludeDeclaration)) {
        std::string pattern(line.data() + kIncludeDeclaration.length(),
                            line.length() - kIncludeDeclaration.length());
        std::string pattern_trimmed;
        TrimWhitespace(pattern, TRIM_ALL, &pattern_trimmed);
        includes->push_back(pattern_trimmed);
      }

      // TODO(aa): Handle more types of metadata.
    }

    line_start = line_end + 1;
  }

  // If no @include patterns were specified, default to @include *.
  // This is what Greasemonkey does.
  if (includes->size() == 0) {
    includes->push_back("*");
  }
}

void UserScriptMaster::ScriptReloader::StartScan(
    MessageLoop* work_loop, const FilePath& script_dir,
    const UserScriptList& lone_scripts) {
  // Add a reference to ourselves to keep ourselves alive while we're running.
  // Balanced by NotifyMaster().
  AddRef();
  work_loop->PostTask(FROM_HERE,
      NewRunnableMethod(this,
                        &UserScriptMaster::ScriptReloader::RunScan,
                        script_dir, lone_scripts));
}

void UserScriptMaster::ScriptReloader::NotifyMaster(
    base::SharedMemory* memory) {
  if (!master_) {
    // The master went away, so these new scripts aren't useful anymore.
    delete memory;
  } else {
    master_->NewScriptsAvailable(memory);
  }

  // Drop our self-reference.
  // Balances StartScan().
  Release();
}

void UserScriptMaster::ScriptReloader::RunScan(
    const FilePath script_dir, const UserScriptList lone_scripts) {
  base::SharedMemory* shared_memory = GetNewScripts(script_dir, lone_scripts);
  if (!shared_memory)
    return;  // No scripts to load.

  // Post the new scripts back to the master's message loop.
  master_message_loop_->PostTask(FROM_HERE,
      NewRunnableMethod(this,
                        &UserScriptMaster::ScriptReloader::NotifyMaster,
                        shared_memory));
}

base::SharedMemory* UserScriptMaster::ScriptReloader::GetNewScripts(
    const FilePath& script_dir, const UserScriptList& lone_scripts) {
  UserScriptList all_scripts;

  // Find all the scripts in |script_dir|.
  if (!script_dir.value().empty()) {
    file_util::FileEnumerator enumerator(script_dir, false,
                                         file_util::FileEnumerator::FILES,
                                         FILE_PATH_LITERAL("*.user.js"));
    for (FilePath file = enumerator.Next(); !file.value().empty();
         file = enumerator.Next()) {
      all_scripts.push_back(UserScriptInfo());
      UserScriptInfo& info = all_scripts.back();
      info.url = GURL(std::string(kUserScriptURLScheme) + ":/" + 
          net::FilePathToFileURL(file.ToWStringHack()).ExtractFileName());
      info.path = file;
    }
  }

  if (all_scripts.empty() && lone_scripts.empty())
{'fraction_non_alphanumeric': 0.11996886813431176, 'fraction_numerical': 0.0020013342228152103, 'mean_word_length': 3.2529550827423166, 'pattern_counts': {'":': 2, '<': 9, '<?xml version=': 0, '>': 19, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 8, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5317424', 'n_tokens_mistral': 2765, 'n_tokens_neox': 2705, 'n_words': 623}