Ghost/ghost/admin/lib/koenig-editor/addon/utils/oembed.js
Kevin Ansfield a04adae8d2 Koenig - Embed card
refs https://github.com/TryGhost/Ghost/issues/9623
requires https://github.com/TryGhost/Ghost/pull/9666
- `{{koenig-card-embed}}`
    - URL input
    - perform oembed lookup & fetch on <kbd>Enter</kbd>
    - remove card if enter pressed with empty URL
    - show error message on server error
        - "retry" returns to input bar
        - "paste as link" removes card and outputs link
        - "X" removes card
    - force embedded <script> tags to run
    - wrap embed html with `.koenig-embed-{video,photo,rich}` class
- add embed cards to the (+) and /-menus
    - "section" support in the card menus
    - refactor to use single card menu map and content component for both menus
    - update /-menu keyboard movement to handle sections
- add parameter support to /-menu commands
  - `/embed {url}` will insert embed card and automatically fetch oembed for supplied url
2018-06-12 14:07:50 +01:00

80 lines
2.2 KiB
JavaScript

import fetch from 'fetch';
import oembedProviders from './oembed-providers';
import {Promise} from 'rsvp';
let filteredProviders;
// normalize the oembed.com providers list
// implemented as a memoized function rather than direct map to avoid parsing
// cost during initial JS load/parse.
export default function providers() {
if (filteredProviders) {
return filteredProviders;
}
filteredProviders = oembedProviders().map((provider) => {
let {
provider_name, // eslint-disable-line camelcase
provider_url, // eslint-disable-line camelcase
endpoints
} = provider;
let [endpoint] = endpoints;
let {
schemes = [],
url
} = endpoint;
let hostname = new URL(url).hostname;
let domain = hostname ? hostname.replace('www.', '') : '';
return {
provider_name,
provider_url,
schemes,
domain,
url
};
}).filter(provider => provider.domain !== '');
return filteredProviders;
}
export function findProvider(url) {
let candidates = providers().filter((provider) => {
let {
schemes,
domain
} = provider;
if (!schemes.length) {
return url.includes(domain);
}
return schemes.some((scheme) => {
let reg = new RegExp(scheme.replace(/\*/g, '(.*)'), 'i');
return url.match(reg);
});
});
return candidates.length > 0 ? candidates[0] : null;
}
export function fetchEmbed(url, provider) {
return new Promise((resolve, reject) => {
let {
provider_name, // eslint-disable-line camelcase
provider_url, // eslint-disable-line camelcase
url: resourceUrl
} = provider;
let link = `${resourceUrl}?format=json&url=${encodeURIComponent(url)}`;
return fetch(link, {cache: 'no-cache', method: 'cors'}).then(res => res.json()).then((json) => {
json.provider_name = provider_name; // eslint-disable-line camelcase
json.provider_url = provider_url; // eslint-disable-line camelcase
return resolve(json);
}).catch(error => reject(error));
});
}