mirror of
				https://github.com/zulip/zulip.git
				synced 2025-11-04 05:53:43 +00:00 
			
		
		
		
	And convert the corresponding function expressions to arrow style
while we’re here.
import * as babelParser from "recast/parsers/babel";
import * as recast from "recast";
import * as tsParser from "recast/parsers/typescript";
import { builders as b, namedTypes as n } from "ast-types";
import K from "ast-types/gen/kinds";
import fs from "fs";
import path from "path";
import process from "process";
const checkExpression = (node: n.Node): node is K.ExpressionKind =>
  n.Expression.check(node);
for (const file of process.argv.slice(2)) {
  console.log("Parsing", file);
  const ast = recast.parse(fs.readFileSync(file, { encoding: "utf8" }), {
    parser: path.extname(file) === ".ts" ? tsParser : babelParser,
  });
  let changed = false;
  recast.visit(ast, {
    visitCallExpression(path) {
      const { callee, arguments: args } = path.node;
      if (
        n.MemberExpression.check(callee) &&
        !callee.computed &&
        n.Identifier.check(callee.object) &&
        callee.object.name === "_" &&
        n.Identifier.check(callee.property) &&
        callee.property.name === "map" &&
        args.length === 2 &&
        checkExpression(args[0]) &&
        checkExpression(args[1])
      ) {
        const [arr, fn] = args;
        path.replace(
          b.callExpression(b.memberExpression(arr, b.identifier("map")), [
            n.FunctionExpression.check(fn) ||
            n.ArrowFunctionExpression.check(fn)
              ? b.arrowFunctionExpression(
                  fn.params,
                  n.BlockStatement.check(fn.body) &&
                    fn.body.body.length === 1 &&
                    n.ReturnStatement.check(fn.body.body[0])
                    ? fn.body.body[0].argument || b.identifier("undefined")
                    : fn.body
                )
              : fn,
          ])
        );
        changed = true;
      }
      this.traverse(path);
    },
  });
  if (changed) {
    console.log("Writing", file);
    fs.writeFileSync(file, recast.print(ast).code, { encoding: "utf8" });
  }
}
Signed-off-by: Anders Kaseorg <anders@zulipchat.com>
		
	
		
			
				
	
	
		
			291 lines
		
	
	
		
			7.0 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
			
		
		
	
	
			291 lines
		
	
	
		
			7.0 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
const render_more_topics = require('../templates/more_topics.hbs');
 | 
						|
const render_more_topics_spinner = require('../templates/more_topics_spinner.hbs');
 | 
						|
const render_topic_list_item = require('../templates/topic_list_item.hbs');
 | 
						|
const IntDict = require('./int_dict').IntDict;
 | 
						|
const topic_list_data = require('./topic_list_data');
 | 
						|
 | 
						|
/*
 | 
						|
    Track all active widgets with an IntDict.
 | 
						|
 | 
						|
    (We have at max one for now, but we may
 | 
						|
    eventually allow multiple streams to be
 | 
						|
    expanded.)
 | 
						|
*/
 | 
						|
 | 
						|
const active_widgets = new IntDict();
 | 
						|
 | 
						|
// We know whether we're zoomed or not.
 | 
						|
let zoomed = false;
 | 
						|
 | 
						|
exports.update = function () {
 | 
						|
    for (const widget of active_widgets.values()) {
 | 
						|
        widget.build();
 | 
						|
    }
 | 
						|
};
 | 
						|
 | 
						|
exports.remove_expanded_topics = function () {
 | 
						|
    stream_popover.hide_topic_popover();
 | 
						|
 | 
						|
    for (const widget of active_widgets.values()) {
 | 
						|
        widget.remove();
 | 
						|
    }
 | 
						|
 | 
						|
    active_widgets.clear();
 | 
						|
};
 | 
						|
 | 
						|
exports.close = function () {
 | 
						|
    zoomed = false;
 | 
						|
    exports.remove_expanded_topics();
 | 
						|
};
 | 
						|
 | 
						|
exports.zoom_out = function () {
 | 
						|
    zoomed = false;
 | 
						|
 | 
						|
    const stream_ids = Array.from(active_widgets.keys());
 | 
						|
 | 
						|
    if (stream_ids.length !== 1) {
 | 
						|
        blueslip.error('Unexpected number of topic lists to zoom out.');
 | 
						|
        return;
 | 
						|
    }
 | 
						|
 | 
						|
    const stream_id = stream_ids[0];
 | 
						|
    const widget = active_widgets.get(stream_id);
 | 
						|
    const parent_widget = widget.get_parent();
 | 
						|
 | 
						|
    exports.rebuild(parent_widget, stream_id);
 | 
						|
};
 | 
						|
 | 
						|
