DEV: Add jquery-free `decorateCookedElement` function to plugin api (#9534)

This is a replacement for `decorateCooked` which will work without jquery.

A backwards compatibility layer is provided for existing plugins/themes which are currently using `decorateCooked`
This commit is contained in:
David Taylor 2020-04-24 09:47:33 +01:00 committed by GitHub
parent 8a112b7464
commit 0616826841
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 33 additions and 22 deletions

View File

@ -1019,7 +1019,7 @@ export default Component.extend({
this._registerImageScaleButtonClick($preview);
this.trigger("previewRefreshed", $preview);
this.trigger("previewRefreshed", $preview[0]);
this.afterRefresh($preview);
}
}

View File

@ -84,8 +84,8 @@ function show(image) {
}
}
function forEachImage($post, callback) {
$post[0].querySelectorAll("img").forEach(img => {
function forEachImage(post, callback) {
post.querySelectorAll("img").forEach(img => {
if (img.width >= MINIMUM_SIZE && img.height >= MINIMUM_SIZE) {
callback(img);
}
@ -104,7 +104,7 @@ export function setupLazyLoading(api) {
});
}, OBSERVER_OPTIONS);
api.decorateCooked($post => forEachImage($post, img => hide(img)), {
api.decorateCookedElement(post => forEachImage(post, img => hide(img)), {
onlyStream: true,
id: "discourse-lazy-load"
});
@ -112,8 +112,8 @@ export function setupLazyLoading(api) {
// IntersectionObserver.observe must be called after the cooked
// content is adopted by the document element in chrome
// https://bugs.chromium.org/p/chromium/issues/detail?id=1073469
api.decorateCooked(
$post => forEachImage($post, img => observer.observe(img)),
api.decorateCookedElement(
post => forEachImage(post, img => observer.observe(img)),
{
onlyStream: true,
id: "discourse-lazy-load-after-adopt",

View File

@ -54,7 +54,7 @@ import { on } from "@ember/object/evented";
import KeyboardShortcuts from "discourse/lib/keyboard-shortcuts";
// If you add any methods to the API ensure you bump up this number
const PLUGIN_API_VERSION = "0.8.41";
const PLUGIN_API_VERSION = "0.8.42";
class PluginApi {
constructor(version, container) {
@ -192,10 +192,23 @@ class PluginApi {
}
/**
* Used for decorating the `cooked` content of a post after it is rendered using
* jQuery.
* Method for decorating the `cooked` content of a post using JQuery
*
* `callback` will be called when it is time to decorate with a jQuery selector.
* You should use decorateCookedElement instead, which works without JQuery
*
* This method will be deprecated in future
**/
decorateCooked(callback, opts) {
this.decorateCookedElement(
(element, decoratorHelper) => callback($(element), decoratorHelper),
opts
);
}
/**
* Used for decorating the `cooked` content of a post after it is rendered
*
* `callback` will be called when it is time to decorate with an DOM node.
*
* Use `options.onlyStream` if you only want to decorate posts within a topic,
* and not in other places like the user stream.
@ -206,8 +219,8 @@ class PluginApi {
* For example, to add a yellow background to all posts you could do this:
*
* ```
* api.decorateCooked(
* $elem => $elem.css({ backgroundColor: 'yellow' }),
* api.decorateCookedElement(
* elem => { elem.style.backgroundColor = 'yellow' },
* { id: 'yellow-decorator' }
* );
* ```
@ -215,7 +228,7 @@ class PluginApi {
* NOTE: To avoid memory leaks, it is highly recommended to pass a unique `id` parameter.
* You will receive a warning if you do not.
**/
decorateCooked(callback, opts) {
decorateCookedElement(callback, opts) {
opts = opts || {};
addDecorator(callback, { afterAdopt: !!opts.afterAdopt });
@ -1114,10 +1127,10 @@ function decorate(klass, evt, cb, id) {
}
const mixin = {};
mixin["_decorate_" + _decorateId++] = on(evt, function($elem) {
$elem = $elem || $(this.element);
if ($elem) {
cb($elem);
mixin["_decorate_" + _decorateId++] = on(evt, function(elem) {
elem = elem || this.element;
if (elem) {
cb(elem);
}
});
klass.reopen(mixin);

View File

@ -11,7 +11,7 @@ import {
let _beforeAdoptDecorators = [];
let _afterAdoptDecorators = [];
// Don't call this directly: use `plugin-api/decorateCooked`
// Don't call this directly: use `plugin-api/decorateCookedElement`
export function addDecorator(callback, { afterAdopt = false } = {}) {
if (afterAdopt) {
_afterAdoptDecorators.push(callback);
@ -67,13 +67,11 @@ export default class PostCooked {
}
_decorateAndAdopt(cooked) {
const $cooked = $(cooked);
_beforeAdoptDecorators.forEach(d => d($cooked, this.decoratorHelper));
_beforeAdoptDecorators.forEach(d => d(cooked, this.decoratorHelper));
document.adoptNode(cooked);
_afterAdoptDecorators.forEach(d => d($cooked, this.decoratorHelper));
_afterAdoptDecorators.forEach(d => d(cooked, this.decoratorHelper));
}
_applySearchHighlight($html) {