// 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/native_window_win.h"

#include "base/utf_string_conversions.h"
#include "base/values.h"
#include "base/win/wrapped_window_proc.h"
#include "chrome/browser/platform_util.h"
#include "content/nw/src/api/menu/menu.h"
#include "content/nw/src/browser/native_window_toolbar_win.h"
#include "content/nw/src/common/shell_switches.h"
#include "content/nw/src/nw_shell.h"
#include "content/public/browser/native_web_keyboard_event.h"
#include "content/public/browser/render_view_host.h"
#include "content/public/browser/render_widget_host_view.h"
#include "content/public/browser/web_contents.h"
#include "content/public/browser/web_contents_view.h"
#include "extensions/common/draggable_region.h"
#include "third_party/skia/include/core/SkPaint.h"
#include "ui/base/hit_test.h"
#include "ui/base/win/hwnd_util.h"
#include "ui/gfx/path.h"
#include "ui/views/controls/webview/webview.h"
#include "ui/views/layout/box_layout.h"
#include "ui/views/views_delegate.h"
#include "ui/views/widget/widget.h"
#include "ui/views/widget/native_widget_win.h"
#include "ui/views/window/native_frame_view.h"

namespace nw {

namespace {

const int kResizeInsideBoundsSize = 5;
const int kResizeAreaCornerSize = 16;

// Returns true if |possible_parent| is a parent window of |child|.
bool IsParent(gfx::NativeView child, gfx::NativeView possible_parent) {
  if (!child)
    return false;
#if !defined(USE_AURA) && defined(OS_WIN)
  if (::GetWindow(child, GW_OWNER) == possible_parent)
    return true;
#endif
  gfx::NativeView parent = child;
  while ((parent = platform_util::GetParent(parent))) {
    if (possible_parent == parent)
      return true;
  }

  return false;
}

class NativeWindowClientView : public views::ClientView {
 public:
  NativeWindowClientView(views::Widget* widget,
                         views::View* contents_view,
                         content::Shell* shell)
      : views::ClientView(widget, contents_view),
        shell_(shell) {
  }
  virtual ~NativeWindowClientView() {}

  virtual bool CanClose() OVERRIDE {
    return shell_->ShouldCloseWindow();
  }

 private:
  content::Shell* shell_;
};

class NativeWindowFrameView : public views::NonClientFrameView {
 public:
  static const char kViewClassName[];

  explicit NativeWindowFrameView(NativeWindowWin* window);
  virtual ~NativeWindowFrameView();

  void Init(views::Widget* frame);

  // views::NonClientFrameView implementation.
  virtual gfx::Rect GetBoundsForClientView() const OVERRIDE;
  virtual gfx::Rect GetWindowBoundsForClientBounds(
      const gfx::Rect& client_bounds) const OVERRIDE;
  virtual int NonClientHitTest(const gfx::Point& point) OVERRIDE;
  virtual void GetWindowMask(const gfx::Size& size,
                             gfx::Path* window_mask) OVERRIDE;
  virtual void ResetWindowControls() OVERRIDE {}
  virtual void UpdateWindowIcon() OVERRIDE {}
  virtual void UpdateWindowTitle() OVERRIDE {}

  // views::View implementation.
  virtual gfx::Size GetPreferredSize() OVERRIDE;
  virtual void Layout() OVERRIDE;
  virtual std::string GetClassName() const OVERRIDE;
  virtual void OnPaint(gfx::Canvas* canvas) OVERRIDE;
  virtual gfx::Size GetMinimumSize() OVERRIDE;
  virtual gfx::Size GetMaximumSize() OVERRIDE;

 private:
  NativeWindowWin* window_;
  views::Widget* frame_;

