mirror of
https://github.com/TryGhost/Ghost.git
synced 2024-12-01 13:54:35 +03:00
a04adae8d2
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
80 lines
2.2 KiB
JavaScript
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));
|
|
});
|
|
}
|