<commit_before>import Component from '@ember/component';
import countWords from '../utils/count-words';
import layout from '../templates/components/koenig-card-embed';
import noframe from 'noframe.js';
import {NO_CURSOR_MOVEMENT} from './koenig-editor';
import {computed} from '@ember/object';
import {isBlank} from '@ember/utils';
import {run} from '@ember/runloop';
import {inject as service} from '@ember/service';
import {set} from '@ember/object';
import {task} from 'ember-concurrency';

export default Component.extend({
    ajax: service(),
    ghostPaths: service(),

    layout,

    // attrs
    payload: null,
    isSelected: false,
    isEditing: false,

    // internal properties
    hasError: false,

    // closure actions
    selectCard() {},
    deselectCard() {},
    editCard() {},
    saveCard() {},
    deleteCard() {},
    moveCursorToNextSection() {},
    moveCursorToPrevSection() {},
    addParagraphAfterCard() {},
    registerComponent() {},

    counts: computed('payload.{html,caption}', function () {
        return {
            imageCount: this.payload.html ? 1 : 0,
            wordCount: countWords(this.payload.caption)
        };
    }),

    init() {
        this._super(...arguments);
        if (this.payload.url && !this.payload.html) {
            this.convertUrl.perform(this.payload.url);
        }

        this.registerComponent(this);
    },

    didInsertElement() {
        this._super(...arguments);
        this._populateIframe();
        this._focusInput();
    },

    willDestroyElement() {
        this._super(...arguments);

        run.cancel(this._resizeDebounce);

        if (this._iframeMutationObserver) {
            this._iframeMutationObserver.disconnect();
        }

        window.removeEventListener('resize', this._windowResizeHandler);
    },

    actions: {
        onDeselect() {
            if (this.payload.url && !this.payload.html && !this.hasError) {
                this.convertUrl.perform(this.payload.url);
            } else {
                this._deleteIfEmpty();
            }
        },

        updateUrl(event) {
            let url = event.target.value;
            set(this.payload, 'url', url);
        },

        urlKeydown(event) {
            if (event.key === 'Enter') {
                event.preventDefault();
                this.convertUrl.perform(this.payload.url);
            }

            if (event.key === 'Escape') {
                event.target.blur();
                this.deleteCard();
            }
        },

        updateCaption(caption) {
            set(this.payload, 'caption', caption);
            this.saveCard(this.payload, false);
        },

        retry() {
            this.set('hasError', false);
        },

        insertAsLink(options = {linkOnError: false}) {
            let {range} = this.editor;

            this.editor.run((postEditor) => {
                let {builder} = postEditor;
                let cardSection = this.env.postModel;
                let p = builder.createMarkupSection('p');
                let link = builder.createMarkup('a', {href: this.payload.url});

                postEditor.replaceSection(cardSection, p);
                postEditor.insertTextWithMarkup(p.toRange().head, this.payload.url, [link]);

                // if a user is typing further on in the doc (possible if embed
                // was created automatically via paste of URL) then return the
                // cursor so the card->link change doesn't cause a cursor jump
                if (range.headSection !== cardSection) {
                    postEditor.setRange(range);
                }

                // avoid adding an extra undo step when automatically creating
                // link after an error so that an Undo after pasting a URL
                // doesn't get stuck in a loop going through link->embed->link
                if (options.linkOnError) {
                    postEditor.cancelSnapshot();
                }
            });
        }
    },

    convertUrl: task(function* (url) {
        if (isBlank(url)) {
            this.deleteCard();
            return;
        }

        try {
            let oembedEndpoint = this.ghostPaths.url.api('oembed');
            let response = yield this.ajax.request(oembedEndpoint, {
                data: {
                    url
                }
            });

            if (!response.html) {
                throw 'No HTML returned';
            }

            set(this.payload.linkOnError, undefined);
            set(this.payload, 'html', response.html);
            set(this.payload, 'type', response.type);
            this.saveCard(this.payload, false);

            run.schedule('afterRender', this, this._populateIframe);
        } catch (err) {
            if (this.payload.linkOnError) {
                this.send('insertAsLink', {linkOnError: true});
                return;
            }
            this.set('hasError', true);
        }
    }),

    _focusInput() {
        let urlInput = this.element.querySelector('[name="url"]');<commit_msg>Koenig - Fixed embeds cards<commit_after>import Component from '@ember/component';
import countWords from '../utils/count-words';
import layout from '../templates/components/koenig-card-embed';
import noframe from 'noframe.js';
import {NO_CURSOR_MOVEMENT} from './koenig-editor';
import {computed} from '@ember/object';
import {isBlank} from '@ember/utils';
import {run} from '@ember/runloop';
import {inject as service} from '@ember/service';
import {set} from '@ember/object';
import {task} from 'ember-concurrency';

export default Component.extend({
    ajax: service(),
    ghostPaths: service(),

    layout,

    // attrs
    payload: null,
    isSelected: false,
    isEditing: false,

    // internal properties
    hasError: false,

    // closure actions
    selectCard() {},
    deselectCard() {},
    editCard() {},
    saveCard() {},
    deleteCard() {},
    moveCursorToNextSection() {},
    moveCursorToPrevSection() {},
    addParagraphAfterCard() {},
    registerComponent() {},

    counts: computed('payload.{html,caption}', function () {
        return {
            imageCount: this.payload.html ? 1 : 0,
            wordCount: countWords(this.payload.caption)
        };
    }),

    init() {
        this._super(...arguments);
        if (this.payload.url && !this.payload.html) {
            this.convertUrl.perform(this.payload.url);
        }

        this.registerComponent(this);
    },

    didInsertElement() {
        this._super(...arguments);
        this._populateIframe();
        this._focusInput();
    },

    willDestroyElement() {
        this._super(...arguments);

        run.cancel(this._resizeDebounce);

        if (this._iframeMutationObserver) {
            this._iframeMutationObserver.disconnect();
        }

        window.removeEventListener('resize', this._windowResizeHandler);
    },

    actions: {
        onDeselect() {
            if (this.payload.url && !this.payload.html && !this.hasError) {
                this.convertUrl.perform(this.payload.url);
            } else {
                this._deleteIfEmpty();
            }
        },

        updateUrl(event) {
            let url = event.target.value;
            set(this.payload, 'url', url);
        },

        urlKeydown(event) {
            if (event.key === 'Enter') {
                event.preventDefault();
                this.convertUrl.perform(this.payload.url);
            }

            if (event.key === 'Escape') {
                event.target.blur();
                this.deleteCard();
            }
        },

        updateCaption(caption) {
            set(this.payload, 'caption', caption);
            this.saveCard(this.payload, false);
        },

        retry() {
            this.set('hasError', false);
        },

        insertAsLink(options = {linkOnError: false}) {
            let {range} = this.editor;

            this.editor.run((postEditor) => {
                let {builder} = postEditor;
                let cardSection = this.env.postModel;
                let p = builder.createMarkupSection('p');
                let link = builder.createMarkup('a', {href: this.payload.url});

                postEditor.replaceSection(cardSection, p);
                postEditor.insertTextWithMarkup(p.toRange().head, this.payload.url, [link]);

                // if a user is typing further on in the doc (possible if embed
                // was created automatically via paste of URL) then return the
                // cursor so the card->link change doesn't cause a cursor jump
                if (range.headSection !== cardSection) {
                    postEditor.setRange(range);
                }

                // avoid adding an extra undo step when automatically creating
                // link after an error so that an Undo after pasting a URL
                // doesn't get stuck in a loop going through link->embed->link
                if (options.linkOnError) {
                    postEditor.cancelSnapshot();
                }
            });
        }
    },

    convertUrl: task(function* (url) {
        if (isBlank(url)) {
            this.deleteCard();
            return;
        }

        try {
            let oembedEndpoint = this.ghostPaths.url.api('oembed');
            let response = yield this.ajax.request(oembedEndpoint, {
                data: {
                    url
                }
            });

            if (!response.html) {
                throw 'No HTML returned';
            }

            set(this.payload, 'linkOnError', undefined);
            set(this.payload, 'html', response.html);
            set(this.payload, 'type', response.type);
            this.saveCard(this.payload, false);

            run.schedule('afterRender', this, this._populateIframe);
        } catch (err) {
            if (this.payload.linkOnError) {
                this.send('insertAsLink', {linkOnError: true});
                return;
            }
            this.set('hasError', true);
        }
    }),

    _focusInput() {
        let urlInput = this.element.querySelector('[name="url"]');
{'fraction_non_alphanumeric': 0.12774549394267704, 'fraction_numerical': 0.00039397222495814047, 'mean_word_length': 1.7458085451595458, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 11, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3956710', 'n_tokens_mistral': 2774, 'n_tokens_neox': 2641, 'n_words': 577}