  DISALLOW_COPY_AND_ASSIGN(NativeWindowFrameView);
};

const char NativeWindowFrameView::kViewClassName[] =
    "content/nw/src/browser/NativeWindowFrameView";

NativeWindowFrameView::NativeWindowFrameView(NativeWindowWin* window)
    : window_(window),
      frame_(NULL) {
}

NativeWindowFrameView::~NativeWindowFrameView() {
}

void NativeWindowFrameView::Init(views::Widget* frame) {
  frame_ = frame;
}

gfx::Rect NativeWindowFrameView::GetBoundsForClientView() const {
  return bounds();
}

gfx::Rect NativeWindowFrameView::GetWindowBoundsForClientBounds(
      const gfx::Rect& client_bounds) const {
  gfx::Rect window_bounds = client_bounds;
  // Enforce minimum size (1, 1) in case that client_bounds is passed with
  // empty size. This could occur when the frameless window is being
  // initialized.
  if (window_bounds.IsEmpty()) {
    window_bounds.set_width(1);
    window_bounds.set_height(1);
  }
  return window_bounds;
}

int NativeWindowFrameView::NonClientHitTest(const gfx::Point& point) {
  if (frame_->IsFullscreen())
    return HTCLIENT;

  // Check the frame first, as we allow a small area overlapping the contents
  // to be used for resize handles.
  bool can_ever_resize = frame_->widget_delegate() ?
      frame_->widget_delegate()->CanResize() :
      false;
  // Don't allow overlapping resize handles when the window is maximized or
  // fullscreen, as it can't be resized in those states.
  int resize_border =
      frame_->IsMaximized() || frame_->IsFullscreen() ? 0 :
      kResizeInsideBoundsSize;
  int frame_component = GetHTComponentForFrame(point,
                                               resize_border,
                                               resize_border,
                                               kResizeAreaCornerSize,
                                               kResizeAreaCornerSize,
                                               can_ever_resize);
  if (frame_component != HTNOWHERE)
    return frame_component;

  // Ajust the point if we have a toolbar.
  gfx::Point adjusted_point(point);
  if (window_->toolbar())
    adjusted_point.set_y(adjusted_point.y() - window_->toolbar()->height());

  // Check for possible draggable region in the client area for the frameless
  // window.
  if (window_->draggable_region() &&
      window_->draggable_region()->contains(adjusted_point.x(),
                                            adjusted_point.y()))
    return HTCAPTION;

  int client_component = frame_->client_view()->NonClientHitTest(point);
  if (client_component != HTNOWHERE)
    return client_component;

  // Caption is a safe default.
  return HTCAPTION;
}

void NativeWindowFrameView::GetWindowMask(const gfx::Size& size,
                                         gfx::Path* window_mask) {
  // We got nothing to say about no window mask.
}

gfx::Size NativeWindowFrameView::GetPreferredSize() {
  gfx::Size pref = frame_->client_view()->GetPreferredSize();
  gfx::Rect bounds(0, 0, pref.width(), pref.height());
  return frame_->non_client_view()->GetWindowBoundsForClientBounds(
      bounds).size();
}

void NativeWindowFrameView::Layout() {
}

void NativeWindowFrameView::OnPaint(gfx::Canvas* canvas) {
}

std::string NativeWindowFrameView::GetClassName() const {
  return kViewClassName;
}

gfx::Size NativeWindowFrameView::GetMinimumSize() {
  return frame_->client_view()->GetMinimumSize();
}

gfx::Size NativeWindowFrameView::GetMaximumSize() {
  return frame_->client_view()->GetMaximumSize();
}

}  // namespace

NativeWindowWin::NativeWindowWin(content::Shell* shell,
                                 base::DictionaryValue* manifest)
    : NativeWindow(shell, manifest),
      web_view_(NULL),
      toolbar_(NULL),
      is_fullscreen_(false),
      is_minimized_(false),
      is_focus_(false),
      is_blur_(false),
      menu_(NULL),
      resizable_(true),
      minimum_size_(0, 0),
      maximum_size_() {
  window_ = new views::Widget;
  views::Widget::InitParams params(views::Widget::InitParams::TYPE_WINDOW);
  params.delegate = this;
  params.remove_standard_frame = !has_frame();
  params.use_system_default_icon = true;
  window_->Init(params);

  views::WidgetFocusManager::GetInstance()->AddFocusChangeListener(this);

  int width, height;
  manifest->GetInteger(switches::kmWidth, &width);
  manifest->GetInteger(switches::kmHeight, &height);
  gfx::Rect window_bounds =
    window_->non_client_view()->GetWindowBoundsForClientBounds(
        gfx::Rect(width,height));
  window_->SetSize(window_bounds.size());
  window_->CenterWindow(window_bounds.size());

  window_->UpdateWindowIcon();

  OnViewWasResized();
}

NativeWindowWin::~NativeWindowWin() {
  views::WidgetFocusManager::GetInstance()->RemoveFocusChangeListener(this);
}

void NativeWindowWin::Close() {
  window_->Close();
}

void NativeWindowWin::Move(const gfx::Rect& bounds) {
  window_->SetBounds(bounds);
}

void NativeWindowWin::Focus(bool focus) {
  window_->Activate();
}

void NativeWindowWin::Show() {
  window_->Show();
}

void NativeWindowWin::Hide() {
  window_->Hide();
}

void NativeWindowWin::Maximize() {
  window_->Maximize();
}

void NativeWindowWin::Unmaximize() {
  window_->Restore();
}

void NativeWindowWin::Minimize() {
  window_->Minimize();
}

void NativeWindowWin::Restore() {
  window_->Restore();
}

void NativeWindowWin::SetFullscreen(bool fullscreen) {
  is_fullscreen_ = fullscreen;
  window_->SetFullscreen(fullscreen);
  if (fullscreen)
    shell()->SendEvent("enter-fullscreen");
  else
    shell()->SendEvent("leave-fullscreen");
}

bool NativeWindowWin::IsFullscreen() {
  return is_fullscreen_;
}

void NativeWindowWin::SetSize(const gfx::Size& size) {
  window_->SetSize(size);
}

gfx::Size NativeWindowWin::GetSize() {
  return window_->GetWindowBoundsInScreen().size();
}

void NativeWindowWin::SetMinimumSize(int width, int height) {
  minimum_size_.set_width(width);
  minimum_size_.set_height(height);
}

void NativeWindowWin::SetMaximumSize(int width, int height) {
  maximum_size_.set_width(width);
  maximum_size_.set_height(height);
}

void NativeWindowWin::SetResizable(bool resizable) {
  resizable_ = resizable;

  // Show/Hide the maximize button.
  DWORD style = ::GetWindowLong(window_->GetNativeView(), GWL_STYLE);
  if (resizable)
    style |= WS_MAXIMIZEBOX;
  else
    style &= ~WS_MAXIMIZEBOX;
  ::SetWindowLong(window_->GetNativeView(), GWL_STYLE, style);
}

void NativeWindowWin::SetAlwaysOnTop(bool top) {
  window_->SetAlwaysOnTop(top);
}

void NativeWindowWin::SetPosition(const std::string& position) {
  if (position == "center") {
    gfx::Rect bounds = window_->GetWindowBoundsInScreen();
    window_->CenterWindow(gfx::Size(bounds.width(), bounds.height()));
  }
}

void NativeWindowWin::SetPosition(const gfx::Point& position) {
  gfx::Rect bounds = window_->GetWindowBoundsInScreen();
  window_->SetBounds(gfx::Rect(position, bounds.size()));
}

gfx::Point NativeWindowWin::GetPosition() {
  return window_->GetWindowBoundsInScreen().origin();
}

void NativeWindowWin::FlashFrame(bool flash) {
  window_->FlashFrame(flash);
}

void NativeWindowWin::SetKiosk(bool kiosk) {
  SetFullscreen(kiosk);
}

bool NativeWindowWin::IsKiosk() {
  return IsFullscreen();
}

void NativeWindowWin::SetMenu(api::Menu* menu) {
  window_->set_has_menu_bar(true);
  menu_ = menu;

  // The menu is lazily built.
  menu->Rebuild();

  // menu is api::Menu, menu->menu_ is NativeMenuWin,
  ::SetMenu(window_->GetNativeWindow(), menu->menu_->GetNativeMenu());
}

void NativeWindowWin::SetTitle(const std::string& title) {
  title_ = title;
  window_->UpdateWindowTitle();
}

void NativeWindowWin::AddToolbar() {
  toolbar_ = new NativeWindowToolbarWin(shell());
  AddChildViewAt(toolbar_, 0);
}

void NativeWindowWin::SetToolbarButtonEnabled(TOOLBAR_BUTTON button,
                                              bool enabled) {
  if (toolbar_)
    toolbar_->SetButtonEnabled(button, enabled);
}

void NativeWindowWin::SetToolbarUrlEntry(const std::string& url) {
  if (toolbar_)
    toolbar_->SetUrlEntry(url);
}

void NativeWindowWin::SetToolbarIsLoading(bool loading) {
  if (toolbar_)
    toolbar_->SetIsLoading(loading);
}

views::View* NativeWindowWin::GetContentsView() {
  return this;
}

views::ClientView* NativeWindowWin::CreateClientView(views::Widget* widget) {
  return new NativeWindowClientView(widget, GetContentsView(), shell());
}

views::NonClientFrameView* NativeWindowWin::CreateNonClientFrameView(
    views::Widget* widget) {
  if (has_frame())
    return new views::NativeFrameView(GetWidget());

  NativeWindowFrameView* frame_view = new NativeWindowFrameView(this);
  frame_view->Init(window_);
  return frame_view;
}

bool NativeWindowWin::CanResize() const {
  return resizable_;
}

bool NativeWindowWin::CanMaximize() const {
  return resizable_;
}

views::Widget* NativeWindowWin::GetWidget() {
  return window_;
}

const views::Widget* NativeWindowWin::GetWidget() const {
  return window_;
}

string16 NativeWindowWin::GetWindowTitle() const {
  return UTF8ToUTF16(title_);
}

void NativeWindowWin::DeleteDelegate() {
  delete shell();
}

bool NativeWindowWin::ShouldShowWindowTitle() const {
  return has_frame();
}

void NativeWindowWin::OnNativeFocusChange(gfx::NativeView focused_before,
                                          gfx::NativeView focused_now) {
  gfx::NativeView this_window = GetWidget()->GetNativeView();
  if (IsParent(focused_now, this_window) ||
      IsParent(this_window, focused_now))
    return;

  if (focused_now == this_window) {
    if (!is_focus_)
      shell()->SendEvent("focus");
    is_focus_ = true;
    is_blur_ = false;
  } else if (focused_before == this_window) {
    if (!is_blur_)
      shell()->SendEvent("blur");
    is_focus_ = false;
    is_blur_ = true;
  }
}

gfx::ImageSkia NativeWindowWin::GetWindowAppIcon() {
  gfx::Image icon = app_icon();
  if (icon.IsEmpty())
    return gfx::ImageSkia();

  return *icon.ToImageSkia();
}

gfx::ImageSkia NativeWindowWin::GetWindowIcon() {
  return GetWindowAppIcon();
}

views::View* NativeWindowWin::GetInitiallyFocusedView() {
  return web_view_;
}

void NativeWindowWin::UpdateDraggableRegions(
    const std::vector<extensions::DraggableRegion>& regions) {
  // Draggable region is not supported for non-frameless window.
  if (has_frame())
    return;

  SkRegion* draggable_region = new SkRegion;

  // By default, the whole window is non-draggable. We need to explicitly
  // include those draggable regions.
  for (std::vector<extensions::DraggableRegion>::const_iterator iter =
           regions.begin();
       iter != regions.end(); ++iter) {
    const extensions::DraggableRegion& region = *iter;
    draggable_region->op(
        region.bounds.x(),
        region.bounds.y(),
        region.bounds.right(),
        region.bounds.bottom(),
        region.draggable ? SkRegion::kUnion_Op : SkRegion::kDifference_Op);
  }

  draggable_region_.reset(draggable_region);
  OnViewWasResized();
}

void NativeWindowWin::HandleKeyboardEvent(
    const content::NativeWebKeyboardEvent& event) {
  // Any unhandled keyboard/character messages should be defproced.
  // This allows stuff like F10, etc to work correctly.
  DefWindowProc(event.os_event.hwnd, event.os_event.message,
                event.os_event.wParam, event.os_event.lParam);
}

void NativeWindowWin::Layout() {
  DCHECK(web_view_);
  if (toolbar_) {
    toolbar_->SetBounds(0, 0, width(), 34);
    web_view_->SetBounds(0, 34, width(), height() - 34);
  } else {
    web_view_->SetBounds(0, 0, width(), height());
  }
  OnViewWasResized();
}

void NativeWindowWin::ViewHierarchyChanged(
    bool is_add, views::View *parent, views::View *child) {
  if (is_add && child == this) {
    views::BoxLayout* layout = new views::BoxLayout(
        views::BoxLayout::kVertical, 0, 0, 0);
    SetLayoutManager(layout);

    web_view_ = new views::WebView(NULL);
    web_view_->SetWebContents(web_contents());
    AddChildView(web_view_);
  }
}

gfx::Size NativeWindowWin::GetMinimumSize() {
  return minimum_size_;
}

gfx::Size NativeWindowWin::GetMaximumSize() {
  return maximum_size_;
}

void NativeWindowWin::OnFocus() {
  web_view_->RequestFocus();
}

bool NativeWindowWin::ExecuteWindowsCommand(int command_id) {
  // Windows uses the 4 lower order bits of |command_id| for type-specific
  // information so we must exclude this when comparing.
  static const int sc_mask = 0xFFF0;

  if ((command_id & sc_mask) == SC_MINIMIZE) {
    is_minimized_ = true;
    shell()->SendEvent("minimize");
  } else if ((command_id & sc_mask) == SC_RESTORE && is_minimized_) {
    is_minimized_ = false;
    shell()->SendEvent("restore");
  } else if ((command_id & sc_mask) == SC_RESTORE && !is_minimized_) {
    shell()->SendEvent("unmaximize");
  } else if ((command_id & sc_mask) == SC_MAXIMIZE) {
    shell()->SendEvent("maximize");
  }

  return false;
}

bool NativeWindowWin::ExecuteAppCommand(int command_id) {
  if (menu_) {
    menu_->menu_delegate_->ExecuteCommand(command_id);
    menu_->menu_->UpdateStates();
  }

  return false;
}

void NativeWindowWin::SaveWindowPlacement(const gfx::Rect& bounds,
                                          ui::WindowShowState show_state) {
  // views::WidgetDelegate::SaveWindowPlacement(bounds, show_state);
}

void NativeWindowWin::OnViewWasResized() {
  // Set the window shape of the RWHV.
  DCHECK(window_);
  DCHECK(web_view_);
  gfx::Size sz = web_view_->size();
  int height = sz.height(), width = sz.width();
  gfx::Path path;
  path.addRect(0, 0, width, height);
  SetWindowRgn(web_contents()->GetView()->GetNativeView(),
               path.CreateNativeRegion(),
               1);

  SkRegion* rgn = new SkRegion;
  if (!window_->IsFullscreen()) {
    if (draggable_region())
      rgn->op(*draggable_region(), SkRegion::kUnion_Op);
    if (!window_->IsMaximized()) {
      if (!has_frame()) {
        rgn->op(0, 0, width, kResizeInsideBoundsSize, SkRegion::kUnion_Op);
        rgn->op(0, 0, kResizeInsideBoundsSize, height, SkRegion::kUnion_Op);
        rgn->op(width - kResizeInsideBoundsSize, 0, width, height,
            SkRegion::kUnion_Op);
        rgn->op(0, height - kResizeInsideBoundsSize, width, height,
            SkRegion::kUnion_Op);
      }
    }
  }
  if (web_contents()->GetRenderViewHost()->GetView())
    web_contents()->GetRenderViewHost()->GetView()->SetClickthroughRegion(rgn);
}

}  // namespace nw


