"use strict";
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
const browser = require("../../../base/browser/browser.js");
const dom = require("../../../base/browser/dom.js");
const async = require("../../../base/common/async.js");
const lifecycle = require("../../../base/common/lifecycle.js");
const layoutService = require("../../layout/browser/layoutService.js");
const log = require("../../log/common/log.js");
var __decorate = globalThis && globalThis.__decorate || function(decorators, target, key, desc) {
  var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
  if (typeof Reflect === "object" && typeof Reflect.decorate === "function")
    r = Reflect.decorate(decorators, target, key, desc);
  else
    for (var i = decorators.length - 1; i >= 0; i--)
      if (d = decorators[i])
        r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
  return c > 3 && r && Object.defineProperty(target, key, r), r;
};
var __param = globalThis && globalThis.__param || function(paramIndex, decorator) {
  return function(target, key) {
    decorator(target, key, paramIndex);
  };
};
var __awaiter = globalThis && globalThis.__awaiter || function(thisArg, _arguments, P, generator) {
  function adopt(value) {
    return value instanceof P ? value : new P(function(resolve) {
      resolve(value);
    });
  }
  return new (P || (P = Promise))(function(resolve, reject) {
    function fulfilled(value) {
      try {
        step(generator.next(value));
      } catch (e) {
        reject(e);
      }
    }
    function rejected(value) {
      try {
        step(generator["throw"](value));
      } catch (e) {
        reject(e);
      }
    }
    function step(result) {
      result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected);
    }
    step((generator = generator.apply(thisArg, _arguments || [])).next());
  });
};
exports.BrowserClipboardService = class BrowserClipboardService extends lifecycle.Disposable {
  constructor(layoutService2, logService) {
    super();
    this.layoutService = layoutService2;
    this.logService = logService;
    this.mapTextToType = /* @__PURE__ */ new Map();
    this.findText = "";
    if (browser.isSafari || browser.isWebkitWebView) {
      this.installWebKitWriteTextWorkaround();
    }
  }
  // In Safari, it has the following note:
  //
  // "The request to write to the clipboard must be triggered during a user gesture.
  // A call to clipboard.write or clipboard.writeText outside the scope of a user
  // gesture(such as "click" or "touch" event handlers) will result in the immediate
  // rejection of the promise returned by the API call."
  // From: https://webkit.org/blog/10855/async-clipboard-api/
  //
  // Since extensions run in a web worker, and handle gestures in an asynchronous way,
  // they are not classified by Safari as "in response to a user gesture" and will reject.
  //
  // This function sets up some handlers to work around that behavior.
  installWebKitWriteTextWorkaround() {
    const handler = () => {
      const currentWritePromise = new async.DeferredPromise();
      if (this.webKitPendingClipboardWritePromise && !this.webKitPendingClipboardWritePromise.isSettled) {
        this.webKitPendingClipboardWritePromise.cancel();
      }
      this.webKitPendingClipboardWritePromise = currentWritePromise;
      navigator.clipboard.write([new ClipboardItem({
        "text/plain": currentWritePromise.p
      })]).catch((err) => __awaiter(this, void 0, void 0, function* () {
        if (!(err instanceof Error) || err.name !== "NotAllowedError" || !currentWritePromise.isRejected) {
          this.logService.error(err);
        }
      }));
    };
    if (this.layoutService.hasContainer) {
      this._register(dom.addDisposableListener(this.layoutService.container, "click", handler));
      this._register(dom.addDisposableListener(this.layoutService.container, "keydown", handler));
    }
  }
  writeText(text, type) {
    return __awaiter(this, void 0, void 0, function* () {
      if (type) {
        this.mapTextToType.set(type, text);
        return;
      }
      if (this.webKitPendingClipboardWritePromise) {
        return this.webKitPendingClipboardWritePromise.complete(text);
      }
      try {
        return yield navigator.clipboard.writeText(text);
      } catch (error) {
        console.error(error);
      }
      const activeElement = document.activeElement;
      const textArea = document.body.appendChild(dom.$("textarea", { "aria-hidden": true }));
      textArea.style.height = "1px";
      textArea.style.width = "1px";
      textArea.style.position = "absolute";
      textArea.value = text;
      textArea.focus();
      textArea.select();
      document.execCommand("copy");
      if (activeElement instanceof HTMLElement) {
        activeElement.focus();
      }
      document.body.removeChild(textArea);
      return;
    });
  }
  readText(type) {
    return __awaiter(this, void 0, void 0, function* () {
      if (type) {
        return this.mapTextToType.get(type) || "";
      }
      try {
        return yield navigator.clipboard.readText();
      } catch (error) {
        console.error(error);
        return "";
      }
    });
  }
  readFindText() {
    return __awaiter(this, void 0, void 0, function* () {
      return this.findText;
    });
  }
  writeFindText(text) {
    return __awaiter(this, void 0, void 0, function* () {
      this.findText = text;
    });
  }
};
exports.BrowserClipboardService = __decorate([
  __param(0, layoutService.ILayoutService),
  __param(1, log.ILogService)
], exports.BrowserClipboardService);
