diff --git a/app/assets/javascripts/admin/controllers/admin-customize-colors.js.es6 b/app/assets/javascripts/admin/controllers/admin-customize-colors.js.es6 index 945a46acf36..60a0af98b84 100644 --- a/app/assets/javascripts/admin/controllers/admin-customize-colors.js.es6 +++ b/app/assets/javascripts/admin/controllers/admin-customize-colors.js.es6 @@ -11,7 +11,7 @@ export default Ember.Controller.extend({ baseColors: function() { var baseColorsHash = Em.Object.create({}); - _.each(this.get("baseColorScheme.colors"), function(color) { + this.get("baseColorScheme.colors").forEach(color => { baseColorsHash.set(color.get("name"), color); }); return baseColorsHash; diff --git a/app/assets/javascripts/admin/controllers/admin-user-badges.js.es6 b/app/assets/javascripts/admin/controllers/admin-user-badges.js.es6 index b72cdae15fe..784d2077ea4 100644 --- a/app/assets/javascripts/admin/controllers/admin-user-badges.js.es6 +++ b/app/assets/javascripts/admin/controllers/admin-user-badges.js.es6 @@ -20,13 +20,13 @@ export default Ember.Controller.extend(GrantBadgeController, { _(grouped).each(function(badges) { var lastGranted = badges[0].granted_at; - _.each(badges, function(badge) { + badges.forEaach(badge => { lastGranted = lastGranted < badge.granted_at ? badge.granted_at : lastGranted; }); if (badges.length === 1 || expandedBadges.includes(badges[0].badge.id)) { - _.each(badges, badge => expanded.push(badge)); + badges.forEach(badge => expanded.push(badge)); return; } diff --git a/app/assets/javascripts/admin/controllers/modals/admin-badge-preview.js.es6 b/app/assets/javascripts/admin/controllers/modals/admin-badge-preview.js.es6 index aa91a1be7cc..27023621569 100644 --- a/app/assets/javascripts/admin/controllers/modals/admin-badge-preview.js.es6 +++ b/app/assets/javascripts/admin/controllers/modals/admin-badge-preview.js.es6 @@ -21,7 +21,7 @@ export default Ember.Controller.extend({ var raw = this.get("model.query_plan"), returned = "
"; - _.each(raw, function(linehash) { + raw.forEach(linehash => { returned += escapeExpression(linehash["QUERY PLAN"]); returned += "
"; }); diff --git a/app/assets/javascripts/admin/models/admin-user.js.es6 b/app/assets/javascripts/admin/models/admin-user.js.es6 index ec230ffff48..fc36b9bfe88 100644 --- a/app/assets/javascripts/admin/models/admin-user.js.es6 +++ b/app/assets/javascripts/admin/models/admin-user.js.es6 @@ -542,7 +542,7 @@ const AdminUser = Discourse.User.extend({ AdminUser.reopenClass({ bulkApprove(users) { - _.each(users, function(user) { + users.forEach(user => { user.setProperties({ approved: true, can_approve: false, @@ -557,7 +557,7 @@ AdminUser.reopenClass({ }, bulkReject(users) { - _.each(users, function(user) { + users.forEach(user => { user.set("can_approve", false); user.set("selected", false); }); diff --git a/app/assets/javascripts/admin/models/color-scheme.js.es6 b/app/assets/javascripts/admin/models/color-scheme.js.es6 index 04d661dee6b..e781320c298 100644 --- a/app/assets/javascripts/admin/models/color-scheme.js.es6 +++ b/app/assets/javascripts/admin/models/color-scheme.js.es6 @@ -19,7 +19,7 @@ const ColorScheme = Discourse.Model.extend(Ember.Copyable, { schemeJson() { let buffer = []; - _.each(this.get("colors"), c => { + this.get("colors").forEach(c => { buffer.push(` "${c.get("name")}": "${c.get("hex")}"`); }); @@ -32,7 +32,7 @@ const ColorScheme = Discourse.Model.extend(Ember.Copyable, { can_edit: true, colors: Em.A() }); - _.each(this.get("colors"), function(c) { + this.get("colors").forEach(c => { newScheme.colors.pushObject( ColorSchemeColor.create({ name: c.get("name"), @@ -86,7 +86,7 @@ const ColorScheme = Discourse.Model.extend(Ember.Copyable, { data.name = this.name; data.base_scheme_id = this.get("base_scheme_id"); data.colors = []; - _.each(this.get("colors"), function(c) { + this.get("colors").forEach(c => { if (!self.id || c.get("changed")) { data.colors.pushObject({ name: c.get("name"), hex: c.get("hex") }); } @@ -107,9 +107,7 @@ const ColorScheme = Discourse.Model.extend(Ember.Copyable, { } if (!opts || !opts.enabledOnly) { self.startTrackingChanges(); - _.each(self.get("colors"), function(c) { - c.startTrackingChanges(); - }); + self.get("colors").forEach(c => c.startTrackingChanges()); } self.set("savingStatus", I18n.t("saved")); self.set("saving", false); @@ -130,7 +128,7 @@ ColorScheme.reopenClass({ findAll: function() { var colorSchemes = ColorSchemes.create({ content: [], loading: true }); return ajax("/admin/color_schemes").then(function(all) { - _.each(all, function(colorScheme) { + all.forEach(colorScheme => { colorSchemes.pushObject( ColorScheme.create({ id: colorScheme.id, diff --git a/app/assets/javascripts/admin/models/report.js.es6 b/app/assets/javascripts/admin/models/report.js.es6 index 5e1829f97cd..709dac0a52b 100644 --- a/app/assets/javascripts/admin/models/report.js.es6 +++ b/app/assets/javascripts/admin/models/report.js.es6 @@ -62,7 +62,7 @@ const Report = Discourse.Model.extend({ let d, sum = 0, count = 0; - _.each(this.data, datum => { + this.data.forEach(datum => { d = moment(datum.x); if (d >= earliestDate && d <= latestDate) { sum += datum.y; diff --git a/app/assets/javascripts/admin/routes/admin-badges.js.es6 b/app/assets/javascripts/admin/routes/admin-badges.js.es6 index 6d55997403a..9fee47fb4e4 100644 --- a/app/assets/javascripts/admin/routes/admin-badges.js.es6 +++ b/app/assets/javascripts/admin/routes/admin-badges.js.es6 @@ -17,9 +17,10 @@ export default Discourse.Route.extend({ const badgeTriggers = []; const badgeGroupings = []; - _.each(json.admin_badges.triggers, function(v, k) { + Object.keys(json.admin_badges.triggers).forEach(k => { + const id = json.admin_badges.triggers[k]; badgeTriggers.push({ - id: v, + id, name: I18n.t("admin.badges.trigger_type." + k) }); }); diff --git a/app/assets/javascripts/discourse/components/create-topics-notice.js.es6 b/app/assets/javascripts/discourse/components/create-topics-notice.js.es6 index a6dcff014bf..8a8557458b6 100644 --- a/app/assets/javascripts/discourse/components/create-topics-notice.js.es6 +++ b/app/assets/javascripts/discourse/components/create-topics-notice.js.es6 @@ -20,7 +20,7 @@ export default Ember.Component.extend({ postCount = 0; // Use data we already have before fetching live stats - _.each(this.site.get("categories"), function(c) { + this.site.get("categories").forEach(c => { if (!c.get("read_restricted")) { topicCount += c.get("topic_count"); postCount += c.get("post_count"); diff --git a/app/assets/javascripts/discourse/initializers/live-development.js.es6 b/app/assets/javascripts/discourse/initializers/live-development.js.es6 index 250ce27a172..8104bdfd0ab 100644 --- a/app/assets/javascripts/discourse/initializers/live-development.js.es6 +++ b/app/assets/javascripts/discourse/initializers/live-development.js.es6 @@ -53,7 +53,7 @@ export default { // hbs notifications only happen in dev Ember.TEMPLATES.empty = Handlebars.compile(""); } - _.each(data, function(me) { + data.forEach(me => { if (me === "refresh") { // Refresh if necessary document.location.reload(true); diff --git a/app/assets/javascripts/discourse/initializers/subscribe-user-notifications.js.es6 b/app/assets/javascripts/discourse/initializers/subscribe-user-notifications.js.es6 index 4b0812e1476..0dd8250fe44 100644 --- a/app/assets/javascripts/discourse/initializers/subscribe-user-notifications.js.es6 +++ b/app/assets/javascripts/discourse/initializers/subscribe-user-notifications.js.es6 @@ -114,8 +114,8 @@ export default { const router = container.lookup("router:main"); bus.subscribe("/categories", data => { - _.each(data.categories, c => site.updateCategory(c)); - _.each(data.deleted_categories, id => site.removeCategory(id)); + data.categories.forEach(c => site.updateCategory(c)); + data.deleted_categories.forEach(id => site.removeCategory(id)); }); bus.subscribe("/client_settings", data => diff --git a/app/assets/javascripts/discourse/lib/autocomplete.js.es6 b/app/assets/javascripts/discourse/lib/autocomplete.js.es6 index 6039c2deb98..939eef6a90e 100644 --- a/app/assets/javascripts/discourse/lib/autocomplete.js.es6 +++ b/app/assets/javascripts/discourse/lib/autocomplete.js.es6 @@ -218,7 +218,7 @@ export default function(options) { ); var vals = this.val().split(","); - _.each(vals, function(x) { + vals.forEach(x => { if (x !== "") { if (options.reverseTransform) { x = options.reverseTransform(x); @@ -231,7 +231,7 @@ export default function(options) { }); if (options.items) { - _.each(options.items, function(item) { + options.items.forEach(item => { if (options.single) { me.hide(); } diff --git a/app/assets/javascripts/discourse/lib/page-tracker.js.es6 b/app/assets/javascripts/discourse/lib/page-tracker.js.es6 index 7d637e1a2fd..0765ad50b16 100644 --- a/app/assets/javascripts/discourse/lib/page-tracker.js.es6 +++ b/app/assets/javascripts/discourse/lib/page-tracker.js.es6 @@ -32,7 +32,8 @@ export function startPageTracking(router, appEvents) { }); transitionCount++; - _.each(cache, (v, k) => { + Object.keys(cache).forEach(k => { + const v = cache[k]; if (v && v.target && v.target < transitionCount) { delete cache[k]; } @@ -56,7 +57,7 @@ export function googleTagManagerPageChanged(data) { } }; - _.each(_gtmPageChangedCallbacks, callback => callback(gtmData)); + _gtmPageChangedCallbacks.forEach(callback => callback(gtmData)); window.dataLayer.push(gtmData); } diff --git a/app/assets/javascripts/discourse/models/category.js.es6 b/app/assets/javascripts/discourse/models/category.js.es6 index 20f070b1e79..5c349d87f59 100644 --- a/app/assets/javascripts/discourse/models/category.js.es6 +++ b/app/assets/javascripts/discourse/models/category.js.es6 @@ -259,7 +259,7 @@ Category.reopenClass({ findByIds(ids) { const categories = []; - _.each(ids, id => { + ids.forEach(id => { const found = Category.findById(id); if (found) { categories.push(found); diff --git a/app/assets/javascripts/discourse/models/nav-item.js.es6 b/app/assets/javascripts/discourse/models/nav-item.js.es6 index c0b4a1f0b23..0739efe27ac 100644 --- a/app/assets/javascripts/discourse/models/nav-item.js.es6 +++ b/app/assets/javascripts/discourse/models/nav-item.js.es6 @@ -59,16 +59,12 @@ const NavItem = Discourse.Model.extend({ href(filterMode) { let customHref = null; - _.each( - NavItem.customNavItemHrefs, - function(cb) { - customHref = cb.call(this, this); - if (customHref) { - return false; - } - }, - this - ); + NavItem.customNavItemHrefs.forEach(function(cb) { + customHref = cb.call(this, this); + if (customHref) { + return false; + } + }, this); if (customHref) { return customHref; @@ -143,7 +139,7 @@ NavItem.reopenClass({ if (opts.noSubcategories) { args.noSubcategories = true; } - _.each(NavItem.extraArgsCallbacks, function(cb) { + NavItem.extraArgsCallbacks.forEach(cb => { extra = cb.call(self, text, opts); _.merge(args, extra); }); diff --git a/app/assets/javascripts/discourse/models/site.js.es6 b/app/assets/javascripts/discourse/models/site.js.es6 index a2de542fa4e..70ec3bbc9a4 100644 --- a/app/assets/javascripts/discourse/models/site.js.es6 +++ b/app/assets/javascripts/discourse/models/site.js.es6 @@ -11,7 +11,9 @@ const Site = RestModel.extend({ @computed("notification_types") notificationLookup(notificationTypes) { const result = []; - _.each(notificationTypes, (v, k) => (result[v] = k)); + Object.keys(notificationTypes).forEach( + k => (result[notificationTypes[k]] = k) + ); return result; }, diff --git a/app/assets/javascripts/discourse/models/topic-list.js.es6 b/app/assets/javascripts/discourse/models/topic-list.js.es6 index 0a4a7e33a35..edd5e9b2656 100644 --- a/app/assets/javascripts/discourse/models/topic-list.js.es6 +++ b/app/assets/javascripts/discourse/models/topic-list.js.es6 @@ -25,9 +25,9 @@ const TopicList = RestModel.extend({ forEachNew(topics, callback) { const topicIds = []; - _.each(this.get("topics"), topic => (topicIds[topic.get("id")] = true)); + this.get("topics").forEach(topic => (topicIds[topic.get("id")] = true)); - _.each(topics, topic => { + topics.forEach(topic => { if (!topicIds[topic.id]) { callback(topic); } diff --git a/app/assets/javascripts/discourse/models/topic-tracking-state.js.es6 b/app/assets/javascripts/discourse/models/topic-tracking-state.js.es6 index 1e0e0ec1d76..70ed88d5741 100644 --- a/app/assets/javascripts/discourse/models/topic-tracking-state.js.es6 +++ b/app/assets/javascripts/discourse/models/topic-tracking-state.js.es6 @@ -308,12 +308,14 @@ const TopicTrackingState = Discourse.Model.extend({ const ids = {}; list.topics.forEach(r => (ids["t" + r.id] = true)); - _.each(tracker.states, (v, k) => { + Object.keys(tracker.states).forEach(k => { // we are good if we are on the list if (ids[k]) { return; } + const v = tracker.states[k]; + if (filter === "unread" && isUnread(v)) { // pretend read v.last_read_post_number = v.highest_post_number; @@ -371,7 +373,7 @@ const TopicTrackingState = Discourse.Model.extend({ countCategory(category_id) { let sum = 0; - _.each(this.states, function(topic) { + this.states.forEach(topic => { if (topic.category_id === category_id && !topic.deleted) { sum += topic.last_read_post_number === null || @@ -411,7 +413,7 @@ const TopicTrackingState = Discourse.Model.extend({ // I am taking some shortcuts here to avoid 500 gets for a large list if (data) { - _.each(data, topic => { + data.forEach(topic => { var category = idMap[topic.category_id]; if (category && category.parent_category_id) { topic.parent_category_id = category.parent_category_id; diff --git a/app/assets/javascripts/discourse/models/user-action.js.es6 b/app/assets/javascripts/discourse/models/user-action.js.es6 index 9c73093a395..a60f5898235 100644 --- a/app/assets/javascripts/discourse/models/user-action.js.es6 +++ b/app/assets/javascripts/discourse/models/user-action.js.es6 @@ -21,9 +21,9 @@ const UserActionTypes = { }; const InvertedActionTypes = {}; -_.each(UserActionTypes, (k, v) => { - InvertedActionTypes[k] = v; -}); +Object.keys(UserActionTypes).forEach( + k => (InvertedActionTypes[k] = UserActionTypes[k]) +); const UserAction = RestModel.extend({ @on("init") diff --git a/app/assets/javascripts/discourse/models/user.js.es6 b/app/assets/javascripts/discourse/models/user.js.es6 index 3bb87992028..f1f22752a71 100644 --- a/app/assets/javascripts/discourse/models/user.js.es6 +++ b/app/assets/javascripts/discourse/models/user.js.es6 @@ -446,7 +446,7 @@ const User = RestModel.extend({ statsCountNonPM() { if (Ember.isEmpty(this.get("statsExcludingPms"))) return 0; let count = 0; - _.each(this.get("statsExcludingPms"), val => { + this.get("statsExcludingPms").forEach(val => { if (this.inAllStream(val)) { count += val.count; } @@ -690,13 +690,13 @@ const User = RestModel.extend({ availableTitles() { let titles = []; - _.each(this.get("groups"), group => { + (this.get("groups") || []).forEach(group => { if (group.get("title")) { titles.push(group.get("title")); } }); - _.each(this.get("badges"), badge => { + (this.get("badges") || []).forEach(badge => { if (badge.get("allow_title")) { titles.push(badge.get("name")); } diff --git a/app/assets/javascripts/discourse/widgets/post-links.js.es6 b/app/assets/javascripts/discourse/widgets/post-links.js.es6 index e904ebb3d5a..9038e3b319f 100644 --- a/app/assets/javascripts/discourse/widgets/post-links.js.es6 +++ b/app/assets/javascripts/discourse/widgets/post-links.js.es6 @@ -52,7 +52,7 @@ export default createWidget("post-links", { // show all links if (links.length <= 5 || !state.collapsed) { - _.each(links, l => result.push(this.linkHtml(l))); + links.forEach(l => result.push(this.linkHtml(l))); } else { const max = Math.min(5, links.length); for (let i = 0; i < max; i++) { diff --git a/test/javascripts/acceptance/admin-watched-words-test.js.es6 b/test/javascripts/acceptance/admin-watched-words-test.js.es6 index 6e5773b1db7..ca255a06a4d 100644 --- a/test/javascripts/acceptance/admin-watched-words-test.js.es6 +++ b/test/javascripts/acceptance/admin-watched-words-test.js.es6 @@ -47,9 +47,9 @@ QUnit.test("add words", async assert => { await click(".watched-word-form button"); let found = []; - _.each(find(".watched-words-list .watched-word"), i => { + $.each(find(".watched-words-list .watched-word"), (index, elem) => { if ( - $(i) + $(elem) .text() .trim() === "poutine" ) { @@ -65,13 +65,13 @@ QUnit.test("remove words", async assert => { let word = null; - _.each(find(".watched-words-list .watched-word"), i => { + $.each(find(".watched-words-list .watched-word"), (index, elem) => { if ( - $(i) + $(elem) .text() .trim() === "anise" ) { - word = i; + word = elem; } }); diff --git a/test/javascripts/components/keyboard-shortcuts-test.js.es6 b/test/javascripts/components/keyboard-shortcuts-test.js.es6 index d9cc073e9f2..a96ac88cdcd 100644 --- a/test/javascripts/components/keyboard-shortcuts-test.js.es6 +++ b/test/javascripts/components/keyboard-shortcuts-test.js.es6 @@ -14,7 +14,7 @@ QUnit.module("lib:keyboard-shortcuts", { }, this); if (_.isArray(bindings)) { - _.each(bindings, registerBinding, this); + bindings.forEach(registerBinding, this); } else { registerBinding(bindings); } @@ -67,9 +67,9 @@ QUnit.module("lib:keyboard-shortcuts", { } }); -var pathBindings = KeyboardShortcuts.PATH_BINDINGS; - -_.each(pathBindings, function(path, binding) { +var pathBindings = KeyboardShortcuts.PATH_BINDINGS || {}; +Object.keys(pathBindings).forEach(path => { + const binding = pathBindings[path]; var testName = binding + " goes to " + path; test(testName, function(assert) { @@ -80,9 +80,9 @@ _.each(pathBindings, function(path, binding) { }); }); -var clickBindings = KeyboardShortcuts.CLICK_BINDINGS; - -_.each(clickBindings, function(selector, binding) { +var clickBindings = KeyboardShortcuts.CLICK_BINDINGS || {}; +Object.keys(clickBindings).forEach(selector => { + const binding = clickBindings[selector]; var bindings = binding.split(","); var testName = binding + " clicks on " + selector; @@ -93,19 +93,15 @@ _.each(clickBindings, function(selector, binding) { assert.ok(true, selector + " was clicked"); }); - _.each( - bindings, - function(b) { - testMouseTrap.trigger(b); - }, - this - ); + bindings.forEach(function(b) { + testMouseTrap.trigger(b); + }, this); }); }); -var functionBindings = KeyboardShortcuts.FUNCTION_BINDINGS; - -_.each(functionBindings, function(func, binding) { +var functionBindings = KeyboardShortcuts.FUNCTION_BINDINGS || {}; +Object.keys(functionBindings).forEach(func => { + const binding = functionBindings[func]; var testName = binding + " calls " + func; test(testName, function(assert) { diff --git a/test/javascripts/lib/utilities-test.js.es6 b/test/javascripts/lib/utilities-test.js.es6 index 56804e0aca9..d5280741a53 100644 --- a/test/javascripts/lib/utilities-test.js.es6 +++ b/test/javascripts/lib/utilities-test.js.es6 @@ -204,16 +204,16 @@ QUnit.test("replaces GUID in image alt text on iOS", assert => { }); QUnit.test("isAnImage", assert => { - _.each(["png", "jpg", "jpeg", "bmp", "gif", "tif", "tiff", "ico"], function( - extension - ) { - var image = "image." + extension; - assert.ok(isAnImage(image), image + " is recognized as an image"); - assert.ok( - isAnImage("http://foo.bar/path/to/" + image), - image + " is recognized as an image" - ); - }); + ["png", "jpg", "jpeg", "bmp", "gif", "tif", "tiff", "ico"].forEach( + extension => { + var image = "image." + extension; + assert.ok(isAnImage(image), image + " is recognized as an image"); + assert.ok( + isAnImage("http://foo.bar/path/to/" + image), + image + " is recognized as an image" + ); + } + ); assert.not(isAnImage("file.txt")); assert.not(isAnImage("http://foo.bar/path/to/file.txt")); assert.not(isAnImage(""));