class ShellContentBrowserClient : public ContentBrowserClient {

exports.test = function() {
  return "module2";
}


#endif  // CONTENT_SHELL_SHELL_CONTENT_BROWSER_CLIENT_H_

keep keep keep add keep 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/dispatcher_host.h"

#include "base/logging.h"
#include "base/values.h"
#include "content/browser/web_contents/web_contents_impl.h"
#include "content/nw/src/api/api_messages.h"
#include "content/nw/src/api/app/app.h"
#include "content/nw/src/api/base/base.h"
#include "content/nw/src/api/clipboard/clipboard.h"
#include "content/nw/src/api/menu/menu.h"
#include "content/nw/src/api/menuitem/menuitem.h"
#include "content/nw/src/api/shell/shell.h"
#include "content/nw/src/api/tray/tray.h"
#include "content/nw/src/api/window/window.h"
#include "content/nw/src/common/shell_switches.h"
#include "content/nw/src/shell_browser_context.h"
#include "content/nw/src/nw_shell.h"
#include "content/public/browser/render_process_host.h"

using content::WebContents;
using content::ShellBrowserContext;

namespace api {

DispatcherHost::DispatcherHost(content::RenderViewHost* render_view_host)
    : content::RenderViewHostObserver(render_view_host) {
}

DispatcherHost::~DispatcherHost() {
}

Base* DispatcherHost::GetApiObject(int id) {
  return objects_registry_.Lookup(id);
}

void DispatcherHost::SendEvent(Base* object,
                               const std::string& event,
                               const base::ListValue& arguments) {
  Send(new ShellViewMsg_Object_On_Event(
       routing_id(), object->id(), event, arguments));
}

bool DispatcherHost::Send(IPC::Message* message) {
  return content::RenderViewHostObserver::Send(message);
}

bool DispatcherHost::OnMessageReceived(const IPC::Message& message) {
  bool handled = true;
  IPC_BEGIN_MESSAGE_MAP(DispatcherHost, message)
    IPC_MESSAGE_HANDLER(ShellViewHostMsg_Allocate_Object, OnAllocateObject)
    IPC_MESSAGE_HANDLER(ShellViewHostMsg_Deallocate_Object, OnDeallocateObject)
    IPC_MESSAGE_HANDLER(ShellViewHostMsg_Call_Object_Method, OnCallObjectMethod)
    IPC_MESSAGE_HANDLER(ShellViewHostMsg_Call_Object_Method_Sync,
                        OnCallObjectMethodSync)
    IPC_MESSAGE_HANDLER(ShellViewHostMsg_Call_Static_Method, OnCallStaticMethod)
    IPC_MESSAGE_HANDLER(ShellViewHostMsg_Call_Static_Method_Sync,
                        OnCallStaticMethodSync)
    IPC_MESSAGE_HANDLER(ShellViewHostMsg_UncaughtException,
                        OnUncaughtException);
    IPC_MESSAGE_HANDLER(ShellViewHostMsg_GetShellId, OnGetShellId);
    IPC_MESSAGE_HANDLER(ShellViewHostMsg_CreateShell, OnCreateShell);
    IPC_MESSAGE_UNHANDLED(handled = false)
  IPC_END_MESSAGE_MAP()

  return handled;
}

void DispatcherHost::OnAllocateObject(int object_id,
                                      const std::string& type,
                                      const base::DictionaryValue& option) {
  DVLOG(1) << "OnAllocateObject: object_id:" << object_id
             << " type:" << type
             << " option:" << option;

  if (type == "Menu") {
    objects_registry_.AddWithID(new Menu(object_id, this, option), object_id);
  } else if (type == "MenuItem") {
    objects_registry_.AddWithID(
        new MenuItem(object_id, this, option), object_id);
  } else if (type == "Tray") {
    objects_registry_.AddWithID(new Tray(object_id, this, option), object_id);
  } else if (type == "Clipboard") {
    objects_registry_.AddWithID(
        new Clipboard(object_id, this, option), object_id);
  } else if (type == "Window") {
    objects_registry_.AddWithID(new Window(object_id, this, option), object_id);
  } else {
    LOG(ERROR) << "Allocate an object of unknow type: " << type;
    objects_registry_.AddWithID(new Base(object_id, this, option), object_id);
  }
}

void DispatcherHost::OnDeallocateObject(int object_id) {
  DLOG(INFO) << "OnDeallocateObject: object_id:" << object_id;
  objects_registry_.Remove(object_id);
}

void DispatcherHost::OnCallObjectMethod(
    int object_id,
    const std::string& type,
    const std::string& method,
    const base::ListValue& arguments) {
  DLOG(INFO) << "OnCallObjectMethod: object_id:" << object_id
             << " type:" << type
             << " method:" << method
             << " arguments:" << arguments;

  Base* object = GetApiObject(object_id);
  DCHECK(object) << "Unknown object: " << object_id;
  object->Call(method, arguments);
}

void DispatcherHost::OnCallObjectMethodSync(
    int object_id,
    const std::string& type,
    const std::string& method,
    const base::ListValue& arguments,
    base::ListValue* result) {
  DLOG(INFO) << "OnCallObjectMethodSync: object_id:" << object_id
             << " type:" << type
             << " method:" << method
             << " arguments:" << arguments;

  Base* object = GetApiObject(object_id);
  DCHECK(object) << "Unknown object: " << object_id;
  object->CallSync(method, arguments, result);
}

void DispatcherHost::OnCallStaticMethod(
    const std::string& type,
    const std::string& method,
    const base::ListValue& arguments) {
  DLOG(INFO) << "OnCallStaticMethod: "
             << " type:" << type
             << " method:" << method
             << " arguments:" << arguments;

  if (type == "Shell") {
    api::Shell::Call(method, arguments);
    return;
  } else if (type == "App") {
    api::App::Call(method, arguments);
    return;
  }

  NOTREACHED() << "Calling unknown method " << method << " of class " << type;
}

void DispatcherHost::OnCallStaticMethodSync(
    const std::string& type,
    const std::string& method,
    const base::ListValue& arguments,
    base::ListValue* result) {
  DLOG(INFO) << "OnCallStaticMethodSync: "
             << " type:" << type
             << " method:" << method
             << " arguments:" << arguments;

  if (type == "App") {
    content::Shell* shell =
        content::Shell::FromRenderViewHost(render_view_host());
    api::App::Call(shell, method, arguments, result);
    return;
  }

  NOTREACHED() << "Calling unknown method " << method << " of class " << type;
}

void DispatcherHost::OnUncaughtException(const std::string& err) {
  content::Shell* shell =
      content::Shell::FromRenderViewHost(render_view_host());
  shell->PrintCriticalError("Uncaught node.js Error", err);
}

void DispatcherHost::OnGetShellId(int* id) {
  content::Shell* shell =
      content::Shell::FromRenderViewHost(render_view_host());
  *id = shell->id();
}

void DispatcherHost::OnCreateShell(const std::string& url,
                                   const base::DictionaryValue& manifest,
                                   int* routing_id) {
  WebContents* base_web_contents =
      content::Shell::FromRenderViewHost(render_view_host())->web_contents();
  ShellBrowserContext* browser_context =
      static_cast<ShellBrowserContext*>(base_web_contents->GetBrowserContext());
  scoped_ptr<base::DictionaryValue> new_manifest(manifest.DeepCopy());
  bool new_renderer = false;
  if (new_manifest->GetBoolean(switches::kmNewInstance,
                               &new_renderer) && new_renderer)
    browser_context->set_pinning_renderer(false);

  WebContents::CreateParams create_params(browser_context,
                                          new_renderer ? NULL : base_web_contents->GetSiteInstance());

  WebContents* web_contents = content::WebContentsImpl::CreateWithOpener(
      create_params,
      static_cast<content::WebContentsImpl*>(base_web_contents));
  new content::Shell(web_contents, new_manifest.get());
  web_contents->GetController().LoadURL(
      GURL(url),
      content::Referrer(),
      content::PAGE_TRANSITION_TYPED,
      std::string());

  if (new_renderer)
    browser_context->set_pinning_renderer(true);

  *routing_id = web_contents->GetRoutingID();
}

}  // 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/dispatcher_bindings.h"

#include "base/files/file_path.h"
#include "base/file_util.h"
#include "base/logging.h"
#include "base/values.h"
#include "base/command_line.h"
#include "chrome/renderer/static_v8_external_string_resource.h"
#include "content/nw/src/api/api_messages.h"
#include "content/nw/src/api/bindings_common.h"
#include "content/public/renderer/render_view.h"
#include "content/public/renderer/render_thread.h"
#include "content/public/renderer/v8_value_converter.h"
#include "grit/nw_resources.h"

using content::RenderView;
using content::V8ValueConverter;
using base::FilePath;

namespace api {

namespace {

v8::Handle<v8::String> WrapSource(v8::Handle<v8::String> source) {
  v8::HandleScope handle_scope;
  v8::Handle<v8::String> left =
      v8::String::New("(function(nw, exports) {");
  v8::Handle<v8::String> right = v8::String::New("\n})");
  return handle_scope.Close(
      v8::String::Concat(left, v8::String::Concat(source, right)));
}

// Similar to node's `require` function, save functions in `exports`.
void RequireFromResource(v8::Handle<v8::Object> root,
                         v8::Handle<v8::Object> gui,
                         v8::Handle<v8::String> name,
                         int resource_id) {
  v8::HandleScope scope;

  v8::Handle<v8::String> source = v8::String::NewExternal(
      new StaticV8ExternalAsciiStringResource(
          GetStringResource(resource_id)));
  v8::Handle<v8::String> wrapped_source = WrapSource(source);

  v8::Handle<v8::Script> script(v8::Script::New(wrapped_source, name));
  v8::Handle<v8::Function> func = v8::Handle<v8::Function>::Cast(script->Run());
  v8::Handle<v8::Value> args[] = { root, gui };
  func->Call(root, 2, args);
}

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;
}

}  // namespace

DispatcherBindings::DispatcherBindings()
    : v8::Extension("dispatcher_bindings.js",
                    GetStringResource(
                        IDR_NW_API_DISPATCHER_BINDINGS_JS).data(),
                    0,     // num dependencies.
                    NULL,  // dependencies array.
                    GetStringResource(
                        IDR_NW_API_DISPATCHER_BINDINGS_JS).size()) {
}

DispatcherBindings::~DispatcherBindings() {
}

v8::Handle<v8::FunctionTemplate>
DispatcherBindings::GetNativeFunction(v8::Handle<v8::String> name) {
  if (name->Equals(v8::String::New("RequireNwGui")))
    return v8::FunctionTemplate::New(RequireNwGui);
  else if (name->Equals(v8::String::New("GetAbsolutePath")))
    return v8::FunctionTemplate::New(GetAbsolutePath);
  else if (name->Equals(v8::String::New("GetShellIdForCurrentContext")))
    return v8::FunctionTemplate::New(GetShellIdForCurrentContext);
  else if (name->Equals(v8::String::New("GetRoutingIDForCurrentContext")))
    return v8::FunctionTemplate::New(GetRoutingIDForCurrentContext);
  else if (name->Equals(v8::String::New("CreateShell")))
    return v8::FunctionTemplate::New(CreateShell);
  else if (name->Equals(v8::String::New("AllocateObject")))
    return v8::FunctionTemplate::New(AllocateObject);
  else if (name->Equals(v8::String::New("DeallocateObject")))
    return v8::FunctionTemplate::New(DeallocateObject);
  else if (name->Equals(v8::String::New("CallObjectMethod")))
    return v8::FunctionTemplate::New(CallObjectMethod);
  else if (name->Equals(v8::String::New("CallObjectMethodSync")))
    return v8::FunctionTemplate::New(CallObjectMethodSync);
  else if (name->Equals(v8::String::New("CallStaticMethod")))
    return v8::FunctionTemplate::New(CallStaticMethod);
  else if (name->Equals(v8::String::New("CallStaticMethodSync")))
    return v8::FunctionTemplate::New(CallStaticMethodSync);

  NOTREACHED() << "Trying to get an non-exist function in DispatcherBindings:"
               << *v8::String::Utf8Value(name);
  return v8::FunctionTemplate::New();
}

// static
v8::Handle<v8::Value>
DispatcherBindings::RequireNwGui(const v8::Arguments& args) {
  v8::HandleScope scope;

  // Initialize lazily
  v8::Local<v8::String> NwGuiSymbol = v8::String::NewSymbol("nwGui");
  v8::Local<v8::Value> NwGuiHidden = args.This()->Get(NwGuiSymbol);
  if (NwGuiHidden->IsObject())
    return scope.Close(NwGuiHidden);

  v8::Local<v8::Object> NwGui = v8::Object::New();
  args.This()->Set(NwGuiSymbol, NwGui);
  RequireFromResource(args.This(),
      NwGui, v8::String::New("base.js"), IDR_NW_API_BASE_JS);
  RequireFromResource(args.This(),
      NwGui, v8::String::New("menuitem.js"), IDR_NW_API_MENUITEM_JS);
  RequireFromResource(args.This(),
      NwGui, v8::String::New("menu.js"), IDR_NW_API_MENU_JS);
  RequireFromResource(args.This(),
      NwGui, v8::String::New("tray.js"), IDR_NW_API_TRAY_JS);
  RequireFromResource(args.This(),
      NwGui, v8::String::New("clipboard.js"), IDR_NW_API_CLIPBOARD_JS);
  RequireFromResource(args.This(),
      NwGui, v8::String::New("window.js"), IDR_NW_API_WINDOW_JS);
  RequireFromResource(args.This(),
      NwGui, v8::String::New("shell.js"), IDR_NW_API_SHELL_JS);
  RequireFromResource(args.This(),
      NwGui, v8::String::New("app.js"), IDR_NW_API_APP_JS);

  return scope.Close(NwGui);
}

// static
v8::Handle<v8::Value>
DispatcherBindings::GetAbsolutePath(const v8::Arguments& args) {
  FilePath path = FilePath::FromUTF8Unsafe(*v8::String::Utf8Value(args[0]));
  MakePathAbsolute(&path);
#if defined(OS_POSIX)
  return v8::String::New(path.value().c_str());
#else
  return v8::String::New(path.AsUTF8Unsafe().c_str());
#endif
}

// static
v8::Handle<v8::Value>
DispatcherBindings::GetShellIdForCurrentContext(const v8::Arguments& args) {
  RenderView* render_view = GetCurrentRenderView();
  if (!render_view) {
    return v8::ThrowException(v8::Exception::Error(v8::String::New(
            "Unable to get render view in CallStaticMethodSync")));
  }

  int id = -1;
  render_view->Send(new ShellViewHostMsg_GetShellId(MSG_ROUTING_NONE, &id));
  return v8::Integer::New(id);
}

// static
v8::Handle<v8::Value>
DispatcherBindings::GetRoutingIDForCurrentContext(const v8::Arguments& args) {
  RenderView* render_view = GetCurrentRenderView();
  if (!render_view) {
    return v8::ThrowException(v8::Exception::Error(v8::String::New(
            "Unable to get render view in GetRoutingIDForCurrentContext")));
  }

  return v8::Integer::New(render_view->GetRoutingID());
}

// static
v8::Handle<v8::Value>
DispatcherBindings::CreateShell(const v8::Arguments& args) {
  if (args.Length() < 2)
    return v8::ThrowException(v8::Exception::Error(v8::String::New(
        "CreateShell requries 2 arguments")));

  std::string url = *v8::String::Utf8Value(args[0]);

  scoped_ptr<V8ValueConverter> converter(V8ValueConverter::create());

  scoped_ptr<base::Value> value_manifest(
      converter->FromV8Value(args[1], v8::Context::GetCurrent()));
  if (!value_manifest.get() ||
      !value_manifest->IsType(base::Value::TYPE_DICTIONARY)) {
    return v8::ThrowException(v8::Exception::Error(v8::String::New(
            "Unable to convert 'options' passed to CreateShell")));
  }

  RenderView* render_view = GetCurrentRenderView();
  if (!render_view) {
    return v8::ThrowException(v8::Exception::Error(v8::String::New(
            "Unable to get render view in CallStaticMethod")));
  }

  int routing_id = -1;
  render_view->Send(new ShellViewHostMsg_CreateShell(
      render_view->GetRoutingID(),
      url,
      *static_cast<base::DictionaryValue*>(value_manifest.get()),
      &routing_id));

  return v8::Integer::New(routing_id);
}

// static
v8::Handle<v8::Value>
DispatcherBindings::AllocateObject(const v8::Arguments& args) {
  if (args.Length() < 3)
    return v8::ThrowException(v8::Exception::Error(v8::String::New(
        "AllocateObject requries 3 arguments")));

  int object_id = args[0]->Int32Value();
  std::string name = *v8::String::Utf8Value(args[1]);

  RenderView* render_view = GetCurrentRenderView();
  if (!render_view) {
    return v8::ThrowException(v8::Exception::Error(v8::String::New(
            "Unable to get render view in AllocateObject")));
  }

  return remote::AllocateObject(
      render_view->GetRoutingID(), object_id, name, args[2]);
}

// static
v8::Handle<v8::Value>
DispatcherBindings::DeallocateObject(const v8::Arguments& args) {
  RenderView* render_view = GetCurrentRenderView();
  if (!render_view) {
    return v8::ThrowException(v8::Exception::Error(v8::String::New(
            "Unable to get render view in DeallocateObject")));
  }

  if (args.Length() < 1)
    return v8::ThrowException(v8::Exception::Error(v8::String::New(
        "DeallocateObject requries 1 arguments")));

  return remote::DeallocateObject(render_view->GetRoutingID(),
                                  args[0]->Int32Value());
}

// static
v8::Handle<v8::Value>
DispatcherBindings::CallObjectMethod(const v8::Arguments& args) {
  if (args.Length() < 4)
    return v8::ThrowException(v8::Exception::Error(v8::String::New(
        "CallObjectMethod requries 4 arguments")));

  int object_id = args[0]->Int32Value();
  std::string type = *v8::String::Utf8Value(args[1]);
  std::string method = *v8::String::Utf8Value(args[2]);

  RenderView* render_view = GetCurrentRenderView();
  if (!render_view) {
    return v8::ThrowException(v8::Exception::Error(v8::String::New(
            "Unable to get render view in CallObjectMethod")));
  }

  return remote::CallObjectMethod(
      render_view->GetRoutingID(), object_id, type, method, args[3]);
}

// static
v8::Handle<v8::Value> DispatcherBindings::CallObjectMethodSync(
    const v8::Arguments& args) {
  if (args.Length() < 4)
    return v8::ThrowException(v8::Exception::Error(v8::String::New(
        "CallObjectMethodSync requries 4 arguments")));

  int object_id = args[0]->Int32Value();
  std::string type = *v8::String::Utf8Value(args[1]);
  std::string method = *v8::String::Utf8Value(args[2]);

  RenderView* render_view = GetCurrentRenderView();
  if (!render_view) {
    return v8::ThrowException(v8::Exception::Error(v8::String::New(
            "Unable to get render view in CallObjectMethod")));
  }

  return remote::CallObjectMethodSync(
      render_view->GetRoutingID(), object_id, type, method, args[3]);
}

// static
v8::Handle<v8::Value> DispatcherBindings::CallStaticMethod(
    const v8::Arguments& args) {
  if (args.Length() < 3) {
    return v8::ThrowException(v8::Exception::Error(v8::String::New(
            "CallStaticMethod requries 3 arguments")));
  }

  std::string type = *v8::String::Utf8Value(args[0]);
  std::string method = *v8::String::Utf8Value(args[1]);

  scoped_ptr<V8ValueConverter> converter(V8ValueConverter::create());

  scoped_ptr<base::Value> value_args(
      converter->FromV8Value(args[2], v8::Context::GetCurrent()));
  if (!value_args.get() ||
      !value_args->IsType(base::Value::TYPE_LIST)) {
    return v8::ThrowException(v8::Exception::Error(v8::String::New(
            "Unable to convert 'args' passed to CallStaticMethod")));
  }

  RenderView* render_view = GetCurrentRenderView();
  if (!render_view) {
    return v8::ThrowException(v8::Exception::Error(v8::String::New(
            "Unable to get render view in CallStaticMethod")));
  }

  render_view->Send(new ShellViewHostMsg_Call_Static_Method(
        render_view->GetRoutingID(),
        type,
        method,
        *static_cast<base::ListValue*>(value_args.get())));
  return v8::Undefined();
}

// static
v8::Handle<v8::Value> DispatcherBindings::CallStaticMethodSync(
    const v8::Arguments& args) {
  if (args.Length() < 3) {
    return v8::ThrowException(v8::Exception::Error(v8::String::New(
            "CallStaticMethodSync requries 3 arguments")));
  }

  std::string type = *v8::String::Utf8Value(args[0]);
  std::string method = *v8::String::Utf8Value(args[1]);

  scoped_ptr<V8ValueConverter> converter(V8ValueConverter::create());

  scoped_ptr<base::Value> value_args(
      converter->FromV8Value(args[2], v8::Context::GetCurrent()));
  if (!value_args.get() ||
      !value_args->IsType(base::Value::TYPE_LIST)) {
    return v8::ThrowException(v8::Exception::Error(v8::String::New(
            "Unable to convert 'args' passed to CallStaticMethodSync")));
  }

  RenderView* render_view = GetCurrentRenderView();
  if (!render_view) {
    return v8::ThrowException(v8::Exception::Error(v8::String::New(
            "Unable to get render view in CallStaticMethodSync")));
  }

  base::ListValue result;
  render_view->Send(new ShellViewHostMsg_Call_Static_Method_Sync(
        MSG_ROUTING_NONE,
        type,
        method,
        *static_cast<base::ListValue*>(value_args.get()),
        &result));
  return converter->ToV8Value(&result, v8::Context::GetCurrent());
}

}  // namespace api


