import { __esDecorate, __runInitializers } from "tslib";
import { LitElement, html } from 'lit';
import { property, query } from 'lit/decorators.js';
import { PrismHighlighter } from './PrismHighlighter.js';
let PrismHighlight = (() => {
    let _classSuper = LitElement;
    let _code_decorators;
    let _code_initializers = [];
    let _code_extraInitializers = [];
    let _lang_decorators;
    let _lang_initializers = [];
    let _lang_extraInitializers = [];
    let _raw_decorators;
    let _raw_initializers = [];
    let _raw_extraInitializers = [];
    let _outputElement_decorators;
    let _outputElement_initializers = [];
    let _outputElement_extraInitializers = [];
    return class PrismHighlight extends _classSuper {
        static {
            const _metadata = typeof Symbol === "function" && Symbol.metadata ? Object.create(_classSuper[Symbol.metadata] ?? null) : void 0;
            _code_decorators = [property({ type: String })];
            _lang_decorators = [property({ type: String, reflect: true })];
            _raw_decorators = [property({ type: Boolean, reflect: true })];
            _outputElement_decorators = [query('code')];
            __esDecorate(this, null, _code_decorators, { kind: "accessor", name: "code", static: false, private: false, access: { has: obj => "code" in obj, get: obj => obj.code, set: (obj, value) => { obj.code = value; } }, metadata: _metadata }, _code_initializers, _code_extraInitializers);
            __esDecorate(this, null, _lang_decorators, { kind: "accessor", name: "lang", static: false, private: false, access: { has: obj => "lang" in obj, get: obj => obj.lang, set: (obj, value) => { obj.lang = value; } }, metadata: _metadata }, _lang_initializers, _lang_extraInitializers);
            __esDecorate(this, null, _raw_decorators, { kind: "accessor", name: "raw", static: false, private: false, access: { has: obj => "raw" in obj, get: obj => obj.raw, set: (obj, value) => { obj.raw = value; } }, metadata: _metadata }, _raw_initializers, _raw_extraInitializers);
            __esDecorate(this, null, _outputElement_decorators, { kind: "accessor", name: "outputElement", static: false, private: false, access: { has: obj => "outputElement" in obj, get: obj => obj.outputElement, set: (obj, value) => { obj.outputElement = value; } }, metadata: _metadata }, _outputElement_initializers, _outputElement_extraInitializers);
            if (_metadata) Object.defineProperty(this, Symbol.metadata, { enumerable: true, configurable: true, writable: true, value: _metadata });
        }
        #code_accessor_storage = __runInitializers(this, _code_initializers, void 0);
        /**
         * A data to be highlighted and rendered.
         * @attribute
         */
        get code() { return this.#code_accessor_storage; }
        set code(value) { this.#code_accessor_storage = value; }
        #lang_accessor_storage = (__runInitializers(this, _code_extraInitializers), __runInitializers(this, _lang_initializers, ''
        /**
         * When set it ignores syntax highlighting and only renders the code.
         * @attribute
         */
        ));
        /**
         * Prism supported language.
         * @attribute
         */
        get lang() { return this.#lang_accessor_storage; }
        set lang(value) { this.#lang_accessor_storage = value; }
        #raw_accessor_storage = (__runInitializers(this, _lang_extraInitializers), __runInitializers(this, _raw_initializers, void 0));
        /**
         * When set it ignores syntax highlighting and only renders the code.
         * @attribute
         */
        get raw() { return this.#raw_accessor_storage; }
        set raw(value) { this.#raw_accessor_storage = value; }
        #outputElement_accessor_storage = (__runInitializers(this, _raw_extraInitializers), __runInitializers(this, _outputElement_initializers, void 0));
        get outputElement() { return this.#outputElement_accessor_storage; }
        set outputElement(value) { this.#outputElement_accessor_storage = value; }
        highlighter = (__runInitializers(this, _outputElement_extraInitializers), new PrismHighlighter(this.handleHighlight.bind(this)));
        tokenizeResults;
        updated(cp) {
            super.updated(cp);
            if (cp.has('code') || cp.has('lang')) {
                this.highlight();
            }
            if (cp.has('raw')) {
                this.rawChanged();
            }
        }
        firstUpdated() {
            /* istanbul ignore if */
            if (this.tokenizeResults && !this.raw) {
                const out = this.outputElement;
                if (out) {
                    out.innerHTML += this.tokenizeResults;
                }
                this.tokenizeResults = undefined;
            }
        }
        // Resets the state of the render to initial state.
        reset() {
            const node = this.outputElement;
            if (node) {
                node.innerHTML = '';
            }
        }
        handleHighlight(code) {
            const node = this.outputElement;
            /* istanbul ignore else */
            if (node) {
                node.innerHTML += code;
            }
            else {
                this.tokenizeResults = code;
            }
        }
        rawChanged() {
            if (!this.raw) {
                this.highlight();
            }
        }
        /**
         * Highlights the code.
         */
        highlight() {
            const { code, lang, raw } = this;
            if ((!code && lang) || raw) {
                return;
            }
            this.reset();
            this.highlighter.debounce(code || '', lang);
        }
        /**
         * Handler for click events.
         */
        handleLinks(e) {
            const el = e.target;
            if (el.localName !== 'a') {
                return;
            }
            const link = el;
            const newEntity = e.ctrlKey || e.metaKey;
            e.preventDefault();
            e.stopPropagation();
            e.stopImmediatePropagation();
            const url = link.href;
            this.dispatchEvent(new CustomEvent('link', {
                detail: {
                    url,
                    asNew: newEntity,
                },
            }));
        }
        render() {
            const { raw } = this;
            return raw ? this.renderRaw() : this.renderHighlighted();
        }
        renderHighlighted() {
            return html `
      <pre class="parsed-content">
      <code id="output" class="language-" @click="${this.handleLinks}"></code>
    </pre>
    `;
        }
        renderRaw() {
            return html `
      <pre class="raw-content">
      <code id="output" class="raw">${this.code}</code>
    </pre>
    `;
        }
    };
})();
/**
 * Syntax highlighting via Prism
 *
 * ### Example
 *
 * ```html
 * <prism-highlight id="c1" lang="markdown"></prism-highlight>
 * <script>
 *  document.querySelector('#c1').code = '# Test highlight';
 * &lt;/script>
 * ```
 *
 * The `lang` attribute is required and the component will not start parsing data without it.
 *
 * Changing the `lang` and `code` properties together, do it in less than 10 ms.
 * The element is set to commit changes after this time period. Otherwise it may display
 * old and new code due to the asynchronous nature of the code highlighter.
 *
 * @fires link - An event dispatched when the user click on the link. The detail object has the `url`
 *               property with the link value and the `asNew` property set to `true` when ctrl/cmd
 *               key was pressed when the link was clicked.
 */
export default PrismHighlight;
//# sourceMappingURL=PrismHighlight.js.map