exports.keyed_topic_li = (convo) => {
 | 
						|
    const render = () => {
 | 
						|
        return render_topic_list_item(convo);
 | 
						|
    };
 | 
						|
 | 
						|
    const eq = (other) => {
 | 
						|
        return _.isEqual(convo, other.convo);
 | 
						|
    };
 | 
						|
 | 
						|
    const key = 't:' + convo.topic_name;
 | 
						|
 | 
						|
    return {
 | 
						|
        key: key,
 | 
						|
        render: render,
 | 
						|
        convo: convo,
 | 
						|
        eq: eq,
 | 
						|
    };
 | 
						|
};
 | 
						|
 | 
						|
exports.more_li = (more_topics_unreads) => {
 | 
						|
    const render = () => {
 | 
						|
        return render_more_topics({
 | 
						|
            more_topics_unreads: more_topics_unreads,
 | 
						|
        });
 | 
						|
    };
 | 
						|
 | 
						|
    const eq = (other) => {
 | 
						|
        return other.more_items &&
 | 
						|
            more_topics_unreads === other.more_topics_unreads;
 | 
						|
    };
 | 
						|
 | 
						|
    const key = 'more';
 | 
						|
 | 
						|
    return {
 | 
						|
        key: key,
 | 
						|
        more_items: true,
 | 
						|
        more_topics_unreads: more_topics_unreads,
 | 
						|
        render: render,
 | 
						|
        eq: eq,
 | 
						|
    };
 | 
						|
};
 | 
						|
 | 
						|
exports.spinner_li = () => {
 | 
						|
    const render = () => {
 | 
						|
        return render_more_topics_spinner();
 | 
						|
    };
 | 
						|
 | 
						|
    const eq = (other) => {
 | 
						|
        return other.spinner;
 | 
						|
    };
 | 
						|
 | 
						|
    const key = 'more';
 | 
						|
 | 
						|
    return {
 | 
						|
        key: key,
 | 
						|
        spinner: true,
 | 
						|
        render: render,
 | 
						|
        eq: eq,
 | 
						|
    };
 | 
						|
};
 | 
						|
 | 
						|
exports.widget = function (parent_elem, my_stream_id) {
 | 
						|
    const self = {};
 | 
						|
 | 
						|
    self.prior_dom = undefined;
 | 
						|
 | 
						|
    self.build_list = function (spinner) {
 | 
						|
        const list_info = topic_list_data.get_list_info(
 | 
						|
            my_stream_id, zoomed);
 | 
						|
 | 
						|
        const num_possible_topics = list_info.num_possible_topics;
 | 
						|
        const more_topics_unreads = list_info.more_topics_unreads;
 | 
						|
 | 
						|
        const is_showing_all_possible_topics =
 | 
						|
            list_info.items.length === num_possible_topics &&
 | 
						|
            topic_data.is_complete_for_stream_id(my_stream_id);
 | 
						|
 | 
						|
        const attrs = [
 | 
						|
            ['class', 'topic-list'],
 | 
						|
        ];
 | 
						|
 | 
						|
        const nodes = list_info.items.map(exports.keyed_topic_li);
 | 
						|
 | 
						|
        if (spinner) {
 | 
						|
            nodes.push(exports.spinner_li());
 | 
						|
        } else if (!is_showing_all_possible_topics) {
 | 
						|
            nodes.push(exports.more_li(more_topics_unreads));
 | 
						|
        }
 | 
						|
 | 
						|
        const dom = vdom.ul({
 | 
						|
            attrs: attrs,
 | 
						|
            keyed_nodes: nodes,
 | 
						|
        });
 | 
						|
 | 
						|
        return dom;
 | 
						|
    };
 | 
						|
 | 
						|
    self.get_parent = function () {
 | 
						|
        return parent_elem;
 | 
						|
    };
 | 
						|
 | 
						|
    self.get_stream_id = function () {
 | 
						|
        return my_stream_id;
 | 
						|
    };
 | 
						|
 | 
						|
    self.remove = function () {
 | 
						|
        parent_elem.find('.topic-list').remove();
 | 
						|
        self.prior_dom = undefined;
 | 
						|
    };
 | 
						|
 | 
						|
    self.build = function (spinner) {
 | 
						|
        const new_dom = self.build_list(spinner);
 | 
						|
 | 
						|
        function replace_content(html) {
 | 
						|
            self.remove();
 | 
						|
            parent_elem.append(html);
 | 
						|
        }
 | 
						|
 | 
						|
        function find() {
 | 
						|
            return parent_elem.find('.topic-list');
 | 
						|
        }
 | 
						|
 | 
						|
        vdom.update(replace_content, find, new_dom, self.prior_dom);
 | 
						|
 | 
						|
        self.prior_dom = new_dom;
 | 
						|
    };
 | 
						|
 | 
						|
    return self;
 | 
						|
};
 | 
						|
 | 
						|