<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
	<key>CFBundleDevelopmentRegion</key>
	<string>en</string>
	<key>CFBundleDisplayName</key>
	<string>${EXECUTABLE_NAME}</string>
	<key>CFBundleExecutable</key>
	<string>${EXECUTABLE_NAME}</string>
	<key>CFBundleIdentifier</key>
	<string>com.intel.nw.helper</string>
	<key>CFBundleInfoDictionaryVersion</key>
	<string>6.0</string>
	<key>CFBundleName</key>
	<string>${PRODUCT_NAME}</string>
	<key>CFBundlePackageType</key>
	<string>APPL</string>
	<key>CFBundleSignature</key>
	<string>????</string>
	<key>LSFileQuarantineEnabled</key>
	<true/>
	<key>LSMinimumSystemVersion</key>
	<string>${MACOSX_DEPLOYMENT_TARGET}.0</string>
	<key>LSUIElement</key>
	<string>1</string>
	<key>NSSupportsAutomaticGraphicsSwitching</key>
	<true/>
</dict>
</plist>


// 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.

// Get basic type definitions.
#define IPC_MESSAGE_IMPL
#include "content/nw/src/renderer/common/render_messages.h"

// Generate constructors.
#include "ipc/struct_constructor_macros.h"
#include "content/nw/src/renderer/common/render_messages.h"

