mirror of
https://github.com/discourse/discourse.git
synced 2024-12-01 10:04:34 +08:00
REFACTOR: Remove _.merge
This commit is contained in:
parent
720cd57fb5
commit
c4079780be
37
app/assets/javascripts/discourse-common/addon/lib/object.js
Normal file
37
app/assets/javascripts/discourse-common/addon/lib/object.js
Normal file
|
@ -0,0 +1,37 @@
|
||||||
|
// a fairly simple deep merge based on: https://gist.github.com/ahtcx/0cd94e62691f539160b32ecda18af3d6
|
||||||
|
export function merge(...objects) {
|
||||||
|
const isObject = obj => obj && typeof obj === "object";
|
||||||
|
|
||||||
|
function deepMergeInner(target, source) {
|
||||||
|
Object.keys(source).forEach(key => {
|
||||||
|
const targetValue = target[key];
|
||||||
|
const sourceValue = source[key];
|
||||||
|
|
||||||
|
if (Array.isArray(targetValue) && Array.isArray(sourceValue)) {
|
||||||
|
target[key] = targetValue.concat(sourceValue);
|
||||||
|
} else if (isObject(targetValue) && isObject(sourceValue)) {
|
||||||
|
target[key] = deepMergeInner(
|
||||||
|
Object.assign({}, targetValue),
|
||||||
|
sourceValue
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
target[key] = sourceValue;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return target;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (objects.some(object => object && !isObject(object))) {
|
||||||
|
throw new Error('deepMerge: all values should be of type "object"');
|
||||||
|
}
|
||||||
|
|
||||||
|
const target = objects.shift();
|
||||||
|
let source;
|
||||||
|
|
||||||
|
while ((source = objects.shift())) {
|
||||||
|
deepMergeInner(target, source || {});
|
||||||
|
}
|
||||||
|
|
||||||
|
return target;
|
||||||
|
}
|
|
@ -26,6 +26,7 @@ import { escapeExpression } from "discourse/lib/utilities";
|
||||||
import { AUTO_DELETE_PREFERENCES } from "discourse/models/bookmark";
|
import { AUTO_DELETE_PREFERENCES } from "discourse/models/bookmark";
|
||||||
import { inject as service } from "@ember/service";
|
import { inject as service } from "@ember/service";
|
||||||
import bootbox from "bootbox";
|
import bootbox from "bootbox";
|
||||||
|
import { merge } from "discourse-common/lib/object";
|
||||||
|
|
||||||
let customPostMessageCallbacks = {};
|
let customPostMessageCallbacks = {};
|
||||||
|
|
||||||
|
@ -249,7 +250,7 @@ export default Controller.extend(bufferedProperty("model"), {
|
||||||
this.set("loadingPostIds", true);
|
this.set("loadingPostIds", true);
|
||||||
|
|
||||||
return ajax(url, {
|
return ajax(url, {
|
||||||
data: _.merge(
|
data: merge(
|
||||||
{ post_number: post.get("post_number") },
|
{ post_number: post.get("post_number") },
|
||||||
postStream.get("streamFilters")
|
postStream.get("streamFilters")
|
||||||
)
|
)
|
||||||
|
|
|
@ -13,6 +13,7 @@ import User from "discourse/models/user";
|
||||||
import Post from "discourse/models/post";
|
import Post from "discourse/models/post";
|
||||||
import Topic from "discourse/models/topic";
|
import Topic from "discourse/models/topic";
|
||||||
import { escapeExpression } from "discourse/lib/utilities";
|
import { escapeExpression } from "discourse/lib/utilities";
|
||||||
|
import { merge } from "discourse-common/lib/object";
|
||||||
|
|
||||||
export function translateResults(results, opts) {
|
export function translateResults(results, opts) {
|
||||||
opts = opts || {};
|
opts = opts || {};
|
||||||
|
@ -206,7 +207,7 @@ export function applySearchAutocomplete(
|
||||||
};
|
};
|
||||||
|
|
||||||
$input.autocomplete(
|
$input.autocomplete(
|
||||||
_.merge(
|
merge(
|
||||||
{
|
{
|
||||||
template: findRawTemplate("category-tag-autocomplete"),
|
template: findRawTemplate("category-tag-autocomplete"),
|
||||||
key: "#",
|
key: "#",
|
||||||
|
@ -226,7 +227,7 @@ export function applySearchAutocomplete(
|
||||||
|
|
||||||
if (siteSettings.enable_mentions) {
|
if (siteSettings.enable_mentions) {
|
||||||
$input.autocomplete(
|
$input.autocomplete(
|
||||||
_.merge(
|
merge(
|
||||||
{
|
{
|
||||||
template: findRawTemplate("user-selector-autocomplete"),
|
template: findRawTemplate("user-selector-autocomplete"),
|
||||||
key: "@",
|
key: "@",
|
||||||
|
|
|
@ -4,6 +4,7 @@ import toMarkdown from "discourse/lib/to-markdown";
|
||||||
import Handlebars from "handlebars";
|
import Handlebars from "handlebars";
|
||||||
import { default as getURL, getURLWithCDN } from "discourse-common/lib/get-url";
|
import { default as getURL, getURLWithCDN } from "discourse-common/lib/get-url";
|
||||||
import { helperContext } from "discourse-common/lib/helpers";
|
import { helperContext } from "discourse-common/lib/helpers";
|
||||||
|
import { merge } from "discourse-common/lib/object";
|
||||||
|
|
||||||
let _defaultHomepage;
|
let _defaultHomepage;
|
||||||
|
|
||||||
|
@ -85,7 +86,7 @@ export function avatarImg(options, customGetURL) {
|
||||||
|
|
||||||
export function tinyAvatar(avatarTemplate, options) {
|
export function tinyAvatar(avatarTemplate, options) {
|
||||||
return avatarImg(
|
return avatarImg(
|
||||||
_.merge({ avatarTemplate: avatarTemplate, size: "tiny" }, options)
|
merge({ avatarTemplate: avatarTemplate, size: "tiny" }, options)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -8,6 +8,7 @@ import getUrl from "discourse-common/lib/get-url";
|
||||||
import { on } from "@ember/object/evented";
|
import { on } from "@ember/object/evented";
|
||||||
import Mixin from "@ember/object/mixin";
|
import Mixin from "@ember/object/mixin";
|
||||||
import bootbox from "bootbox";
|
import bootbox from "bootbox";
|
||||||
|
import { merge } from "discourse-common/lib/object";
|
||||||
|
|
||||||
export default Mixin.create({
|
export default Mixin.create({
|
||||||
uploading: false,
|
uploading: false,
|
||||||
|
@ -56,7 +57,7 @@ export default Mixin.create({
|
||||||
});
|
});
|
||||||
|
|
||||||
$upload.fileupload(
|
$upload.fileupload(
|
||||||
_.merge(
|
merge(
|
||||||
{
|
{
|
||||||
url: this.calculateUploadUrl(),
|
url: this.calculateUploadUrl(),
|
||||||
dataType: "json",
|
dataType: "json",
|
||||||
|
@ -82,7 +83,7 @@ export default Mixin.create({
|
||||||
});
|
});
|
||||||
|
|
||||||
$upload.on("fileuploadsubmit", (e, data) => {
|
$upload.on("fileuploadsubmit", (e, data) => {
|
||||||
const opts = _.merge(
|
const opts = merge(
|
||||||
{
|
{
|
||||||
bypassNewUserRestriction: true,
|
bypassNewUserRestriction: true,
|
||||||
user: this.currentUser,
|
user: this.currentUser,
|
||||||
|
|
|
@ -9,6 +9,7 @@ import deprecated from "discourse-common/lib/deprecated";
|
||||||
import Site from "discourse/models/site";
|
import Site from "discourse/models/site";
|
||||||
import User from "discourse/models/user";
|
import User from "discourse/models/user";
|
||||||
import { getOwner } from "discourse-common/lib/get-owner";
|
import { getOwner } from "discourse-common/lib/get-owner";
|
||||||
|
import { merge } from "discourse-common/lib/object";
|
||||||
|
|
||||||
const NavItem = EmberObject.extend({
|
const NavItem = EmberObject.extend({
|
||||||
@discourseComputed("name")
|
@discourseComputed("name")
|
||||||
|
@ -180,7 +181,7 @@ NavItem.reopenClass({
|
||||||
args.noSubcategories = true;
|
args.noSubcategories = true;
|
||||||
}
|
}
|
||||||
NavItem.extraArgsCallbacks.forEach(cb =>
|
NavItem.extraArgsCallbacks.forEach(cb =>
|
||||||
_.merge(args, cb.call(this, filterType, opts))
|
merge(args, cb.call(this, filterType, opts))
|
||||||
);
|
);
|
||||||
|
|
||||||
let store = getOwner(this).lookup("service:store");
|
let store = getOwner(this).lookup("service:store");
|
||||||
|
@ -222,7 +223,7 @@ NavItem.reopenClass({
|
||||||
};
|
};
|
||||||
|
|
||||||
const extraItems = NavItem.extraNavItemDescriptors
|
const extraItems = NavItem.extraNavItemDescriptors
|
||||||
.map(descriptor => ExtraNavItem.create(_.merge({}, context, descriptor)))
|
.map(descriptor => ExtraNavItem.create(merge({}, context, descriptor)))
|
||||||
.filter(item => {
|
.filter(item => {
|
||||||
if (!item.customFilter) return true;
|
if (!item.customFilter) return true;
|
||||||
return item.customFilter(category, args);
|
return item.customFilter(category, args);
|
||||||
|
|
|
@ -10,6 +10,7 @@ import discourseComputed from "discourse-common/utils/decorators";
|
||||||
import { loadTopicView } from "discourse/models/topic";
|
import { loadTopicView } from "discourse/models/topic";
|
||||||
import { Promise } from "rsvp";
|
import { Promise } from "rsvp";
|
||||||
import User from "discourse/models/user";
|
import User from "discourse/models/user";
|
||||||
|
import { merge } from "discourse-common/lib/object";
|
||||||
|
|
||||||
export default RestModel.extend({
|
export default RestModel.extend({
|
||||||
_identityMap: null,
|
_identityMap: null,
|
||||||
|
@ -274,7 +275,7 @@ export default RestModel.extend({
|
||||||
this.set("loadingFilter", true);
|
this.set("loadingFilter", true);
|
||||||
this.set("loadingNearPost", opts.nearPost);
|
this.set("loadingNearPost", opts.nearPost);
|
||||||
|
|
||||||
opts = _.merge(opts, this.streamFilters);
|
opts = merge(opts, this.streamFilters);
|
||||||
|
|
||||||
// Request a topicView
|
// Request a topicView
|
||||||
return loadTopicView(topic, opts)
|
return loadTopicView(topic, opts)
|
||||||
|
@ -943,7 +944,7 @@ export default RestModel.extend({
|
||||||
include_suggested: includeSuggested
|
include_suggested: includeSuggested
|
||||||
};
|
};
|
||||||
|
|
||||||
data = _.merge(data, this.streamFilters);
|
data = merge(data, this.streamFilters);
|
||||||
const store = this.store;
|
const store = this.store;
|
||||||
|
|
||||||
return ajax(url, { data }).then(result => {
|
return ajax(url, { data }).then(result => {
|
||||||
|
|
|
@ -23,9 +23,10 @@ import { Promise } from "rsvp";
|
||||||
import Site from "discourse/models/site";
|
import Site from "discourse/models/site";
|
||||||
import User from "discourse/models/user";
|
import User from "discourse/models/user";
|
||||||
import bootbox from "bootbox";
|
import bootbox from "bootbox";
|
||||||
|
import { merge } from "discourse-common/lib/object";
|
||||||
|
|
||||||
export function loadTopicView(topic, args) {
|
export function loadTopicView(topic, args) {
|
||||||
const data = _.merge({}, args);
|
const data = merge({}, args);
|
||||||
const url = `${getURL("/t/")}${topic.id}`;
|
const url = `${getURL("/t/")}${topic.id}`;
|
||||||
const jsonUrl = (data.nearPost ? `${url}/${data.nearPost}` : url) + ".json";
|
const jsonUrl = (data.nearPost ? `${url}/${data.nearPost}` : url) + ".json";
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
import I18n from "I18n";
|
import I18n from "I18n";
|
||||||
import DiscourseRoute from "discourse/routes/discourse";
|
import DiscourseRoute from "discourse/routes/discourse";
|
||||||
import PreloadStore from "discourse/lib/preload-store";
|
import PreloadStore from "discourse/lib/preload-store";
|
||||||
|
import { merge } from "discourse-common/lib/object";
|
||||||
|
|
||||||
export default DiscourseRoute.extend({
|
export default DiscourseRoute.extend({
|
||||||
titleToken() {
|
titleToken() {
|
||||||
|
@ -10,7 +11,7 @@ export default DiscourseRoute.extend({
|
||||||
model(params) {
|
model(params) {
|
||||||
if (PreloadStore.get("invite_info")) {
|
if (PreloadStore.get("invite_info")) {
|
||||||
return PreloadStore.getAndRemove("invite_info").then(json =>
|
return PreloadStore.getAndRemove("invite_info").then(json =>
|
||||||
_.merge(params, json)
|
merge(params, json)
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
return {};
|
return {};
|
||||||
|
|
|
@ -3,6 +3,7 @@ import DiscourseRoute from "discourse/routes/discourse";
|
||||||
import PreloadStore from "discourse/lib/preload-store";
|
import PreloadStore from "discourse/lib/preload-store";
|
||||||
import { ajax } from "discourse/lib/ajax";
|
import { ajax } from "discourse/lib/ajax";
|
||||||
import { userPath } from "discourse/lib/url";
|
import { userPath } from "discourse/lib/url";
|
||||||
|
import { merge } from "discourse-common/lib/object";
|
||||||
|
|
||||||
export default DiscourseRoute.extend({
|
export default DiscourseRoute.extend({
|
||||||
titleToken() {
|
titleToken() {
|
||||||
|
@ -12,7 +13,7 @@ export default DiscourseRoute.extend({
|
||||||
model(params) {
|
model(params) {
|
||||||
if (PreloadStore.get("password_reset")) {
|
if (PreloadStore.get("password_reset")) {
|
||||||
return PreloadStore.getAndRemove("password_reset").then(json =>
|
return PreloadStore.getAndRemove("password_reset").then(json =>
|
||||||
_.merge(params, json)
|
merge(params, json)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
|
@ -8,6 +8,7 @@ import { iconNode } from "discourse-common/lib/icon-library";
|
||||||
import RawHtml from "discourse/widgets/raw-html";
|
import RawHtml from "discourse/widgets/raw-html";
|
||||||
import renderTags from "discourse/lib/render-tags";
|
import renderTags from "discourse/lib/render-tags";
|
||||||
import renderTopicFeaturedLink from "discourse/lib/render-topic-featured-link";
|
import renderTopicFeaturedLink from "discourse/lib/render-topic-featured-link";
|
||||||
|
import { merge } from "discourse-common/lib/object";
|
||||||
|
|
||||||
const SCROLLER_HEIGHT = 50;
|
const SCROLLER_HEIGHT = 50;
|
||||||
const LAST_READ_HEIGHT = 20;
|
const LAST_READ_HEIGHT = 20;
|
||||||
|
@ -240,7 +241,7 @@ createWidget("timeline-scrollarea", {
|
||||||
this.attach("timeline-padding", { height: before }),
|
this.attach("timeline-padding", { height: before }),
|
||||||
this.attach(
|
this.attach(
|
||||||
"timeline-scroller",
|
"timeline-scroller",
|
||||||
_.merge(position, {
|
merge(position, {
|
||||||
showDockedButton: !attrs.mobileView && hasBackPosition && !showButton,
|
showDockedButton: !attrs.mobileView && hasBackPosition && !showButton,
|
||||||
fullScreen: attrs.fullScreen
|
fullScreen: attrs.fullScreen
|
||||||
})
|
})
|
||||||
|
|
|
@ -22,6 +22,7 @@ import DecoratorHelper from "discourse/widgets/decorator-helper";
|
||||||
import { Promise } from "rsvp";
|
import { Promise } from "rsvp";
|
||||||
import { isProduction } from "discourse-common/config/environment";
|
import { isProduction } from "discourse-common/config/environment";
|
||||||
import { get } from "@ember/object";
|
import { get } from "@ember/object";
|
||||||
|
import { merge } from "discourse-common/lib/object";
|
||||||
|
|
||||||
const _registry = {};
|
const _registry = {};
|
||||||
|
|
||||||
|
@ -185,7 +186,7 @@ export default class Widget {
|
||||||
|
|
||||||
// Sometimes we pass state down from the parent
|
// Sometimes we pass state down from the parent
|
||||||
if (this.mergeState) {
|
if (this.mergeState) {
|
||||||
this.state = _.merge(this.state, this.mergeState);
|
this.state = merge(this.state, this.mergeState);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (prev) {
|
if (prev) {
|
||||||
|
|
|
@ -2,6 +2,7 @@ import {
|
||||||
cook as cookIt,
|
cook as cookIt,
|
||||||
setup as setupIt
|
setup as setupIt
|
||||||
} from "pretty-text/engines/discourse-markdown-it";
|
} from "pretty-text/engines/discourse-markdown-it";
|
||||||
|
import { merge } from "discourse-common/lib/object";
|
||||||
|
|
||||||
export function registerOption() {
|
export function registerOption() {
|
||||||
// TODO next major version deprecate this
|
// TODO next major version deprecate this
|
||||||
|
@ -48,7 +49,7 @@ export function buildOptions(state) {
|
||||||
};
|
};
|
||||||
|
|
||||||
if (state.features) {
|
if (state.features) {
|
||||||
features = _.merge(features, state.features);
|
features = merge(features, state.features);
|
||||||
}
|
}
|
||||||
|
|
||||||
const options = {
|
const options = {
|
||||||
|
|
|
@ -87,6 +87,7 @@ module PrettyText
|
||||||
root_path = "#{Rails.root}/app/assets/javascripts/"
|
root_path = "#{Rails.root}/app/assets/javascripts/"
|
||||||
|
|
||||||
apply_es6_file(ctx, root_path, "discourse-common/addon/lib/get-url")
|
apply_es6_file(ctx, root_path, "discourse-common/addon/lib/get-url")
|
||||||
|
apply_es6_file(ctx, root_path, "discourse-common/addon/lib/object")
|
||||||
apply_es6_file(ctx, root_path, "discourse/app/lib/to-markdown")
|
apply_es6_file(ctx, root_path, "discourse/app/lib/to-markdown")
|
||||||
apply_es6_file(ctx, root_path, "discourse/app/lib/utilities")
|
apply_es6_file(ctx, root_path, "discourse/app/lib/utilities")
|
||||||
|
|
||||||
|
|
|
@ -8,6 +8,7 @@ import {
|
||||||
} from "pretty-text/inline-oneboxer";
|
} from "pretty-text/inline-oneboxer";
|
||||||
import { extractDataAttribute } from "pretty-text/engines/discourse-markdown-it";
|
import { extractDataAttribute } from "pretty-text/engines/discourse-markdown-it";
|
||||||
import { registerEmoji } from "pretty-text/emoji";
|
import { registerEmoji } from "pretty-text/emoji";
|
||||||
|
import { merge } from "discourse-common/lib/object";
|
||||||
|
|
||||||
QUnit.module("lib:pretty-text");
|
QUnit.module("lib:pretty-text");
|
||||||
|
|
||||||
|
@ -38,7 +39,7 @@ QUnit.assert.cooked = function(input, expected, message) {
|
||||||
};
|
};
|
||||||
|
|
||||||
QUnit.assert.cookedOptions = function(input, opts, expected, message) {
|
QUnit.assert.cookedOptions = function(input, opts, expected, message) {
|
||||||
const merged = _.merge({}, rawOpts, opts);
|
const merged = merge({}, rawOpts, opts);
|
||||||
const actual = new PrettyText(buildOptions(merged)).cook(input);
|
const actual = new PrettyText(buildOptions(merged)).cook(input);
|
||||||
this.pushResult({
|
this.pushResult({
|
||||||
result: actual === expected,
|
result: actual === expected,
|
||||||
|
|
|
@ -1,11 +1,12 @@
|
||||||
import Post from "discourse/models/post";
|
import Post from "discourse/models/post";
|
||||||
import User from "discourse/models/user";
|
import User from "discourse/models/user";
|
||||||
|
import { merge } from "discourse-common/lib/object";
|
||||||
|
|
||||||
QUnit.module("model: Post");
|
QUnit.module("model: Post");
|
||||||
|
|
||||||
var buildPost = function(args) {
|
var buildPost = function(args) {
|
||||||
return Post.create(
|
return Post.create(
|
||||||
_.merge(
|
merge(
|
||||||
{
|
{
|
||||||
id: 1,
|
id: 1,
|
||||||
can_delete: true,
|
can_delete: true,
|
||||||
|
|
Loading…
Reference in New Issue
Block a user