exports.active_stream_id = function () {
 | 
						|
    const stream_ids = Array.from(active_widgets.keys());
 | 
						|
 | 
						|
    if (stream_ids.length !== 1) {
 | 
						|
        return;
 | 
						|
    }
 | 
						|
 | 
						|
    return stream_ids[0];
 | 
						|
};
 | 
						|
 | 
						|
exports.get_stream_li = function () {
 | 
						|
    const widgets = Array.from(active_widgets.values());
 | 
						|
 | 
						|
    if (widgets.length !== 1) {
 | 
						|
        return;
 | 
						|
    }
 | 
						|
 | 
						|
    const stream_li = widgets[0].get_parent();
 | 
						|
    return stream_li;
 | 
						|
};
 | 
						|
 | 
						|
exports.rebuild = function (stream_li, stream_id) {
 | 
						|
    const active_widget = active_widgets.get(stream_id);
 | 
						|
 | 
						|
    if (active_widget) {
 | 
						|
        active_widget.build();
 | 
						|
        return;
 | 
						|
    }
 | 
						|
 | 
						|
    exports.remove_expanded_topics();
 | 
						|
    const widget = exports.widget(stream_li, stream_id);
 | 
						|
    widget.build();
 | 
						|
 | 
						|
    active_widgets.set(stream_id, widget);
 | 
						|
};
 | 
						|
 | 
						|
// For zooming, we only do topic-list stuff here...let stream_list
 | 
						|
// handle hiding/showing the non-narrowed streams
 | 
						|
exports.zoom_in = function () {
 | 
						|
    zoomed = true;
 | 
						|
 | 
						|
    const stream_id = exports.active_stream_id();
 | 
						|
    if (!stream_id) {
 | 
						|
        blueslip.error('Cannot find widget for topic history zooming.');
 | 
						|
        return;
 | 
						|
    }
 | 
						|
 | 
						|
    const active_widget = active_widgets.get(stream_id);
 | 
						|
 | 
						|
    function on_success() {
 | 
						|
        if (!active_widgets.has(stream_id)) {
 | 
						|
            blueslip.warn('User re-narrowed before topic history was returned.');
 | 
						|
            return;
 | 
						|
        }
 | 
						|
 | 
						|
        if (!zoomed) {
 | 
						|
            blueslip.warn('User zoomed out before topic history was returned.');
 | 
						|
            // Note that we could attempt to re-draw the zoomed out topic list
 | 
						|
            // here, given that we have more history, but that might be more
 | 
						|
            // confusing than helpful to a user who is likely trying to browse
 | 
						|
            // other streams.
 | 
						|
            return;
 | 
						|
        }
 | 
						|
 | 
						|
        active_widget.build();
 | 
						|
    }
 | 
						|
 | 
						|
    ui.get_scroll_element($('#stream-filters-container')).scrollTop(0);
 | 
						|
 | 
						|
    const spinner = true;
 | 
						|
    active_widget.build(spinner);
 | 
						|
 | 
						|
    topic_data.get_server_history(stream_id, on_success);
 | 
						|
};
 | 
						|
 | 
						|
exports.initialize = function () {
 | 
						|
    $('#stream_filters').on('click', '.topic-box', function (e) {
 | 
						|
        if (e.metaKey || e.ctrlKey) {
 | 
						|
            return;
 | 
						|
        }
 | 
						|
        if ($(e.target).closest('.show-more-topics').length > 0) {
 | 
						|
            return;
 | 
						|
        }
 | 
						|
 | 
						|
        // In a more componentized world, we would delegate some
 | 
						|
        // of this stuff back up to our parents.
 | 
						|
 | 
						|
        const stream_row = $(e.target).parents('.narrow-filter');
 | 
						|
        const stream_id = parseInt(stream_row.attr('data-stream-id'), 10);
 | 
						|
        const sub = stream_data.get_sub_by_id(stream_id);
 | 
						|
        const topic = $(e.target).parents('li').attr('data-topic-name');
 | 
						|
 | 
						|
        narrow.activate([
 | 
						|
            {operator: 'stream', operand: sub.name},
 | 
						|
            {operator: 'topic', operand: topic}],
 | 
						|
                        {trigger: 'sidebar'});
 | 
						|
 | 
						|
        e.preventDefault();
 | 
						|
    });
 | 
						|
};
 | 
						|
 | 
						|
 | 
						|
window.topic_list = exports;
 |