// Generate destructors.
#include "ipc/struct_destructor_macros.h"
#include "content/nw/src/renderer/common/render_messages.h"

// Generate param traits write methods.
#include "ipc/param_traits_write_macros.h"
namespace IPC {
#include "content/nw/src/renderer/common/render_messages.h"
}  // namespace IPC

// Generate param traits read methods.
#include "ipc/param_traits_read_macros.h"
namespace IPC {
#include "content/nw/src/renderer/common/render_messages.h"
}  // namespace IPC

// Generate param traits log methods.
#include "ipc/param_traits_log_macros.h"
namespace IPC {
#include "content/nw/src/renderer/common/render_messages.h"
}  // namespace IPC


keep keep keep keep keep replace keep keep keep keep

this.commitTimer = new vAPI.SafeAnimationFrame(this.commitNow.bind(this));

/*******************************************************************************

    uBlock Origin - a browser extension to block requests.
    Copyright (C) 2017-present Raymond Hill

    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program.  If not, see {http://www.gnu.org/licenses/}.

    Home: https://github.com/gorhill/uBlock
*/

'use strict';

// Packaging this file is optional: it is not necessary to package it if the
// platform is known to not support user stylesheets.

// >>>>>>>> start of HUGE-IF-BLOCK
if ( typeof vAPI === 'object' && vAPI.supportsUserStylesheets ) {

/******************************************************************************/
/******************************************************************************/

vAPI.userStylesheet = {
    added: new Set(),
    removed: new Set(),
    apply: function(callback) {
        if ( this.added.size === 0 && this.removed.size === 0 ) { return; }
        vAPI.messaging.send('vapi', {
            what: 'userCSS',
            add: Array.from(this.added),
            remove: Array.from(this.removed)
        }, callback);
        this.added.clear();
        this.removed.clear();
    },
    add: function(cssText, now) {
        if ( cssText === '' ) { return; }
        this.added.add(cssText);
        if ( now ) { this.apply(); }
    },
    remove: function(cssText, now) {
        if ( cssText === '' ) { return; }
        this.removed.add(cssText);
        if ( now ) { this.apply(); }
    }
};

/******************************************************************************/

vAPI.DOMFilterer = class {
    constructor() {
        this.commitTimer = new vAPI.SafeAnimationFrame(( ) => this.commitNow);
        this.domIsReady = document.readyState !== 'loading';
        this.disabled = false;
        this.listeners = [];
        this.filterset = new Set();
        this.excludedNodeSet = new WeakSet();
        this.addedCSSRules = new Set();
        this.exceptedCSSRules = [];
        this.reOnlySelectors = /\n\{[^\n]+/g;

        // https://github.com/uBlockOrigin/uBlock-issues/issues/167
        //   By the time the DOMContentLoaded is fired, the content script might
        //   have been disconnected from the background page. Unclear why this
        //   would happen, so far seems to be a Chromium-specific behavior at
        //   launch time.
        if ( this.domIsReady !== true ) {
            document.addEventListener('DOMContentLoaded', ( ) => {
                if ( vAPI instanceof Object === false ) { return; }
                this.domIsReady = true;
                this.commit();
            });
        }
    }

    // Here we will deal with:
    // - Injecting low priority user styles;
    // - Notifying listeners about changed filterset.
    // https://www.reddit.com/r/uBlockOrigin/comments/9jj0y1/no_longer_blocking_ads/
    //   Ensure vAPI is still valid -- it can go away by the time we are
    //   called, since the port could be force-disconnected from the main
    //   process. Another approach would be to have vAPI.SafeAnimationFrame
    //   register a shutdown job: to evaluate. For now I will keep the fix
    //   trivial.
    commitNow() {
        this.commitTimer.clear();
        if ( vAPI instanceof Object === false ) { return; }
        const userStylesheet = vAPI.userStylesheet;
        for ( const entry of this.addedCSSRules ) {
            if (
                this.disabled === false &&
                entry.lazy &&
                entry.injected === false
            ) {
                userStylesheet.add(
                    entry.selectors + '\n{' + entry.declarations + '}'
                );
            }
        }
        this.addedCSSRules.clear();
        userStylesheet.apply();
    }

    commit(commitNow) {
        if ( commitNow ) {
            this.commitTimer.clear();
            this.commitNow();
        } else {
            this.commitTimer.start();
        }
    }

    addCSSRule(selectors, declarations, details) {
        if ( selectors === undefined ) { return; }
        const selectorsStr = Array.isArray(selectors)
                ? selectors.join(',\n')
                : selectors;
        if ( selectorsStr.length === 0 ) { return; }
        if ( details === undefined ) { details = {}; }
        const entry = {
            selectors: selectorsStr,
            declarations,
            lazy: details.lazy === true,
            injected: details.injected === true
        };
        this.addedCSSRules.add(entry);
        this.filterset.add(entry);
        if (
            this.disabled === false &&
            entry.lazy !== true &&
            entry.injected !== true
        ) {
            vAPI.userStylesheet.add(selectorsStr + '\n{' + declarations + '}');
        }
        this.commit();
        if ( this.hasListeners() ) {
            this.triggerListeners({
                declarative: [ [ selectorsStr, declarations ] ]
            });
        }
    }

    exceptCSSRules(exceptions) {
        if ( exceptions.length === 0 ) { return; }
        this.exceptedCSSRules.push(...exceptions);
        if ( this.hasListeners() ) {
            this.triggerListeners({ exceptions });
        }
    }

    addListener(listener) {
        if ( this.listeners.indexOf(listener) !== -1 ) { return; }
        this.listeners.push(listener);
    }

    removeListener(listener) {
        const pos = this.listeners.indexOf(listener);
        if ( pos === -1 ) { return; }
        this.listeners.splice(pos, 1);
    }

    hasListeners() {
        return this.listeners.length !== 0;
    }

    triggerListeners(changes) {
        for ( const listener of this.listeners ) {
            listener.onFiltersetChanged(changes);
        }
    }

    excludeNode(node) {
        this.excludedNodeSet.add(node);
        this.unhideNode(node);
    }

    unexcludeNode(node) {
        this.excludedNodeSet.delete(node);
    }

    hideNode(node) {
        if ( this.excludedNodeSet.has(node) ) { return; }
        if ( this.hideNodeAttr === undefined ) { return; }
        node.setAttribute(this.hideNodeAttr, '');
        if ( this.hideNodeStyleSheetInjected === false ) {
            this.hideNodeStyleSheetInjected = true;
            this.addCSSRule(
                `[${this.hideNodeAttr}]`,
                'display:none!important;'
            );
        }
    }

    unhideNode(node) {
        if ( this.hideNodeAttr === undefined ) { return; }
        node.removeAttribute(this.hideNodeAttr);
    }

    toggle(state, callback) {
        if ( state === undefined ) { state = this.disabled; }
        if ( state !== this.disabled ) { return; }
        this.disabled = !state;
        const userStylesheet = vAPI.userStylesheet;
        for ( const entry of this.filterset ) {
            const rule = `${entry.selectors}\n{${entry.declarations}}`;
            if ( this.disabled ) {
                userStylesheet.remove(rule);
            } else {
                userStylesheet.add(rule);
            }
        }
        userStylesheet.apply(callback);
    }

    getAllSelectors_(all) {
        const out = {
            declarative: [],
            exceptions: this.exceptedCSSRules,
        };
        for ( const entry of this.filterset ) {
            let selectors = entry.selectors;
            if ( all !== true && this.hideNodeAttr !== undefined ) {
                selectors = selectors
                                .replace(`[${this.hideNodeAttr}]`, '')
                                .replace(/^,\n|,\n$/gm, '');
                if ( selectors === '' ) { continue; }
            }
            out.declarative.push([ selectors, entry.declarations ]);
        }
        return out;
    }

    getFilteredElementCount() {
        const details = this.getAllSelectors_(true);
        if ( Array.isArray(details.declarative) === false ) { return 0; }
        const selectors = details.declarative.map(entry => entry[0]);
        if ( selectors.length === 0 ) { return 0; }
        return document.querySelectorAll(selectors.join(',\n')).length;
    }

    getAllSelectors() {
        return this.getAllSelectors_(false);
    }
};

/******************************************************************************/
/******************************************************************************/

}
// <<<<<<<< end of HUGE-IF-BLOCK

/*******************************************************************************

    DO NOT:
    - Remove the following code
    - Add code beyond the following code
    Reason:
    - https://github.com/gorhill/uBlock/pull/3721
    - uBO never uses the return value from injected content scripts

**/

void 0;


extension name.

Më në fund, një bllokues efikas që nuk e rëndon procesorin dhe memorjen.

this will be in the Chrome web store: must be 132 characters or less

uBlock₀ — Paneli i kontrollit

English: uBlock₀ — Dashboard

Parametrat

appears as tab name in dashboard

Listat e filtrave

appears as tab name in dashboard

Filtrat e mi

appears as tab name in dashboard

Rregullat e mia

appears as tab name in dashboard

Lista e bardhë

appears as tab name in dashboard

Shkurtoret

appears as tab name in dashboard

uBlock₀ — Regjistri i kërkesave

Title for the logger window

Info

appears as tab name in dashboard

uBlock₀ — Ilustruesi i aseteve

Title for the asset viewer page

Parametra të avancuar

Title for the advanced settings page

Kliko: uBlock₀ bëhet joaktiv/aktiv te ky uebsajti.

Kliko+Ctrl: uBlock₀ bëhet joaktiv vetëm te kjo faqja.

English: Click: disable/enable uBlock₀ for this site.

Ctrl+click: disable uBlock₀ only on this page.

Çaktivizoj uBlock₀ te ky uebsajti.

Klikimi+Ctrl do të çaktivizojë uBlock₀ vetëm te kjo faqja.

Message to be read by screen readers

Aktivizoj uBlock₀ te ky uebsajti.

Message to be read by screen readers

kërkesa të refuzuara

English: requests blocked

te kjo faqja

English: on this page

{{count}} ose {{percent}}%

Example: 15 or 13%

që prej instalimit

English: since install

ose

English: or

Hap panelin e kontrollit

English: Click to open the dashboard

Asgjësuesi i elementeve

Tooltip for the element-zapper icon in the popup panel

Përzgjedhësi i elementeve

English: Enter element picker mode

Regjistri i kërkesave

Tooltip used for the logger icon in the panel

Bllokoj të gjitha dritaret automatike që hap faqja

Tooltip for the no-popups per-site switch

Bllokoj të gjitha dritaret automatike të faqes

Zhbllokoj të gjitha dritaret automatike të faqes

Bllokoj elementet e mëdha multimediale te faqja

Tooltip for the no-large-media per-site switch

Zbllokoj elementet e mëdha multimediale te faqja

Përdor filtrat kozmetikë te faqja

Tooltip for the no-cosmetic-filtering per-site switch

Çaktivizoj filtrat kozmetikë të faqes

Aktivizoj filtrat kozmetikë të faqes

Bllokoj sistemin e shkronjave jashtë faqes

Tooltip for the no-remote-fonts per-site switch

Zhbllokoj sistemin e shkronjave jashtë faqes

Çaktivizoj JavaScript-in te ky uebsajti

Tooltip for the no-scripting per-site switch

Nuk e çaktivizoj më JavaScript-in te ky uebsajti

Rregullat globale: rregullat në këtë shtyllë aplikohen për të gjitha faqet.

Tooltip when hovering the top-most cell of the global-rules column.

Rregullat lokale: rregullat në këtë shtyllë aplikohen vetëm për këtë faqen dhe kanë përparësi mbi rregullat globale.

Tooltip when hovering the top-most cell of the local-rules column.

Ruaj ndryshimet përherë.

Tooltip when hovering over the padlock in the dynamic filtering pane.

Kthej ndryshimet.

Tooltip when hovering over the eraser in the dynamic filtering pane.

të gjitha

imazhet

palët e treta

CSS/imazhet nga palët e treta

skriptet e integruara

skriptet nga pala kryesore

skriptet nga palët e treta

kuadrot nga palët e treta

faqe të kontaktuara

appears in popup

{{count}} nga {{total}}

appears in popup

Krijoj

English: Create

Përzgjedh

English: Pick

Mbyll

English: Quit

Parashikoj

Element picker preview mode: will cause the elements matching the current filter to be removed from the page

Filtrat e rrjetit

English: header for a type of filter in the element picker dialog

Filtrat kozmetikë

English: Cosmetic filters

Kliko, Kliko me Ctrl

English: Click, Ctrl-click

Bllokoj elementin

English: Block element

Fsheh treguesin e elementeve të bllokuara

English: Hide placeholders of blocked elements

Tregoj te ikona numrin e kërkesave të refuzuara

English: Show the number of blocked requests on the icon

Çaktivizoj përshkrimet e shkurtra

A checkbox in the Settings pane

Përdor menunë kontekstuale sipas rrethanave

English: Make use of context menu where appropriate

Përshtat ngjyrat për daltonikët

English: Color-blind friendly

Aktivizoj renë informatike

Kam njohuri të avancuara (Lexim i detyruar)

parametra të avancuar

For the tooltip of a link which gives access to advanced settings

Çaktivizoj kërkesat paraprake (për të evituar çdo lidhje me kërkesat e refuzuara)

English:

Çaktivizoj analizën e lidhjeve hipertekstuale

English:

Nuk lejoj WebRTC-në që të zbulojë adresat IP lokale

English:

Vlerat standarde

Këto vlera mund të ndryshohen në bazë të faqeve

Çaktivizoj filtrat kozmetikë

Bllokoj elementet multimediale më të mëdha se {{input:number}} kB

Çaktivizoj JavaScript-in

The default state for the per-site no-scripting switch

Bllokoj raportet e CSP-së

background information: https://github.com/gorhill/uBlock/issues/3150

Hapësira e përdorur: {{value}} bajt

English: Storage used: {{}} bytes

Rindërtimi i fundit:

English: Last restore:

Kopja e fundit:

English: Last backup:

{{netFilterCount}} filtra të rrjetit ＋ {{cosmeticFilterCount}} filtra kozmetikë nga:

Appears at the top of the _3rd-party filters_ pane

përdor {{used}} nga {{total}}

Appears aside each filter list in the _3rd-party filters_ pane

Përditësoj filtrat automatikisht

A checkbox in the _3rd-party filters_ pane

Përditësoj tani

A button in the in the _3rd-party filters_ pane

Heq të gjitha stoqet

Analizoj dhe zbatoj filtrat kozmetikë

English: Parse and enforce Adblock+ element hiding filters.

Ky opsion lejon analizimin dhe zbatimin e filtrave “eliminues” njësoj si në Adblock Plus. Këta filtra kozmetikë shërbejnë kryesisht për të fshehur nga ana vizive elementet e padëshirueshme të cilat nuk bllokohen me metodën standarde të filtrimit.

Aktivizimi i kësaj veçorie rrit impaktin e uBlock₀ te memorja e kompjuterit.

Describes the purpose of the 'Parse and enforce cosmetic filters' feature.

Nuk marr parasysh filtrat kozmetikë jospecifikë

This will cause uBO to ignore all generic cosmetic filters.

Filtrat kozmetikë jospecifikë janë filtra kozmetikë të cilët aplikohen për të gjitha faqet e internetit.
Megjithëse uBlock₀ i përdor ata me efikasitet, filtrat kozmetikë jospecifikë përsëri mund të rëndojnë memorjen dhe procesorin e kompjuterit në faqet e gjata.
Aktivizimi i këtij opsioni eliminon peshën e tepërt te memorja dhe procesori, dhe zvogëlon impaktin e uBlock₀ te memorja e kompjuterit.
Rekomandohet që ky opsion të aktivizohet për aparatet jo shumë të shpejta.

Describes the purpose of the 'Ignore generic cosmetic filters' feature.

Lista e hosteve të bllokuara

English: Lists of blocked hosts

Ruaj ndryshimet

English: Apply changes

Lokalë

Header for the uBlock filters section in 'Filter lists pane'

Reklamat

English: Ads

Privatësia

English: Privacy

Domenet e dëmshme

English: Malware domains

Elementet e bezdisshme

The header identifying the filter lists in the category 'annoyances'

Për qëllime të ndryshme

English: Multipurpose

Sipas rajonit, gjuhës

English: Regions, languages

Personalizoj

English: Custom

Importoj...

The label for the checkbox used to import external filter lists

Një URL për rresht. Nuk do të merren parasysh adresat e pasakta.

Short information about how to use the textarea to import external filter lists by URL

E vjetër.

used as a tooltip for the out-of-date icon beside a list

Përditësimi i fundit: {{ago}}.
Klikoni për ta kryer vetë përditësimin.

used as a tooltip for the clock icon beside a list

Po përditësohet...

used as a tooltip for the spinner icon beside a list

Një problem me rrjetin pengoi përditësimin e informacionit.

used as a tooltip for error icon beside a list

Një filtër për rresht. Filtri mund të jetë thjesht emri i një hosti ose i ngjashëm me ata që përdor Adblock Plus. Nuk do të merren parasysh rreshtat që fillojnë me <code>!</code>.

Short information about how to create custom filters

Importoj dhe shtoj

English: Import and append

Eksportoj

English: Export

my-ublock-static-filters_{{datetime}}.txt

English: my-ublock-static-filters_{{datetime}}.txt

Ruaj ndryshimet

English: Apply changes

Rregulla të përhershme

header

Rregulla të përkohshme

header

Rikthej

This will remove all temporary rules

Aplikoj

This will persist temporary rules

Modifikoj

Will enable manual-edit mode (textarea)

Regjistroj

Will save manually-edited content and exit manual-edit mode

Anuloj

Will discard manually-edited content and exit manual-edit mode

Importoj nga skedari...

Ruaj në skedar

my-ublock-dynamic-rules_{{datetime}}.txt

default file name to use

Lista e rregullave për filtrimin dinamik.

English: List of your dynamic filtering rules.

Rregullat e sintaksës: burimi destinacioni lloji veprimi (dokumentimi i plotë).

English: dynamic rule syntax and full documentation.

Lista e bardhë e detyron uBlock Origin të mos veprojë në faqe të caktuara. Një element për rresht. Nuk do të merren parasysh udhëzimet e pasakta.

English: An overview of the content of the dashboard's Whitelist pane.

Importoj dhe shtoj

English: Import and append

Eksportoj

English: Export

English: my-ublock-whitelist_{{datetime}}.txt

Ruaj ndryshimet

English: Apply changes

Lloji

English: Type

Domeni

English: Domain

URL

English: URL

Filtri

English: Filter

Të gjitha

Appears in the logger's tab selector

Në prapaskenë

Pretty name for behind-the-scene network requests

Skeda aktuale

Appears in the logger's tab selector

Ngarko përmbajten e skedës

Tooltip for the reload button in the logger page

Përdor ispektorin DOM

Tooltip for the DOM inspector button in the logger page

Përdor panelin e dritareve automatike

Tooltip for the popup panel button in the logger page

uBlock Origin wiki: Regjistri

Tooltip for the top-right info label in the logger page

Pastro regjistrin

Tooltip for the eraser in the logger page; used to blank the content of the logger

Ndalo regjistrin (fshin të gjithë të dhënat në hyrje)

Tooltip for the pause button in the logger page

Nis regjistrin

Tooltip for the play button in the logger page

Përdor filtrin e regjistrit

Tooltip for the row filterer button in the logger page

filtroni elementet në regjistër

Placeholder string for logger output filtering input field

Zgjedhni filtrat e regjistrimit

Tooltip for the button to bring up logger output filtering options

Nuk

A keyword in the built-in row filtering expression

plot ngjarje

A keyword in the built-in row filtering expression: all items corresponding to uBO doing something (blocked, allowed, redirected, etc.)

të bllokuara

të lejuara

palët e para

palët e treta

Detalet

Small header to identify the 'Details' pane for a specific logger entry

Filtra

Label to identify a filter field

Lista e filtrave

Label to identify a filter list field

Rregulla

Label to identify a rule field

Konteksti

Label to identify a context field (typically a hostname)

Konteksti kryesor

Label to identify a root context field (typically a hostname)

Pjesa e kërkesës

Label to identify a field providing partyness information

Tip

Label to identify the type of an entry

URL

Label to identify the URL of an entry

Filtrim dinamik i adresave

Small header to identify the dynamic URL filtering section

Konteksti:

Label for the context selector

Lloji:

Label for the type selector

Filtrim statik

Small header to identify the static filtering section

{{action}} kërkesat e {{type}} {{br}}adresa e të cilave korrespondon me {{url}} {{br}}dhe që e kanë origjinën {{origin}},{{br}}{{importance}} ekziston një filtër përjashtues i ngjashëm.

Used in the static filtering wizard

Bllokoj

Used in the static filtering wizard

Lejoj

Used in the static filtering wizard

llojit “{{type}}”

Used in the static filtering wizard

çdo lloji

Used in the static filtering wizard

nga “{{origin}}”

Used in the static filtering wizard

ngado

Used in the static filtering wizard

përveçse kur

Used in the static filtering wizard

edhe kur

Used in the static filtering wizard

Filtri statik <code>{{filter}}</code> gjendet në:

Below this sentence, the filter list(s) in which the filter was found

Filtri statik <code>{{filter}}</code> nuk gjendet në asnjërën nga listat aktive

Message to show when a filter cannot be found in any filter lists

Regjistrimi i regjistrit që nuk plotëson të tri kushtet e mëposhtme automatikisht do të fshihet:

Logger setting: A sentence to describe the purpose of the settings below

Mbaj shënimet për {{input}} minutat e fundit

A logger setting

Mbaje më së shumti {{input}} ngarkime faqe për skedë

A logger setting

Mbaje më së shumti {{input}} shënime për kartë

A logger setting

Përdor {{input}} rreshta për artikull në mënyrë të zgjeruar vertikalisht

A logger setting

Fshih kolonat:

Logger settings: a sentence to describe the purpose of the checkboxes below

{{input}} Koha

A label for the time column

{{input}} Filtra/rregulla

A label for the filter or rule column

{{input}} Konteksti

A label for the context column

{{input}} Pjesa e kërkesës

A label for the partyness column

Lista

Label for radio-button to pick export format

Tabella

Thjeshtë

Label for radio-button to pick export text format

Markdown

Ditari i ndryshimeve

Wiki

English: project' wiki on GitHub

Mbështetja teknike

A link for where to get support

Lista e problemeve

Text for a link to official issue tracker

Materiali burimor (GPLv3)

English: Source code (GPLv3)

Kontribuesit

English: Contributors

Programe kushtëzuese (përshtatet me GPLv3):

Shown in the About pane

Kopjoj në skedar

Text for button to create a backup of all settings

English: my-ublock-backup_{{datetime}}.txt

Rindërtoj sipas skedarit...

English: Restore from file...

Kthej parametrat fillestarë...

English: Reset to default settings...

Të gjithë parametrat do të mbishkruhen me të dhënat e kopjuara më {{time}}, dhe uBlock₀ do të hapet përsëri.

Të mbishkruhen parametrat aktualë?

Message asking user to confirm restore

Të dhënat nuk lexohen ose mund të jenë dëmtuar

Message to display when an error occurred during restore

Të gjithë parametrat do të fshihen dhe uBlock₀ do të hapet përsëri.

Të kthehen parametrat origjinalë?

Message asking user to confirm reset

Problem me rrjetin: {{msg}}

English: Network error: {{msg}}

uBlock₀: Të shtohet adresa në listën e filtrave tuaj?

Titulli: "{{title}}"
URL: {{url}}

English: The message seen by the user to confirm subscription to a ABP filter list

një minutë më parë

English: a minute ago

{{value}} minuta më parë

English: {{value}} minutes ago

një orë më parë

English: an hour ago

{{value}} orë më parë

English: {{value}} hours ago

një ditë më parë

English: a day ago

{{value}} ditë më parë

English: {{value}} days ago

Paneli i kontrollit

Firefox/Fennec-specific: Show Dashboard

Regjistri i kërkesave

Firefox/Fennec-specific: Show Logger

fikur

Firefox-specific: appears as 'uBlock₀ (off)'

uBlock Origin po pengon hapjen e faqes:

English: uBlock₀ has prevented the following page from loading:

Për shkak të filtrit

English: Because of the following filter

pa parametra

label to be used for the parameter-less URL: https://cloud.githubusercontent.com/assets/585534/9832014/bfb1b8f0-593b-11e5-8a27-fba472a5529a.png

Gjendet në:

English: List of filter list names follows

Kthehem

English: Go back

Mbyll dritaren

English: Close this window

Zhbllokoj mënyrën strikte për {{hostname}}

English: Disable strict blocking for {{hostname}} ...

Përkohësisht

English: Temporarily

Gjithmonë

English: Permanently

Eksportoj në renë informatike

tooltip

Importoj nga reja informatike

tooltip

Importoj nga reja informatike dhe bashkoj me parametrat aktualë

tooltip

Emri i aparatit:

used as a prompt for the user to provide a custom device name

Kujdes! Përgjegjësia për ndryshimin e këtyre parametrave bie mbi ju.

A warning to users at the top of 'Advanced settings' page

Parashtroj

for generic 'Submit' buttons

Ruaj ndryshimet

for generic 'Apply changes' buttons

Rikthej

for generic 'Revert' buttons

bajt

Lejoj përkohësisht elementet multimediale me përmasa të mëdha

A context menu entry, present when large media elements have been blocked on the current site

Vendosni kombinimin

Placeholder string for input field used to capture a keyboard shortcut

Bllokoj shiritin e lëvizjes

Tooltip for the button used to lock scrolling between the views in the 'My rules' pane

Kopjo në kujtesën

Label for buttons used to copy something to the clipboard

This entry must be the last one

so we dont need to deal with comma for last entry


Действащ блокер: щадящ паметта и процесора, но и способен да зареди и наложи хиляди филтри в сравнение с други популярни блокери.

Илюстрация на неговата ефикасност: https://github.com/gorhill/uBlock/wiki/uBlock-vs.-ABP:-efficiency-compared

Използване: големият бутон за включване в изскачащия прозорец забранява/разрешава uBlock в текущия сайт. Приложим само за текущия сайт, не действа глобално.

***

Гъвкав, нещо повече от „блокер на реклами“: чете и създава филтри на базата на файлове с хостове.

Първоначално са заредени и наложени следните филтри:

- EasyList
- списък с рекламни сървъри от Peter Lowe
- EasyPrivacy
- вредоносни домейни

Aко желаете, на разположение са допълнителни списъци, които да изберете:

- разширен проследяващ списък от Fanboy
- файл с хостове от Dan Pollock
- рекламни и проследяващи сървъри от hpHosts
- MVPS HOSTS
- Spam404
- и много други

Разбира се, колкото повече списъци включите, толкова по-голямо е използването на паметта. Въпреки това, дори и след добавяне на двата допълнителни списъка от Fanboy, рекламните и проследяващи сървъри от hpHosts, uBlock₀ използва по-малко памет в сравнение с други много популярни блокери.

Имайте също така предвид, че избирането на определени допълнителни списъци може да доведе с голяма степен на вероятност до неправилно функциониране на сайтовете — особено тези, които по принцип се ползват като файл с хостове.

***

Без предварително зададените списъци с филтри, това разширение е нищо. Така че, ако някога наистина искате да допринесете с нещо, помислете за хората, работещи усилено по поддържането на списъците с филтри, предоставени ви за безплатно използване от всички.

***

Безплатно.
Отворен код с публичен лиценз (GPLv3)
За потребители от потребители.

Сътрудници @ Github: https://github.com/gorhill/uBlock/graphs/contributors
Сътрудници @ Crowdin: https://crowdin.net/project/ublock

***

Това е доста ранна версия, имайте го предвид, когато я разглеждате.

Списък с промени на проекта:
https://github.com/gorhill/uBlock/releases


/*******************************************************************************

    uBlock Origin - a browser extension to block requests.
    Copyright (C) 2018-present Raymond Hill

    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program.  If not, see {http://www.gnu.org/licenses/}.

    Home: https://github.com/gorhill/uBlock
*/

'use strict';

(function() {

    // https://developer.mozilla.org/en-US/Add-ons/WebExtensions/manifest.json/commands#Shortcut_values
    let validStatus0Keys = new Map([
        [ 'alt', 'Alt' ],
        [ 'control', 'Ctrl' ],
    ]);
    let validStatus1Keys = new Map([
        [ 'a', 'A' ],
        [ 'b', 'B' ],
        [ 'c', 'C' ],
        [ 'd', 'D' ],
        [ 'e', 'E' ],
        [ 'f', 'F' ],
        [ 'g', 'G' ],
        [ 'h', 'H' ],
        [ 'i', 'I' ],
        [ 'j', 'J' ],
        [ 'k', 'K' ],
        [ 'l', 'L' ],
        [ 'm', 'M' ],
        [ 'n', 'N' ],
        [ 'o', 'O' ],
        [ 'p', 'P' ],
        [ 'q', 'Q' ],
        [ 'r', 'R' ],
        [ 's', 'S' ],
        [ 't', 'T' ],
        [ 'u', 'U' ],
        [ 'v', 'V' ],
        [ 'w', 'W' ],
        [ 'x', 'X' ],
        [ 'y', 'Y' ],
        [ 'z', 'Z' ],
        [ '0', '0' ],
        [ '1', '1' ],
        [ '2', '2' ],
        [ '3', '3' ],
        [ '4', '4' ],
        [ '5', '5' ],
        [ '6', '6' ],
        [ '7', '7' ],
        [ '8', '8' ],
        [ '9', '9' ],
        [ 'f1', 'F1' ],
        [ 'f2', 'F2' ],
        [ 'f3', 'F3' ],
        [ 'f4', 'F4' ],
        [ 'f5', 'F5' ],
        [ 'f6', 'F6' ],
        [ 'f7', 'F7' ],
        [ 'f8', 'F8' ],
        [ 'f9', 'F9' ],
        [ 'f10', 'F10' ],
        [ 'f11', 'F11' ],
        [ 'f12', 'F12' ],
        [ ' ', 'Space' ],
        [ ',', 'Comma' ],
        [ '.', 'Period' ],
        [ 'home', 'Home' ],
        [ 'end', 'End' ],
        [ 'pageup', 'PageUp' ],
        [ 'pagedown', 'PageDown' ],
        [ 'insert', 'Insert' ],
        [ 'delete', 'Delete' ],
        [ 'arrowup', 'Up' ],
        [ 'arrowdown', 'Down' ],
        [ 'arrowleft', 'Left' ],
        [ 'arrowright', 'Right' ],
        [ 'shift', 'Shift' ],
    ]);

    let commandNameFromElement = function(elem) {
        while ( elem !== null ) {
            let name = elem.getAttribute('data-name');
            if ( typeof name === 'string' && name !== '' ) { return name; }
            elem = elem.parentElement;
        }
    };

    let captureShortcut = function(ev) {
        let input = ev.target;
        let name = commandNameFromElement(input);
        if ( name === undefined ) { return; }

        let before = input.value;
        let after = new Set();
        let status = 0;

        let updateCapturedShortcut = function() {
            return (input.value = Array.from(after).join('+'));
        };

        let blurHandler = function() {
            input.removeEventListener('blur', blurHandler, true);
            input.removeEventListener('keydown', keydownHandler, true);
            input.removeEventListener('keyup', keyupHandler, true);
            if ( status === 2 ) {
                vAPI.messaging.send(
                    'dashboard',
                    { what: 'setShortcut', name: name, shortcut: updateCapturedShortcut() }
                );
            } else {
                input.value = before;
            }
        };

        let keydownHandler = function(ev) {
            ev.preventDefault();
            ev.stopImmediatePropagation();
            if ( ev.code === 'Escape' ) {
                input.blur();
                return;
            }
            if ( status === 0 ) {
                let keyName = validStatus0Keys.get(ev.key.toLowerCase());
                if ( keyName !== undefined ) {
                    after.add(keyName);
                    updateCapturedShortcut();
                    status = 1;
                }
                return;
            }
            if ( status === 1 ) {
                if ( ev.key === 'Shift' ) {
                    after.add('Shift');
                    updateCapturedShortcut();
                    return;
                }
                let keyName = validStatus1Keys.get(ev.key.toLowerCase());
                if ( keyName !== undefined ) {
                    after.add(keyName);
                    updateCapturedShortcut();
                    status = 2;
                    input.blur();
                    return;
                }
            }
        };

        let keyupHandler = function(ev) {
            ev.preventDefault();
            ev.stopImmediatePropagation();
            if ( status !== 1 ) { return; }
            let keyName = validStatus0Keys.get(ev.key.toLowerCase());
            if ( keyName !== undefined && after.has(keyName) ) {
                after.clear();
                updateCapturedShortcut();
                status = 0;
                return;
            }
            if ( ev.key === 'Shift' ) {
                after.delete('Shift');
                updateCapturedShortcut();
                return;
            }
        };

        input.value = '';
        input.addEventListener('blur', blurHandler, true);
        input.addEventListener('keydown', keydownHandler, true);
        input.addEventListener('keyup', keyupHandler, true);
    };

    let resetShortcut = function(ev) {
        let name = commandNameFromElement(ev.target);
        if ( name === undefined ) { return; }

        let input = document.querySelector('[data-name="' + name + '"] input');
        if ( input === null ) { return; }
        input.value = '';
        vAPI.messaging.send(
            'dashboard',
            { what: 'setShortcut', name: name }
        );
    };

    let onShortcutsReady = function(commands) {
        if ( Array.isArray(commands) === false ) { return; }
        let template = document.querySelector('#templates .commandEntry');
        let tbody = document.querySelector('.commandEntries tbody');
        for ( let command of commands ) {
            if ( command.description === '' ) { continue; }
            let tr = template.cloneNode(true);
            tr.setAttribute('data-name', command.name);
            tr.querySelector('.commandDesc').textContent = command.description;
            let input = tr.querySelector('.commandShortcut input');
            input.setAttribute('data-name', command.name);
            input.value = command.shortcut;
            input.addEventListener('focus', captureShortcut);
            tr.querySelector('.commandReset').addEventListener('click', resetShortcut);
            tbody.appendChild(tr);
        }
    };

    vAPI.messaging.send('dashboard', { what: 'getShortcuts' }, onShortcutsReady);

})();