<commit_before>/**********************************************************************
    Freeciv-web - the web version of Freeciv. http://play.freeciv.org/
    Copyright (C) 2009-2015  The Freeciv-web project

    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU Affero General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU Affero General Public License for more details.

    You should have received a copy of the GNU Affero General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.

***********************************************************************/

var toplevel_menu_items = ["help_terrain", "help_economy", "help_cities",
    "help_city_improvements", "help_wonders_of_the_world", "help_units",
    "help_combat", "help_technology"];
var hidden_menu_items = ["help_connecting", "help_languages", "help_governor",
    "help_chatline", "help_about", "help_worklist_editor"];

/**************************************************************************
 Show the Freeciv-web Help Dialog
**************************************************************************/
function show_help()
{
  $("#tabs-hel").show();
  $("#help_menu").remove();
  $("#help_info_page").remove();
  $("

").appendTo("#tabs-hel");
  for (var sec_id in helpdata_order) {
    var key = helpdata_order[sec_id];
    var sec_name = helpdata[key]['name'];
    if (hidden_menu_items.indexOf(key) > -1) {
      continue;
    } else if (key.indexOf("help_gen") != -1) {
      generate_help_menu(key);
    } else if (toplevel_menu_items.indexOf(key) > -1) {
      generate_help_toplevel(key);
    } else {
      var parent_key = find_parent_help_key(key);
      $("
"
        + helpdata_tag_to_title(key) + "
").appendTo(parent_key);
    }
  }

  $("#help_menu").menu({
    select: function( event, ui ) {handle_help_menu_select(ui); }
  });

  show_help_intro();
  $("#tabs-hel").css("height", $(window).height() - 60);
  $("#help_info_page").css("max-width", $(window).width() - $("#help_menu").width() - 60);

}

/**************************************************************************
...
**************************************************************************/
function show_help_intro()
{
  $.get( "/docs/help_intro.txt", function( data ) {
      $("#help_info_page").html(data);
  });
}

/**************************************************************************
...
**************************************************************************/
function generate_help_menu(key)
{
  var impr_id;
  var improvement;
  if (key == "help_gen_terrain") {
    for (var terrain_id in terrains) {
      var terrain = terrains[terrain_id];
      $("
"
        + terrain['name'] + "
").appendTo("#help_terrain_ul");
    }
  } else if (key == "help_gen_improvements") {
    for (impr_id in improvements) {
      improvement = improvements[impr_id];
      if (is_wonder(improvement)) continue;
      $("
"
        + improvement['name'] + "
").appendTo("#help_city_improvements_ul");
    }
  } else if (key == "help_gen_wonders") {
    for (impr_id in improvements) {
      improvement = improvements[impr_id];
      if (!is_wonder(improvement)) continue;
      $("
"
        + improvement['name'] + "
").appendTo("#help_wonders_of_the_world_ul");
    }
  } else if (key == "help_gen_units") {
    for (var i = 0; i < unittype_ids_alphabetic().length; i++) {
      var unit_id = unittype_ids_alphabetic()[i];
      var punit_type = unit_types[unit_id];

       $("
"
          + punit_type['name'] + "
").appendTo("#help_units_ul");
    }
  } else if (key == "help_gen_techs") {
    for (var tech_id in techs) {
      var tech = techs[tech_id];
      if (tech_id == 0) continue;
      $("
"
          + tech['name'] + "
").appendTo("#help_technology_ul");
    }
  } else if (key == "help_gen_ruleset") {
    $("
"
       + "About Current Ruleset" + "
").appendTo(
          find_parent_help_key(key));
  }
}

/**************************************************************************
...
**************************************************************************/
function render_sprite(sprite)
{
  var msg = "

";
  return msg;
}

/**************************************************************************
...
**************************************************************************/
function generate_help_toplevel(key)
{
  var parent_key = find_parent_help_key(key);
  $("
"
     + helpdata_tag_to_title(key) + "
").appendTo(parent_key);
  $("

").appendTo("#" + key);

}

/**************************************************************************
...
**************************************************************************/
function find_parent_help_key(key)
{
  if (key == "help_terrain_alterations") {
    return "#help_terrain_ul";
  } else if (key == "help_villages" || key == "help_borders") {
    return "#help_terrain_ul";
  } else if (key == "help_food" || key == "help_production" || key == "help_trade") {
    return "#help_economy_ul";
  } else if (key == "help_specialists" || key == "help_happiness" || key == "help_pollution"
        || key == "help_plague" || key == "help_migration") {
    return "#help_cities_ul";
  } else if (key == "help_combat_example_1" || key == "help_combat_example_2") {
    return "#help_combat_ul";
  } else  {
    return "#help_menu";
  }
}
/**************************************************************************
...
**************************************************************************/
function handle_help_menu_select( ui )
{
  var selected_tag = $(ui.item).data("helptag");
  if (selected_tag.indexOf("help_gen") != -1) {
    generate_help_text(selected_tag);
  } else if (selected_tag == "help_copying") {
    $.get( "/docs/LICENSE.txt", function( data ) {
      $("#help_info_page").html("
Freeciv-Web License
" + data.replace(/\n/g, "
"));
    });
  } else if (selected_tag == "help_controls") {
    $.get( "/docs/controls.txt", function( data ) {
      $("#help_info_page").html(data.replace(/\n/g, "
"));
    });
  } else {
    var msg = "
" + helpdata_tag_to_title(selected_tag) + "
" + helpdata[selected_tag]['text'];
    $("#help_info_page").html(msg);
  }

  $("#help_info_page").focus();
}

/**************************************************************************
...
**************************************************************************/
function generate_help_text(key)
{
  var msg = "";
  if (key.indexOf("help_gen_terrain") != -1) {
    var terrain = terrains[parseInt(key.replace("help_gen_terrain_", ""))];
    msg = "
" + terrain['name'] + "
" + terrain['helptext']
	    + "

Movement cost: " + terrain['movement_cost']
	    + "
Defense bonus: " + terrain['defense_bonus']
	    + "
Food/Prod/Trade: " + terrain['output'][0] + "/"
	    + terrain['output'][1] + "/" + terrain['output'][2];
  } else if (key.indexOf("help_gen_improvements") != -1 || key.indexOf("help_gen_wonders") != -1) {
    var improvement = improvements[parseInt(key.replace("help_gen_wonders_", "").replace("help_gen_improvements_", ""))];
    msg = "
" + improvement['name'] + "
"
	    + render_sprite(get_improvement_image_sprite(improvement)) + "
"
	    + improvement['helptext']
            + "

Cost: " + improvement['build_cost']
            + "
Upkeep: " + improvement['upkeep'];
    var reqs = get_improvement_requirements(improvement['id']);
    if (reqs != null) {
      msg += "
Requirements: ";
      for (var n = 0; n < reqs.length; n++) {
       msg += techs[reqs[n]]['name'] + " ";
      }
    }
    msg += "

<button class='help_button' onclick=\"show_wikipedia_dialog('" + improvement['name'] + "');\">Wikipedia on "
	    + improvement['name'] +  "</button>";
  } else if (key.indexOf("help_gen_units") != -1) {
    var punit_type = unit_types[parseInt(key.replace("help_gen_units_", ""))];
    msg = "
" + punit_type['name'] + "
"
	    + render_sprite(get_unit_type_image_sprite(punit_type)) + "
"
	    + punit_type['helptext']
            + "

Cost: " + punit_type['build_cost'];
            /*+ "
Upkeep: " + improvement['upkeep'];*/
    msg += "
Attack: " + punit_type['attack_strength'];
    msg += "
Defense: " + punit_type['defense_strength'];
    msg += "
Firepower: " + punit_type['firepower'];
    msg += "
Hitpoints: " + punit_type['hp'];
    msg += "
Moves: " + move_points_text(punit_type['move_rate']);
    msg += "
Vision: " + punit_type['vision_radius_sq'];

    var ireqs = get_improvement_requirements(punit_type['impr_requirement']);
    if (ireqs != null && techs[ireqs] != null) {
      msg += "
Building Requirements: ";
      for (var m = 0; m < ireqs.length; m++) {
        msg += techs[ireqs[m]]['name'] + " ";
      }
    }
    var treq = punit_type['tech_requirement'];
    if (treq != null && techs[treq] != null) {
      msg += "
Tech Requirements: " + techs[treq]['name'];
    }
    msg += "

<button class='help_button' onclick=\"show_wikipedia_dialog('" + punit_type['name'] + "');\">Wikipedia on "
	    + punit_type['name'] +  "</button>";
  } else if (key.indexOf("help_gen_techs") != -1) {
    var tech = techs[parseInt(key.replace("help_gen_techs_", ""))];
    msg = "
" + tech['name'] + "
"
	    + render_sprite(get_technology_image_sprite(tech)) + "
"
	    + get_advances_text(tech['id']);
    msg += "

<button class='help_button' onclick=\"show_wikipedia_dialog('" + tech['name'] + "');\">Wikipedia on "
	    + tech['name'] +  "</button>";
  } else if (key == "help_gen_ruleset") {
    msg = "
" + ruleset_control['name'] + "
";
    if (ruleset_summary != null) {
      msg += "
" + ruleset_summary.replace(/\n/g, "
") + "
";
    }
    if (ruleset_description != null) {
      msg += "
" + ruleset_description.replace(/\n/g, "
") + "
";
    }
  }

  $("#help_info_page").html(msg);
  $(".help_button").button();
}

/**************************************************************************
...
**************************************************************************/
function helpdata_tag_to_title(tag)
{
  var result = tag.replace("_of_the_world", "").replace("help_", "").replace("gen_", "").replace("misc_", "").replace(/_/g, " ");
  return to_title_case(result);

}
<commit_msg>Manual: mark the unit type helptext with an id.<commit_after>/**********************************************************************
    Freeciv-web - the web version of Freeciv. http://play.freeciv.org/
    Copyright (C) 2009-2015  The Freeciv-web project

    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU Affero General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU Affero General Public License for more details.

    You should have received a copy of the GNU Affero General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.

***********************************************************************/

var toplevel_menu_items = ["help_terrain", "help_economy", "help_cities",
    "help_city_improvements", "help_wonders_of_the_world", "help_units",
    "help_combat", "help_technology"];
var hidden_menu_items = ["help_connecting", "help_languages", "help_governor",
    "help_chatline", "help_about", "help_worklist_editor"];

/**************************************************************************
 Show the Freeciv-web Help Dialog
**************************************************************************/
function show_help()
{
  $("#tabs-hel").show();
  $("#help_menu").remove();
  $("#help_info_page").remove();
  $("

").appendTo("#tabs-hel");
  for (var sec_id in helpdata_order) {
    var key = helpdata_order[sec_id];
    var sec_name = helpdata[key]['name'];
    if (hidden_menu_items.indexOf(key) > -1) {
      continue;
    } else if (key.indexOf("help_gen") != -1) {
      generate_help_menu(key);
    } else if (toplevel_menu_items.indexOf(key) > -1) {
      generate_help_toplevel(key);
    } else {
      var parent_key = find_parent_help_key(key);
      $("
"
        + helpdata_tag_to_title(key) + "
").appendTo(parent_key);
    }
  }

  $("#help_menu").menu({
    select: function( event, ui ) {handle_help_menu_select(ui); }
  });

  show_help_intro();
  $("#tabs-hel").css("height", $(window).height() - 60);
  $("#help_info_page").css("max-width", $(window).width() - $("#help_menu").width() - 60);

}

/**************************************************************************
...
**************************************************************************/
function show_help_intro()
{
  $.get( "/docs/help_intro.txt", function( data ) {
      $("#help_info_page").html(data);
  });
}

/**************************************************************************
...
**************************************************************************/
function generate_help_menu(key)
{
  var impr_id;
  var improvement;
  if (key == "help_gen_terrain") {
    for (var terrain_id in terrains) {
      var terrain = terrains[terrain_id];
      $("
"
        + terrain['name'] + "
").appendTo("#help_terrain_ul");
    }
  } else if (key == "help_gen_improvements") {
    for (impr_id in improvements) {
      improvement = improvements[impr_id];
      if (is_wonder(improvement)) continue;
      $("
"
        + improvement['name'] + "
").appendTo("#help_city_improvements_ul");
    }
  } else if (key == "help_gen_wonders") {
    for (impr_id in improvements) {
      improvement = improvements[impr_id];
      if (!is_wonder(improvement)) continue;
      $("
"
        + improvement['name'] + "
").appendTo("#help_wonders_of_the_world_ul");
    }
  } else if (key == "help_gen_units") {
    for (var i = 0; i < unittype_ids_alphabetic().length; i++) {
      var unit_id = unittype_ids_alphabetic()[i];
      var punit_type = unit_types[unit_id];

       $("
"
          + punit_type['name'] + "
").appendTo("#help_units_ul");
    }
  } else if (key == "help_gen_techs") {
    for (var tech_id in techs) {
      var tech = techs[tech_id];
      if (tech_id == 0) continue;
      $("
"
          + tech['name'] + "
").appendTo("#help_technology_ul");
    }
  } else if (key == "help_gen_ruleset") {
    $("
"
       + "About Current Ruleset" + "
").appendTo(
          find_parent_help_key(key));
  }
}

/**************************************************************************
...
**************************************************************************/
function render_sprite(sprite)
{
  var msg = "

";
  return msg;
}

/**************************************************************************
...
**************************************************************************/
function generate_help_toplevel(key)
{
  var parent_key = find_parent_help_key(key);
  $("
"
     + helpdata_tag_to_title(key) + "
").appendTo(parent_key);
  $("

").appendTo("#" + key);

}

/**************************************************************************
...
**************************************************************************/
function find_parent_help_key(key)
{
  if (key == "help_terrain_alterations") {
    return "#help_terrain_ul";
  } else if (key == "help_villages" || key == "help_borders") {
    return "#help_terrain_ul";
  } else if (key == "help_food" || key == "help_production" || key == "help_trade") {
    return "#help_economy_ul";
  } else if (key == "help_specialists" || key == "help_happiness" || key == "help_pollution"
        || key == "help_plague" || key == "help_migration") {
    return "#help_cities_ul";
  } else if (key == "help_combat_example_1" || key == "help_combat_example_2") {
    return "#help_combat_ul";
  } else  {
    return "#help_menu";
  }
}
/**************************************************************************
...
**************************************************************************/
function handle_help_menu_select( ui )
{
  var selected_tag = $(ui.item).data("helptag");
  if (selected_tag.indexOf("help_gen") != -1) {
    generate_help_text(selected_tag);
  } else if (selected_tag == "help_copying") {
    $.get( "/docs/LICENSE.txt", function( data ) {
      $("#help_info_page").html("
Freeciv-Web License
" + data.replace(/\n/g, "
"));
    });
  } else if (selected_tag == "help_controls") {
    $.get( "/docs/controls.txt", function( data ) {
      $("#help_info_page").html(data.replace(/\n/g, "
"));
    });
  } else {
    var msg = "
" + helpdata_tag_to_title(selected_tag) + "
" + helpdata[selected_tag]['text'];
    $("#help_info_page").html(msg);
  }

  $("#help_info_page").focus();
}

/**************************************************************************
...
**************************************************************************/
function generate_help_text(key)
{
  var msg = "";
  if (key.indexOf("help_gen_terrain") != -1) {
    var terrain = terrains[parseInt(key.replace("help_gen_terrain_", ""))];
    msg = "
" + terrain['name'] + "
" + terrain['helptext']
	    + "

Movement cost: " + terrain['movement_cost']
	    + "
Defense bonus: " + terrain['defense_bonus']
	    + "
Food/Prod/Trade: " + terrain['output'][0] + "/"
	    + terrain['output'][1] + "/" + terrain['output'][2];
  } else if (key.indexOf("help_gen_improvements") != -1 || key.indexOf("help_gen_wonders") != -1) {
    var improvement = improvements[parseInt(key.replace("help_gen_wonders_", "").replace("help_gen_improvements_", ""))];
    msg = "
" + improvement['name'] + "
"
	    + render_sprite(get_improvement_image_sprite(improvement)) + "
"
	    + improvement['helptext']
            + "

Cost: " + improvement['build_cost']
            + "
Upkeep: " + improvement['upkeep'];
    var reqs = get_improvement_requirements(improvement['id']);
    if (reqs != null) {
      msg += "
Requirements: ";
      for (var n = 0; n < reqs.length; n++) {
       msg += techs[reqs[n]]['name'] + " ";
      }
    }
    msg += "

<button class='help_button' onclick=\"show_wikipedia_dialog('" + improvement['name'] + "');\">Wikipedia on "
	    + improvement['name'] +  "</button>";
  } else if (key.indexOf("help_gen_units") != -1) {
    var punit_type = unit_types[parseInt(key.replace("help_gen_units_", ""))];
    msg = "
" + punit_type['name'] + "
";
    msg = render_sprite(get_unit_type_image_sprite(punit_type));
    msg += "
" + punit_type['helptext'] + "
";
    msg += "Cost: " + punit_type['build_cost'];
            /*+ "
Upkeep: " + improvement['upkeep'];*/
    msg += "
Attack: " + punit_type['attack_strength'];
    msg += "
Defense: " + punit_type['defense_strength'];
    msg += "
Firepower: " + punit_type['firepower'];
    msg += "
Hitpoints: " + punit_type['hp'];
    msg += "
Moves: " + move_points_text(punit_type['move_rate']);
    msg += "
Vision: " + punit_type['vision_radius_sq'];

    var ireqs = get_improvement_requirements(punit_type['impr_requirement']);
    if (ireqs != null && techs[ireqs] != null) {
      msg += "
Building Requirements: ";
      for (var m = 0; m < ireqs.length; m++) {
        msg += techs[ireqs[m]]['name'] + " ";
      }
    }
    var treq = punit_type['tech_requirement'];
    if (treq != null && techs[treq] != null) {
      msg += "
Tech Requirements: " + techs[treq]['name'];
    }
    msg += "

<button class='help_button' onclick=\"show_wikipedia_dialog('" + punit_type['name'] + "');\">Wikipedia on "
	    + punit_type['name'] +  "</button>";
  } else if (key.indexOf("help_gen_techs") != -1) {
    var tech = techs[parseInt(key.replace("help_gen_techs_", ""))];
    msg = "
" + tech['name'] + "
"
	    + render_sprite(get_technology_image_sprite(tech)) + "
"
	    + get_advances_text(tech['id']);
    msg += "

<button class='help_button' onclick=\"show_wikipedia_dialog('" + tech['name'] + "');\">Wikipedia on "
	    + tech['name'] +  "</button>";
  } else if (key == "help_gen_ruleset") {
    msg = "
" + ruleset_control['name'] + "
";
    if (ruleset_summary != null) {
      msg += "
" + ruleset_summary.replace(/\n/g, "
") + "
";
    }
    if (ruleset_description != null) {
      msg += "
" + ruleset_description.replace(/\n/g, "
") + "
";
    }
  }

  $("#help_info_page").html(msg);
  $(".help_button").button();
}

/**************************************************************************
...
**************************************************************************/
function helpdata_tag_to_title(tag)
{
  var result = tag.replace("_of_the_world", "").replace("help_", "").replace("gen_", "").replace("misc_", "").replace(/_/g, " ");
  return to_title_case(result);

}
<|endoftext|>


<commit_before>if (!window.xe) xe = {};

xe.Editors = [];

function editorStart_xe(editor_sequence, primary_key, content_key, editor_height, colorset, content_style, content_font, content_font_size) {
    if(typeof(colorset)=='undefined') colorset = 'white';
    if(typeof(content_style)=='undefined') content_style = 'xeStyle';
    if(typeof(content_font)=='undefined') content_font= '';
    if(typeof(content_font_size)=='undefined') content_font_size= '';

    var target_src = request_uri+'modules/editor/styles/'+content_style+'/editor.html';

    var textarea = jQuery("#xpress-editor-"+editor_sequence);
    var iframe   = jQuery('');
    var htmlsrc  = jQuery('<textarea rows="10" cols="20" class="input_syntax '+colorset+'" style="display:none"></textarea>');
    var form     = textarea.get(0).form;
    form.setAttribute('editor_sequence', editor_sequence);
    textarea.css("display","none");

    var saved_content = '';
    if(jQuery("input[name=content]",form).size()>0){
        saved_content=jQuery("input[name=content]",form).val().replace(/src=\"files\/attach/g,'src="'+request_uri+'files/attach'); //'
        jQuery("#xpress-editor-"+editor_sequence).val(saved_content);
    }

    /*
    // remove procFilter
    if(form.comment_srl){
        form.onsubmit=function(){
            var content = editorGetContent(editor_sequence);
            editorRelKeys[editor_sequence]['content'].value = content;
            insert_comment(form);
            return false;
        };
    }else{
        form.onsubmit=function(){
            var content = editorGetContent(editor_sequence);
            editorRelKeys[editor_sequence]['content'].value = content;
            insert(form);
            return false;
        };
    }
    */

    // hide textarea
    textarea.hide().css('width', '99%').before(iframe).after(htmlsrc);

    // create an editor
    var oEditor          = new xe.XpressCore();
    var oWYSIWYGIFrame   = iframe.get(0);
    var oIRTextarea      = textarea.get(0);
    var oHTMLSrcTextarea = htmlsrc.get(0);
    var elAppContainer   = jQuery('.xpress-editor', form).get(0);

    oEditor.getFrame = function(){ return oWYSIWYGIFrame;}
	oEditor.getContent = function(){
		editorGetContentTextarea_xe(editor_sequence);
	}

    var content = form[content_key].value;
    if(xFF && !content) content = '

';

    // src, href, url의 XE 상대경로를 http로 시작하는 full path로 변경
    content = content.replace(/(src=|href=|url\()("|\')*([^"\'\)]+)("|\'|\))*(\s|>)*/ig, function(m0,m1,m2,m3,m4,m5) {
        if(m1=="url(") { m2=''; m4=')'; } else { if(typeof(m2)=='undefined') m2 = '"'; if(typeof(m4)=='undefined') m4 = '"'; if(typeof(m5)=='undefined') m5 = ''; }
        var val = jQuery.trim(m3).replace(/^\.\//,'');
        if(/^(http|https|ftp|telnet|mms|\/|\.\.)/i.test(val)) return m0;
        return m1+m2+request_uri+val+m4+m5;
    });

    form[content_key].value = content;
    jQuery("#xpress-editor-"+editor_sequence).val(content);

    // Set standard API
    editorRelKeys[editor_sequence] = new Array();
    editorRelKeys[editor_sequence]["primary"]   = form[primary_key];
    editorRelKeys[editor_sequence]["content"]   = form[content_key];
    editorRelKeys[editor_sequence]["func"]      = editorGetContentTextarea_xe;
    editorRelKeys[editor_sequence]["editor"]    = oEditor;
    editorRelKeys[editor_sequence]["pasteHTML"] = function(text){
        oEditor.exec('PASTE_HTML',[text]);
    }
    xe.Editors[editor_sequence] = oEditor;

    // register plugins
    oEditor.registerPlugin(new xe.CorePlugin(null));

    oEditor.registerPlugin(new xe.XE_PreservTemplate(jQuery("#xpress-editor-"+editor_sequence).val()));
    oEditor.registerPlugin(new xe.StringConverterManager());
    oEditor.registerPlugin(new xe.XE_EditingAreaManager("WYSIWYG", oIRTextarea, {nHeight:parseInt(editor_height), nMinHeight:205}, null, elAppContainer));
    oEditor.registerPlugin(new xe.XE_EditingArea_HTMLSrc(oHTMLSrcTextarea));
    oEditor.registerPlugin(new xe.XE_EditingAreaVerticalResizer(elAppContainer));
    oEditor.registerPlugin(new xe.Utils());
    oEditor.registerPlugin(new xe.DialogLayerManager());
    oEditor.registerPlugin(new xe.ActiveLayerManager());
    oEditor.registerPlugin(new xe.Hotkey());
    oEditor.registerPlugin(new xe.XE_WYSIWYGStyler());
    oEditor.registerPlugin(new xe.XE_WYSIWYGStyleGetter());
    oEditor.registerPlugin(new xe.MessageManager(oMessageMap));
    oEditor.registerPlugin(new xe.XE_Toolbar(elAppContainer));

    oEditor.registerPlugin(new xe.XE_XHTMLFormatter);
    oEditor.registerPlugin(new xe.XE_GET_WYSYWYG_MODE(editor_sequence));
    oEditor.registerPlugin(new xe.XE_GET_WYSYWYG_CONTENT());

    if(jQuery("ul.extra1").length) {
        oEditor.registerPlugin(new xe.XE_ColorPalette(elAppContainer));
        oEditor.registerPlugin(new xe.XE_FontColor(elAppContainer));
        oEditor.registerPlugin(new xe.XE_BGColor(elAppContainer));
        oEditor.registerPlugin(new xe.XE_Quote(elAppContainer));
        oEditor.registerPlugin(new xe.XE_FontNameWithSelectUI(elAppContainer));
        oEditor.registerPlugin(new xe.XE_FontSizeWithSelectUI(elAppContainer));
        oEditor.registerPlugin(new xe.XE_LineHeightWithSelectUI(elAppContainer));
        oEditor.registerPlugin(new xe.XE_UndoRedo());
        oEditor.registerPlugin(new xe.XE_Table(elAppContainer));
        oEditor.registerPlugin(new xe.XE_Hyperlink(elAppContainer));
        oEditor.registerPlugin(new xe.XE_FindReplacePlugin(elAppContainer));
        oEditor.registerPlugin(new xe.XE_FormatWithSelectUI(elAppContainer));
        oEditor.registerPlugin(new xe.XE_SCharacter(elAppContainer));
    }

    if(jQuery("ul.extra2").length) {
        oEditor.registerPlugin(new xe.XE_Extension(elAppContainer, editor_sequence));
    }

    if(jQuery("ul.extra3").length) {
        oEditor.registerPlugin(new xe.XE_EditingModeToggler(elAppContainer));
    }

    //oEditor.registerPlugin(new xe.XE_Preview(elAppContainer));

    if (!jQuery.browser.msie && !jQuery.browser.opera) {
        oEditor.registerPlugin(new xe.XE_WYSIWYGEnterKey(oWYSIWYGIFrame));
    }

    // 자동 저장 사용
    if (s=form._saved_doc_title) {
        oEditor.registerPlugin(new xe.XE_AutoSave(oIRTextarea, elAppContainer));
    }

    function load_proc() {
        try {
            var doc = oWYSIWYGIFrame.contentWindow.document, str;
            if (doc.location == 'about:blank') throw 'blank';

            // get innerHTML
            str = doc.body.innerHTML;

            // register plugin
            oEditor.registerPlugin(new xe.XE_EditingArea_WYSIWYG(oWYSIWYGIFrame));
            oEditor.registerPlugin(new xe.XpressRangeManager(oWYSIWYGIFrame));
            oEditor.registerPlugin(new xe.XE_ExecCommand(oWYSIWYGIFrame));

            if(content_font && !doc.body.style.fontFamily) {
                doc.body.style.fontFamily = content_font;
            }
            if(content_font_size && !doc.body.style.fontSize) {
                doc.body.style.fontSize = content_font_size;
            }

            // run
            oEditor.run();
        } catch(e) {
            setTimeout(load_proc, 0);
        }
    }

    load_proc();

    return oEditor;
}

function editorGetContentTextarea_xe(editor_sequence) {
    var oEditor = xe.Editors[editor_sequence] || null;

    if (!oEditor) return '';

    var str = oEditor.getIR();
    if(!jQuery.trim(str.replace(/( |<\/?(p|br|span|div)([^>]+)?>)/ig, ''))) return '';

    return str;
}

function editorGetIframe(srl) {
    return jQuery('iframe#editor_iframe_'+srl).get(0);
}

function editorReplaceHTML(iframe_obj, content) {
    // src, href, url의 XE 상대경로를 http로 시작하는 full path로 변경
    content = content.replace(/(src=|href=|url\()("|\')*([^"\'\)]+)("|\'|\))*(\s|>)*/ig, function(m0,m1,m2,m3,m4,m5) {
        if(m1=="url(") { m2=''; m4=')'; } else { if(typeof(m2)=='undefined') m2 = '"'; if(typeof(m4)=='undefined') m4 = '"'; if(typeof(m5)=='undefined') m5 = ''; }
        var val = jQuery.trim(m3).replace(/^\.\//,'');
        if(/^(http|https|ftp|telnet|mms|\/|\.\.)/i.test(val)) return m0;
        return m1+m2+request_uri+val+m4+m5;
    });

    var srl = parseInt(iframe_obj.id.replace(/^.*_/,''),10);
    editorRelKeys[srl]["pasteHTML"](content);
}

function editorGetAutoSavedDoc(form) {
    var param = new Array();
    param['mid'] = current_mid;
    param['editor_sequence'] = form.getAttribute('editor_sequence')
    setTimeout(function() {
      var response_tags = new Array("error","message","editor_sequence","title","content","document_srl");
      exec_xml('editor',"procEditorLoadSavedDocument", param, function(a,b,c) { editorRelKeys[param['editor_sequence']]['primary'].value = a['document_srl']; if(typeof(uploadSettingObj[param['editor_sequence']]) == 'object') editorUploadInit(uploadSettingObj[param['editor_sequence']], true); }, response_tags);
    }, 0);

}

// WYSIWYG 모드를 저장하는 확장기능
xe.XE_GET_WYSYWYG_MODE = jQuery.Class({
    name : "XE_GET_WYSYWYG_MODE",

    $init : function(editor_sequence) {
        this.editor_sequence = editor_sequence;
    },

    $ON_CHANGE_EDITING_MODE : function(mode) {
        editorMode[this.editor_sequence] = (mode =='HTMLSrc') ? 'html' : 'wysiwyg';
    }
});

// 이미지등의 상대경로를 절대경로로 바꾸는 플러그인
xe.XE_GET_WYSYWYG_CONTENT = jQuery.Class({
    name : "XE_GET_WYSYWYG_CONTENT",

    $ON_MSG_APP_READY : function() {
        this.oApp.addConverter("IR_TO_WYSIWYG", this.TO_WYSIWYG_SET);
        this.oApp.addConverter("IR_TO_HTMLSrc", this.IR_TO_HTMLSrc);
    },

    TO_WYSIWYG_SET : function(content) {
        // src, href, url의 XE 상대경로를 http로 시작하는 full path로 변경
        content = content.replace(/(src=|href=|url\()("|\')*([^"\'\)]+)("|\'|\))*(\s|>)*/ig, function(m0,m1,m2,m3,m4,m5) {
            if(m1=="url(") { m2=''; m4=')'; } else { if(typeof(m2)=='undefined') m2 = '"'; if(typeof(m4)=='undefined') m4 = '"'; if(typeof(m5)=='undefined') m5 = ''; }
            var val = jQuery.trim(m3).replace(/^\.\//,'');
            if(/^(http|https|ftp|telnet|mms|\/|\.\.)/i.test(val)) return m0;
            return m1+m2+request_uri+val+m4+m5;
        });

        return content;
    },

    IR_TO_HTMLSrc : function(content) {
        // src, href, url의 XE 상대경로를 http로 시작하는 full path로 변경
        content = content.replace(/(src=|href=|url\()("|\')*([^"\'\)]+)("|\'|\))*(\s|>|\))*/ig, function(m0,m1,m2,m3,m4,m5) {
            var uriReg = new RegExp('^'+request_uri.replace('\/','\\/'),'ig');
            if(m1=="url(") { m2=''; m4=')'; } else { if(typeof(m2)=='undefined') m2 = '"'; if(typeof(m4)=='undefined') m4 = '"'; if(typeof(m5)=='undefined') m5 = ''; }
            var val = jQuery.trim(m3);
            if(uriReg.test(val)) val = val.replace(uriReg,'');
            else val = m3;
            return m1+m2+val+m4+m5;
        });
        return content;

    }
});

// 서식 기본 내용을 보존
xe.XE_PreservTemplate = jQuery.Class({
    name : "XE_PreservTemplate",
    isRun : false,

    $BEFORE_SET_IR : function(content) {
        if(!this.isRun && !content) {
            this.isRun = true;
            return false;
        }
    }
});

// 미리보기 확장기능
xe.XE_Preview = jQuery.Class({
    name  : "XE_Preview",
    elPreviewButton : null,

    $init : function(elAppContainer) {
        this._assignHTMLObjects(elAppContainer);
    },

    _assignHTMLObjects : function(elAppContainer) {
        this.elPreviewButton = jQuery("BUTTON.xpress_xeditor_preview_button", elAppContainer);
    },

    $ON_MSG_APP_READY : function() {
        this.oApp.registerBrowserEvent(this.elPreviewButton.get(0), "click", "EVENT_PREVIEW", []);
    },

    $ON_EVENT_PREVIEW : function() {
        // TODO : 버튼이 눌렸을 때의 동작 정의
    }
});
<commit_msg>#18399347 : FF에서 빈칸( ) 대신 빈 줄(
)을 기본 컨텐트로 사용<commit_after>if (!window.xe) xe = {};

xe.Editors = [];

function editorStart_xe(editor_sequence, primary_key, content_key, editor_height, colorset, content_style, content_font, content_font_size) {
    if(typeof(colorset)=='undefined') colorset = 'white';
    if(typeof(content_style)=='undefined') content_style = 'xeStyle';
    if(typeof(content_font)=='undefined') content_font= '';
    if(typeof(content_font_size)=='undefined') content_font_size= '';

    var target_src = request_uri+'modules/editor/styles/'+content_style+'/editor.html';

    var textarea = jQuery("#xpress-editor-"+editor_sequence);
    var iframe   = jQuery('');
    var htmlsrc  = jQuery('<textarea rows="10" cols="20" class="input_syntax '+colorset+'" style="display:none"></textarea>');
    var form     = textarea.get(0).form;
    form.setAttribute('editor_sequence', editor_sequence);
    textarea.css("display","none");

    var saved_content = '';
    if(jQuery("input[name=content]",form).size()>0){
        saved_content=jQuery("input[name=content]",form).val().replace(/src=\"files\/attach/g,'src="'+request_uri+'files/attach'); //'
        jQuery("#xpress-editor-"+editor_sequence).val(saved_content);
    }

    /*
    // remove procFilter
    if(form.comment_srl){
        form.onsubmit=function(){
            var content = editorGetContent(editor_sequence);
            editorRelKeys[editor_sequence]['content'].value = content;
            insert_comment(form);
            return false;
        };
    }else{
        form.onsubmit=function(){
            var content = editorGetContent(editor_sequence);
            editorRelKeys[editor_sequence]['content'].value = content;
            insert(form);
            return false;
        };
    }
    */

    // hide textarea
    textarea.hide().css('width', '99%').before(iframe).after(htmlsrc);

    // create an editor
    var oEditor          = new xe.XpressCore();
    var oWYSIWYGIFrame   = iframe.get(0);
    var oIRTextarea      = textarea.get(0);
    var oHTMLSrcTextarea = htmlsrc.get(0);
    var elAppContainer   = jQuery('.xpress-editor', form).get(0);

    oEditor.getFrame = function(){ return oWYSIWYGIFrame;}
	oEditor.getContent = function(){
		editorGetContentTextarea_xe(editor_sequence);
	}

    var content = form[content_key].value;
    if(xFF && !content) content = '
';

    // src, href, url의 XE 상대경로를 http로 시작하는 full path로 변경
    content = content.replace(/(src=|href=|url\()("|\')*([^"\'\)]+)("|\'|\))*(\s|>)*/ig, function(m0,m1,m2,m3,m4,m5) {
        if(m1=="url(") { m2=''; m4=')'; } else { if(typeof(m2)=='undefined') m2 = '"'; if(typeof(m4)=='undefined') m4 = '"'; if(typeof(m5)=='undefined') m5 = ''; }
        var val = jQuery.trim(m3).replace(/^\.\//,'');
        if(/^(http|https|ftp|telnet|mms|\/|\.\.)/i.test(val)) return m0;
        return m1+m2+request_uri+val+m4+m5;
    });

    form[content_key].value = content;
    jQuery("#xpress-editor-"+editor_sequence).val(content);

    // Set standard API
    editorRelKeys[editor_sequence] = new Array();
    editorRelKeys[editor_sequence]["primary"]   = form[primary_key];
    editorRelKeys[editor_sequence]["content"]   = form[content_key];
    editorRelKeys[editor_sequence]["func"]      = editorGetContentTextarea_xe;
    editorRelKeys[editor_sequence]["editor"]    = oEditor;
    editorRelKeys[editor_sequence]["pasteHTML"] = function(text){
        oEditor.exec('PASTE_HTML',[text]);
    }
    xe.Editors[editor_sequence] = oEditor;

    // register plugins
    oEditor.registerPlugin(new xe.CorePlugin(null));

    oEditor.registerPlugin(new xe.XE_PreservTemplate(jQuery("#xpress-editor-"+editor_sequence).val()));
    oEditor.registerPlugin(new xe.StringConverterManager());
    oEditor.registerPlugin(new xe.XE_EditingAreaManager("WYSIWYG", oIRTextarea, {nHeight:parseInt(editor_height), nMinHeight:205}, null, elAppContainer));
    oEditor.registerPlugin(new xe.XE_EditingArea_HTMLSrc(oHTMLSrcTextarea));
    oEditor.registerPlugin(new xe.XE_EditingAreaVerticalResizer(elAppContainer));
    oEditor.registerPlugin(new xe.Utils());
    oEditor.registerPlugin(new xe.DialogLayerManager());
    oEditor.registerPlugin(new xe.ActiveLayerManager());
    oEditor.registerPlugin(new xe.Hotkey());
    oEditor.registerPlugin(new xe.XE_WYSIWYGStyler());
    oEditor.registerPlugin(new xe.XE_WYSIWYGStyleGetter());
    oEditor.registerPlugin(new xe.MessageManager(oMessageMap));
    oEditor.registerPlugin(new xe.XE_Toolbar(elAppContainer));

    oEditor.registerPlugin(new xe.XE_XHTMLFormatter);
    oEditor.registerPlugin(new xe.XE_GET_WYSYWYG_MODE(editor_sequence));
    oEditor.registerPlugin(new xe.XE_GET_WYSYWYG_CONTENT());

    if(jQuery("ul.extra1").length) {
        oEditor.registerPlugin(new xe.XE_ColorPalette(elAppContainer));
        oEditor.registerPlugin(new xe.XE_FontColor(elAppContainer));
        oEditor.registerPlugin(new xe.XE_BGColor(elAppContainer));
        oEditor.registerPlugin(new xe.XE_Quote(elAppContainer));
        oEditor.registerPlugin(new xe.XE_FontNameWithSelectUI(elAppContainer));
        oEditor.registerPlugin(new xe.XE_FontSizeWithSelectUI(elAppContainer));
        oEditor.registerPlugin(new xe.XE_LineHeightWithSelectUI(elAppContainer));
        oEditor.registerPlugin(new xe.XE_UndoRedo());
        oEditor.registerPlugin(new xe.XE_Table(elAppContainer));
        oEditor.registerPlugin(new xe.XE_Hyperlink(elAppContainer));
        oEditor.registerPlugin(new xe.XE_FindReplacePlugin(elAppContainer));
        oEditor.registerPlugin(new xe.XE_FormatWithSelectUI(elAppContainer));
        oEditor.registerPlugin(new xe.XE_SCharacter(elAppContainer));
    }

    if(jQuery("ul.extra2").length) {
        oEditor.registerPlugin(new xe.XE_Extension(elAppContainer, editor_sequence));
    }

    if(jQuery("ul.extra3").length) {
        oEditor.registerPlugin(new xe.XE_EditingModeToggler(elAppContainer));
    }

    //oEditor.registerPlugin(new xe.XE_Preview(elAppContainer));

    if (!jQuery.browser.msie && !jQuery.browser.opera) {
        oEditor.registerPlugin(new xe.XE_WYSIWYGEnterKey(oWYSIWYGIFrame));
    }

    // 자동 저장 사용
    if (s=form._saved_doc_title) {
        oEditor.registerPlugin(new xe.XE_AutoSave(oIRTextarea, elAppContainer));
    }

    function load_proc() {
        try {
            var doc = oWYSIWYGIFrame.contentWindow.document, str;
            if (doc.location == 'about:blank') throw 'blank';

            // get innerHTML
            str = doc.body.innerHTML;

            // register plugin
            oEditor.registerPlugin(new xe.XE_EditingArea_WYSIWYG(oWYSIWYGIFrame));
            oEditor.registerPlugin(new xe.XpressRangeManager(oWYSIWYGIFrame));
            oEditor.registerPlugin(new xe.XE_ExecCommand(oWYSIWYGIFrame));

            if(content_font && !doc.body.style.fontFamily) {
                doc.body.style.fontFamily = content_font;
            }
            if(content_font_size && !doc.body.style.fontSize) {
                doc.body.style.fontSize = content_font_size;
            }

            // run
            oEditor.run();
        } catch(e) {
            setTimeout(load_proc, 0);
        }
    }

    load_proc();

    return oEditor;
}

function editorGetContentTextarea_xe(editor_sequence) {
    var oEditor = xe.Editors[editor_sequence] || null;

    if (!oEditor) return '';

    var str = oEditor.getIR();
    if(!jQuery.trim(str.replace(/( |<\/?(p|br|span|div)([^>]+)?>)/ig, ''))) return '';

    return str;
}

function editorGetIframe(srl) {
    return jQuery('iframe#editor_iframe_'+srl).get(0);
}

function editorReplaceHTML(iframe_obj, content) {
    // src, href, url의 XE 상대경로를 http로 시작하는 full path로 변경
    content = content.replace(/(src=|href=|url\()("|\')*([^"\'\)]+)("|\'|\))*(\s|>)*/ig, function(m0,m1,m2,m3,m4,m5) {
        if(m1=="url(") { m2=''; m4=')'; } else { if(typeof(m2)=='undefined') m2 = '"'; if(typeof(m4)=='undefined') m4 = '"'; if(typeof(m5)=='undefined') m5 = ''; }
        var val = jQuery.trim(m3).replace(/^\.\//,'');
        if(/^(http|https|ftp|telnet|mms|\/|\.\.)/i.test(val)) return m0;
        return m1+m2+request_uri+val+m4+m5;
    });

    var srl = parseInt(iframe_obj.id.replace(/^.*_/,''),10);
    editorRelKeys[srl]["pasteHTML"](content);
}

function editorGetAutoSavedDoc(form) {
    var param = new Array();
    param['mid'] = current_mid;
    param['editor_sequence'] = form.getAttribute('editor_sequence')
    setTimeout(function() {
      var response_tags = new Array("error","message","editor_sequence","title","content","document_srl");
      exec_xml('editor',"procEditorLoadSavedDocument", param, function(a,b,c) { editorRelKeys[param['editor_sequence']]['primary'].value = a['document_srl']; if(typeof(uploadSettingObj[param['editor_sequence']]) == 'object') editorUploadInit(uploadSettingObj[param['editor_sequence']], true); }, response_tags);
    }, 0);

}

// WYSIWYG 모드를 저장하는 확장기능
xe.XE_GET_WYSYWYG_MODE = jQuery.Class({
    name : "XE_GET_WYSYWYG_MODE",

    $init : function(editor_sequence) {
        this.editor_sequence = editor_sequence;
    },

    $ON_CHANGE_EDITING_MODE : function(mode) {
        editorMode[this.editor_sequence] = (mode =='HTMLSrc') ? 'html' : 'wysiwyg';
    }
});

// 이미지등의 상대경로를 절대경로로 바꾸는 플러그인
xe.XE_GET_WYSYWYG_CONTENT = jQuery.Class({
    name : "XE_GET_WYSYWYG_CONTENT",

    $ON_MSG_APP_READY : function() {
        this.oApp.addConverter("IR_TO_WYSIWYG", this.TO_WYSIWYG_SET);
        this.oApp.addConverter("IR_TO_HTMLSrc", this.IR_TO_HTMLSrc);
    },

    TO_WYSIWYG_SET : function(content) {
        // src, href, url의 XE 상대경로를 http로 시작하는 full path로 변경
        content = content.replace(/(src=|href=|url\()("|\')*([^"\'\)]+)("|\'|\))*(\s|>)*/ig, function(m0,m1,m2,m3,m4,m5) {
            if(m1=="url(") { m2=''; m4=')'; } else { if(typeof(m2)=='undefined') m2 = '"'; if(typeof(m4)=='undefined') m4 = '"'; if(typeof(m5)=='undefined') m5 = ''; }
            var val = jQuery.trim(m3).replace(/^\.\//,'');
            if(/^(http|https|ftp|telnet|mms|\/|\.\.)/i.test(val)) return m0;
            return m1+m2+request_uri+val+m4+m5;
        });

        return content;
    },

    IR_TO_HTMLSrc : function(content) {
        // src, href, url의 XE 상대경로를 http로 시작하는 full path로 변경
        content = content.replace(/(src=|href=|url\()("|\')*([^"\'\)]+)("|\'|\))*(\s|>|\))*/ig, function(m0,m1,m2,m3,m4,m5) {
            var uriReg = new RegExp('^'+request_uri.replace('\/','\\/'),'ig');
            if(m1=="url(") { m2=''; m4=')'; } else { if(typeof(m2)=='undefined') m2 = '"'; if(typeof(m4)=='undefined') m4 = '"'; if(typeof(m5)=='undefined') m5 = ''; }
            var val = jQuery.trim(m3);
            if(uriReg.test(val)) val = val.replace(uriReg,'');
            else val = m3;
            return m1+m2+val+m4+m5;
        });
        return content;

    }
});

// 서식 기본 내용을 보존
xe.XE_PreservTemplate = jQuery.Class({
    name : "XE_PreservTemplate",
    isRun : false,

    $BEFORE_SET_IR : function(content) {
        if(!this.isRun && !content) {
            this.isRun = true;
            return false;
        }
    }
});

// 미리보기 확장기능
xe.XE_Preview = jQuery.Class({
    name  : "XE_Preview",
    elPreviewButton : null,

    $init : function(elAppContainer) {
        this._assignHTMLObjects(elAppContainer);
    },

    _assignHTMLObjects : function(elAppContainer) {
        this.elPreviewButton = jQuery("BUTTON.xpress_xeditor_preview_button", elAppContainer);
    },

    $ON_MSG_APP_READY : function() {
        this.oApp.registerBrowserEvent(this.elPreviewButton.get(0), "click", "EVENT_PREVIEW", []);
    },

    $ON_EVENT_PREVIEW : function() {
        // TODO : 버튼이 눌렸을 때의 동작 정의
    }
});
<|endoftext|>


<commit_before>// @flow
/* eslint-disable max-len */
/**
 * Trying to avoid the unknown-prop errors on styled components by filtering by
 * React's attribute whitelist.
 *
 * To regenerate this regex:
 *
 * 1. `npm i -g regexgen` (https://github.com/devongovett/regexgen)
 * 2. Run `regexgen` with the list of space-separated words below as input
 * 3. Surround the emitted regex with this: `/^(GENERATED_REGEX)$/` -- this will ensure a full string match
 *    and no false positives from partials
 * */
/*
children dangerouslySetInnerHTML key ref autoFocus defaultValue valueLink defaultChecked checkedLink innerHTML suppressContentEditableWarning onFocusIn onFocusOut className onCopy onCut onPaste onCompositionEnd onCompositionStart onCompositionUpdate onKeyDown onKeyPress onKeyUp onFocus onBlur onChange onInput onInvalid onSubmit onReset onClick onContextMenu onDoubleClick onDrag onDragEnd onDragEnter onDragExit onDragLeave onDragOver onDragStart onDrop onMouseDown onMouseEnter onMouseLeave onMouseMove onMouseOut onMouseOver onMouseUp onSelect onTouchCancel onTouchEnd onTouchMove onTouchStart onScroll onWheel onAbort onCanPlay onCanPlayThrough onDurationChange onEmptied onEncrypted onEnded onError onLoadedData onLoadedMetadata onLoadStart onPause onPlay onPlaying onProgress onRateChange onSeeked onSeeking onStalled onSuspend onTimeUpdate onVolumeChange onWaiting onLoad onAnimationStart onAnimationEnd onAnimationIteration onTransitionEnd onCopyCapture onCutCapture onPasteCapture onCompositionEndCapture onCompositionStartCapture onCompositionUpdateCapture onKeyDownCapture onKeyPressCapture onKeyUpCapture onFocusCapture onBlurCapture onChangeCapture onInputCapture onSubmitCapture onResetCapture onClickCapture onContextMenuCapture onDoubleClickCapture onDragCapture onDragEndCapture onDragEnterCapture onDragExitCapture onDragLeaveCapture onDragOverCapture onDragStartCapture onDropCapture onMouseDownCapture onMouseEnterCapture onMouseLeaveCapture onMouseMoveCapture onMouseOutCapture onMouseOverCapture onMouseUpCapture onSelectCapture onTouchCancelCapture onTouchEndCapture onTouchMoveCapture onTouchStartCapture onScrollCapture onWheelCapture onAbortCapture onCanPlayCapture onCanPlayThroughCapture onDurationChangeCapture onEmptiedCapture onEncryptedCapture onEndedCapture onErrorCapture onLoadedDataCapture onLoadedMetadataCapture onLoadStartCapture onPauseCapture onPlayCapture onPlayingCapture onProgressCapture onRateChangeCapture onSeekedCapture onSeekingCapture onStalledCapture onSuspendCapture onTimeUpdateCapture onVolumeChangeCapture onWaitingCapture onLoadCapture onAnimationStartCapture onAnimationEndCapture onAnimationIterationCapture onTransitionEndCapture accept acceptCharset accessKey action allowFullScreen allowTransparency alt as async autoComplete autoPlay capture cellPadding cellSpacing charSet challenge checked cite classID className cols colSpan content contentEditable contextMenu controlsList controls coords crossOrigin data dateTime default defer dir disabled download draggable encType form formAction formEncType formMethod formNoValidate formTarget frameBorder headers height hidden high href hrefLang htmlFor httpEquiv icon id inputMode integrity is keyParams keyType kind label lang list loop low manifest marginHeight marginWidth max maxLength media mediaGroup method min minLength multiple muted name nonce noValidate open optimum pattern placeholder playsInline poster preload profile radioGroup readOnly referrerPolicy rel required reversed role rows rowSpan sandbox scope scoped scrolling seamless selected shape size sizes span spellCheck src srcDoc srcLang srcSet start step style summary tabIndex target title type useMap value width wmode wrap about datatype inlist prefix property resource typeof vocab autoCapitalize autoCorrect autoSave color itemProp itemScope itemType itemID itemRef results security unselectable accentHeight accumulate additive alignmentBaseline allowReorder alphabetic amplitude arabicForm ascent attributeName attributeType autoReverse azimuth baseFrequency baseProfile baselineShift bbox begin bias by calcMode capHeight clip clipPath clipRule clipPathUnits colorInterpolation colorInterpolationFilters colorProfile colorRendering contentScriptType contentStyleType cursor cx cy d decelerate descent diffuseConstant direction display divisor dominantBaseline dur dx dy edgeMode elevation enableBackground end exponent externalResourcesRequired fill fillOpacity fillRule filter filterRes filterUnits floodColor floodOpacity focusable fontFamily fontSize fontSizeAdjust fontStretch fontStyle fontVariant fontWeight format from fx fy g1 g2 glyphName glyphOrientationHorizontal glyphOrientationVertical glyphRef gradientTransform gradientUnits hanging horizAdvX horizOriginX ideographic imageRendering in in2 intercept k k1 k2 k3 k4 kernelMatrix kernelUnitLength kerning keyPoints keySplines keyTimes lengthAdjust letterSpacing lightingColor limitingConeAngle local markerEnd markerMid markerStart markerHeight markerUnits markerWidth mask maskContentUnits maskUnits mathematical mode numOctaves offset opacity operator order orient orientation origin overflow overlinePosition overlineThickness paintOrder panose1 pathLength patternContentUnits patternTransform patternUnits pointerEvents points pointsAtX pointsAtY pointsAtZ preserveAlpha preserveAspectRatio primitiveUnits r radius refX refY renderingIntent repeatCount repeatDur requiredExtensions requiredFeatures restart result rotate rx ry scale seed shapeRendering slope spacing specularConstant specularExponent speed spreadMethod startOffset stdDeviation stemh stemv stitchTiles stopColor stopOpacity strikethroughPosition strikethroughThickness string stroke strokeDasharray strokeDashoffset strokeLinecap strokeLinejoin strokeMiterlimit strokeOpacity strokeWidth surfaceScale systemLanguage tableValues targetX targetY textAnchor textDecoration textRendering textLength to transform u1 u2 underlinePosition underlineThickness unicode unicodeBidi unicodeRange unitsPerEm vAlphabetic vHanging vIdeographic vMathematical values vectorEffect version vertAdvY vertOriginX vertOriginY viewBox viewTarget visibility widths wordSpacing writingMode x xHeight x1 x2 xChannelSelector xlinkActuate xlinkArcrole xlinkHref xlinkRole xlinkShow xlinkTitle xlinkType xmlBase xmlns xmlnsXlink xmlLang xmlSpace y y1 y2 yChannelSelector z zoomAndPan onPointerDown onPointerMove onPointerUp onPointerCancel onGotPointerCapture onLostPointerCapture onPointerEnter onPointerLeave onPointerOver onPointerOut class for autofocus
*/
/* eslint-enable max-len */

const ATTRIBUTE_REGEX = /^((?:s(?:uppressContentEditableWarn|croll|pac)|(?:shape|image|text)Render|(?:letter|word)Spac|vHang|hang)ing|(?:on(?:AnimationIteration|C(?:o(?:mposition(?:Update|Start|End)|ntextMenu|py)|anPlayThrough|anPlay|hange|lick|ut)|(?:Animation|Touch|Load|Drag)Start|(?:(?:Duration|Volume|Rate)Chang|(?:MouseLea|(?:Touch|Mouse)Mo|DragLea)v|Paus)e|Loaded(?:Metad|D)ata|(?:(?:T(?:ransition|ouch)|Animation)E|Suspe)nd|DoubleClick|(?:TouchCanc|Whe)el|Lo(?:stPointer|ad)|TimeUpdate|(?:Mouse(?:Ent|Ov)e|Drag(?:Ent|Ov)e|Erro)r|GotPointer|MouseDown|(?:E(?:n(?:crypt|d)|mpti)|S(?:tall|eek))ed|KeyPress|(?:MouseOu|DragExi|S(?:elec|ubmi)|Rese|Inpu)t|P(?:rogress|laying)|DragEnd|Key(?:Down|Up)|(?:MouseU|Dro)p|(?:Wait|Seek)ing|Scroll|Focus|Paste|Abort|Drag|Play|Blur)Captur|alignmentBaselin|(?:limitingConeAng|xlink(?:(?:Arcr|R)o|Tit)|s(?:urfaceSca|ty|ca)|unselectab|baseProfi|fontSty|(?:focus|dragg)ab|multip|profi|tit)l|d(?:ominantBaselin|efaultValu)|onPointerLeav|a(?:uto(?:Capitaliz|Revers|Sav)|dditiv)|(?:(?:formNoValid|xlinkActu|noValid|accumul|rot)a|autoComple|decelera)t|(?:(?:attribute|item)T|datat)yp|onPointerMov|(?:attribute|glyph)Nam|playsInlin|(?:writing|input|edge)Mod|(?:formE|e)ncTyp|(?:amplitu|mo)d|(?:xlinkTy|itemSco|keyTy|slo)p|(?:xmlSpa|non)c|fillRul|(?:dateTi|na)m|r(?:esourc|ol)|xmlBas|wmod)e|(?:glyphOrientationHorizont|loc)al|(?:externalResourcesRequir|select|revers|mut)ed|c(?:o(?:lorInterpolationFilter|ord)s|o(?:lor(?:Interpolation)?|nt(?:rols|ent))|(?:ontentS(?:cript|tyle)Typ|o(?:ntentEditab|lorProfi)l|l(?:assNam|ipRul)|a(?:lcMod|ptur)|it)e|olorRendering|l(?:ipPathUnits|assID)|(?:ontrolsLis|apHeigh)t|h(?:eckedLink|a(?:llenge|rSet)|ildren|ecked)|ell(?:Spac|Padd)ing|o(?:ntextMenu|ls)|(?:rossOrigi|olSpa)n|l(?:ip(?:Path)?|ass)|ursor|[xy])|glyphOrientationVertical|d(?:angerouslySetInnerHTML|efaultChecked|ownload|isabled|isplay|[xy])|(?:s(?:trikethroughThickn|eaml)es|(?:und|ov)erlineThicknes|r(?:equiredExtension|adiu)|(?:requiredFeatur|tableValu|stitchTil|numOctav|filterR)e|key(?:(?:Splin|Tim)e|Param)|auto[Ff]ocu|header|bia)s|(?:(?:st(?:rikethroughPosi|dDevia)|(?:und|ov)erlinePosi|(?:textDecor|elev)a|orienta)tio|(?:strokeLinejo|orig)i|on(?:PointerDow|FocusI)|formActio|zoomAndPa|directio|(?:vers|act)io|rowSpa|begi|ico)n|o(?:n(?:AnimationIteration|C(?:o(?:mposition(?:Update|Start|End)|ntextMenu|py)|anPlayThrough|anPlay|hange|lick|ut)|(?:(?:Duration|Volume|Rate)Chang|(?:MouseLea|(?:Touch|Mouse)Mo|DragLea)v|Paus)e|Loaded(?:Metad|D)ata|(?:Animation|Touch|Load|Drag)Start|(?:(?:T(?:ransition|ouch)|Animation)E|Suspe)nd|DoubleClick|(?:TouchCanc|Whe)el|(?:Mouse(?:Ent|Ov)e|Drag(?:Ent|Ov)e|Erro)r|TimeUpdate|(?:E(?:n(?:crypt|d)|mpti)|S(?:tall|eek))ed|MouseDown|P(?:rogress|laying)|(?:MouseOu|DragExi|S(?:elec|ubmi)|Rese|Inpu)t|KeyPress|DragEnd|Key(?:Down|Up)|(?:Wait|Seek)ing|(?:MouseU|Dro)p|Scroll|Paste|Focus|Abort|Drag|Play|Load|Blur)|rient)|p(?:reserveA(?:spectRatio|lpha)|ointsAt[X-Z]|anose1)|(?:patternContent|ma(?:sk(?:Content)?|rker)|primitive|gradient|pattern|filter)Units|(?:(?:allowTranspar|baseFrequ)enc|re(?:ferrerPolic|adOnl)|(?:(?:st(?:roke|op)O|floodO|fillO|o)pac|integr|secur)it|visibilit|fontFamil|accessKe|propert|summar)y|(?:gradientT|patternT|t)ransform|(?:[xy]ChannelSelect|lightingCol|textAnch|floodCol|stopCol|operat|htmlF)or|(?:strokeMiterlimi|(?:specularConsta|repeatCou|fontVaria)n|(?:(?:specularE|e)xpon|renderingInt|asc)en|d(?:iffuseConsta|esce)n|(?:fontSizeAdju|lengthAdju|manife)s|baselineShif|onPointerOu|vectorEffec|(?:(?:mar(?:ker|gin)|x)H|accentH|fontW)eigh|markerStar|a(?:utoCorrec|bou)|onFocusOu|intercep|restar|forma|inlis|heigh|lis)t|(?:(?:st(?:rokeDasho|artO)|o)ffs|acceptChars|formTarg|viewTarg|srcS)et|k(?:ernel(?:UnitLength|Matrix)|[1-4])|(?:(?:enableBackgrou|markerE)n|s(?:p(?:readMetho|ee)|ee)|formMetho|(?:markerM|onInval)i|preloa|metho|kin)d|strokeDasharray|(?:onPointerCanc|lab)el|(?:allowFullScre|hidd)en|systemLanguage|(?:(?:o(?:nPointer(?:Ent|Ov)|rd)|allowReord|placehold|frameBord|paintOrd|post)e|repeatDu|d(?:efe|u))r|v(?:Mathematical|ert(?:Origin[XY]|AdvY)|alues|ocab)|(?:pointerEve|keyPoi)nts|(?:strokeLineca|onPointerU|itemPro|useMa|wra|loo)p|h(?:oriz(?:Origin|Adv)X|ttpEquiv)|(?:vI|i)deographic|unicodeRange|mathematical|vAlphabetic|u(?:nicodeBidi|[12])|(?:fontStretc|hig)h|(?:(?:mar(?:ker|gin)W|strokeW)id|azimu)th|(?:xmlnsXl|valueL)ink|mediaGroup|spellCheck|(?:text|m(?:in|ax))Length|(?:unitsPerE|optimu|fro)m|r(?:adioGroup|e(?:sults|f[XY]|l)|ows|[xy])|a(?:rabicForm|l(?:phabetic|t)|sync)|pathLength|innerHTML|xlinkShow|(?:xlinkHr|glyphR)ef|(?:tabInde|(?:sand|b)bo|viewBo)x|(?:(?:href|xml|src)La|kerni)ng|autoPlay|o(?:verflow|pen)|f(?:o(?:ntSize|rm?)|il(?:ter|l))|r(?:e(?:quired|sult|f))?|divisor|p(?:attern|oints)|unicode|d(?:efault|ata|ir)?|i(?:temRef|n2|s)|t(?:arget[XY]|o)|srcDoc|s(?:coped|te(?:m[hv]|p)|pan)|(?:width|size)s|prefix|typeof|itemID|s(?:t(?:roke|art)|hape|cope|rc)|t(?:arget|ype)|(?:stri|la)ng|a(?:ccept|s)|m(?:edia|a(?:sk|x)|in)|x(?:mlns)?|width|value|size|href|k(?:ey)?|end|low|by|i[dn]|y[12]|g[12]|x[12]|f[xy]|[yz])$/

/* From DOMProperty */
const ATTRIBUTE_NAME_START_CHAR =
  ':A-Z_a-z\\u00C0-\\u00D6\\u00D8-\\u00F6\\u00F8-\\u02FF\\u0370-\\u037D\\u037F-\\u1FFF\\u200C-\\u200D\\u2070-\\u218F\\u2C00-\\u2FEF\\u3001-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFFD'
const ATTRIBUTE_NAME_CHAR = `${ATTRIBUTE_NAME_START_CHAR}\\-.0-9\\u00B7\\u0300-\\u036F\\u203F-\\u2040`
const isCustomAttribute = RegExp.prototype.test.bind(
  new RegExp(`^(x|data|aria)-[${ATTRIBUTE_NAME_CHAR}]*$`)
)

export default (name: string) =>
  ATTRIBUTE_REGEX.test(name) || isCustomAttribute(name.toLowerCase())
<commit_msg>add 'allow' as a valid attribute (#2083)<commit_after>// @flow
/* eslint-disable max-len */
/**
 * Trying to avoid the unknown-prop errors on styled components by filtering by
 * React's attribute whitelist.
 *
 * To regenerate this regex:
 *
 * 1. `npm i -g regexgen` (https://github.com/devongovett/regexgen)
 * 2. Run `regexgen` with the list of space-separated words below as input
 * 3. Surround the emitted regex with this: `/^(GENERATED_REGEX)$/` -- this will ensure a full string match
 *    and no false positives from partials
 * */
/*
children dangerouslySetInnerHTML key ref autoFocus defaultValue valueLink defaultChecked checkedLink innerHTML suppressContentEditableWarning onFocusIn onFocusOut className onCopy onCut onPaste onCompositionEnd onCompositionStart onCompositionUpdate onKeyDown onKeyPress onKeyUp onFocus onBlur onChange onInput onInvalid onSubmit onReset onClick onContextMenu onDoubleClick onDrag onDragEnd onDragEnter onDragExit onDragLeave onDragOver onDragStart onDrop onMouseDown onMouseEnter onMouseLeave onMouseMove onMouseOut onMouseOver onMouseUp onSelect onTouchCancel onTouchEnd onTouchMove onTouchStart onScroll onWheel onAbort onCanPlay onCanPlayThrough onDurationChange onEmptied onEncrypted onEnded onError onLoadedData onLoadedMetadata onLoadStart onPause onPlay onPlaying onProgress onRateChange onSeeked onSeeking onStalled onSuspend onTimeUpdate onVolumeChange onWaiting onLoad onAnimationStart onAnimationEnd onAnimationIteration onTransitionEnd onCopyCapture onCutCapture onPasteCapture onCompositionEndCapture onCompositionStartCapture onCompositionUpdateCapture onKeyDownCapture onKeyPressCapture onKeyUpCapture onFocusCapture onBlurCapture onChangeCapture onInputCapture onSubmitCapture onResetCapture onClickCapture onContextMenuCapture onDoubleClickCapture onDragCapture onDragEndCapture onDragEnterCapture onDragExitCapture onDragLeaveCapture onDragOverCapture onDragStartCapture onDropCapture onMouseDownCapture onMouseEnterCapture onMouseLeaveCapture onMouseMoveCapture onMouseOutCapture onMouseOverCapture onMouseUpCapture onSelectCapture onTouchCancelCapture onTouchEndCapture onTouchMoveCapture onTouchStartCapture onScrollCapture onWheelCapture onAbortCapture onCanPlayCapture onCanPlayThroughCapture onDurationChangeCapture onEmptiedCapture onEncryptedCapture onEndedCapture onErrorCapture onLoadedDataCapture onLoadedMetadataCapture onLoadStartCapture onPauseCapture onPlayCapture onPlayingCapture onProgressCapture onRateChangeCapture onSeekedCapture onSeekingCapture onStalledCapture onSuspendCapture onTimeUpdateCapture onVolumeChangeCapture onWaitingCapture onLoadCapture onAnimationStartCapture onAnimationEndCapture onAnimationIterationCapture onTransitionEndCapture accept acceptCharset accessKey action allowFullScreen allowTransparency alt as async autoComplete autoPlay capture cellPadding cellSpacing charSet challenge checked cite classID className cols colSpan content contentEditable contextMenu controlsList controls coords crossOrigin data dateTime default defer dir disabled download draggable encType form formAction formEncType formMethod formNoValidate formTarget frameBorder headers height hidden high href hrefLang htmlFor httpEquiv icon id inputMode integrity is keyParams keyType kind label lang list loop low manifest marginHeight marginWidth max maxLength media mediaGroup method min minLength multiple muted name nonce noValidate open optimum pattern placeholder playsInline poster preload profile radioGroup readOnly referrerPolicy rel required reversed role rows rowSpan sandbox scope scoped scrolling seamless selected shape size sizes span spellCheck src srcDoc srcLang srcSet start step style summary tabIndex target title type useMap value width wmode wrap about datatype inlist prefix property resource typeof vocab autoCapitalize autoCorrect autoSave color itemProp itemScope itemType itemID itemRef results security unselectable accentHeight accumulate additive alignmentBaseline allowReorder alphabetic amplitude arabicForm ascent attributeName attributeType autoReverse azimuth baseFrequency baseProfile baselineShift bbox begin bias by calcMode capHeight clip clipPath clipRule clipPathUnits colorInterpolation colorInterpolationFilters colorProfile colorRendering contentScriptType contentStyleType cursor cx cy d decelerate descent diffuseConstant direction display divisor dominantBaseline dur dx dy edgeMode elevation enableBackground end exponent externalResourcesRequired fill fillOpacity fillRule filter filterRes filterUnits floodColor floodOpacity focusable fontFamily fontSize fontSizeAdjust fontStretch fontStyle fontVariant fontWeight format from fx fy g1 g2 glyphName glyphOrientationHorizontal glyphOrientationVertical glyphRef gradientTransform gradientUnits hanging horizAdvX horizOriginX ideographic imageRendering in in2 intercept k k1 k2 k3 k4 kernelMatrix kernelUnitLength kerning keyPoints keySplines keyTimes lengthAdjust letterSpacing lightingColor limitingConeAngle local markerEnd markerMid markerStart markerHeight markerUnits markerWidth mask maskContentUnits maskUnits mathematical mode numOctaves offset opacity operator order orient orientation origin overflow overlinePosition overlineThickness paintOrder panose1 pathLength patternContentUnits patternTransform patternUnits pointerEvents points pointsAtX pointsAtY pointsAtZ preserveAlpha preserveAspectRatio primitiveUnits r radius refX refY renderingIntent repeatCount repeatDur requiredExtensions requiredFeatures restart result rotate rx ry scale seed shapeRendering slope spacing specularConstant specularExponent speed spreadMethod startOffset stdDeviation stemh stemv stitchTiles stopColor stopOpacity strikethroughPosition strikethroughThickness string stroke strokeDasharray strokeDashoffset strokeLinecap strokeLinejoin strokeMiterlimit strokeOpacity strokeWidth surfaceScale systemLanguage tableValues targetX targetY textAnchor textDecoration textRendering textLength to transform u1 u2 underlinePosition underlineThickness unicode unicodeBidi unicodeRange unitsPerEm vAlphabetic vHanging vIdeographic vMathematical values vectorEffect version vertAdvY vertOriginX vertOriginY viewBox viewTarget visibility widths wordSpacing writingMode x xHeight x1 x2 xChannelSelector xlinkActuate xlinkArcrole xlinkHref xlinkRole xlinkShow xlinkTitle xlinkType xmlBase xmlns xmlnsXlink xmlLang xmlSpace y y1 y2 yChannelSelector z zoomAndPan onPointerDown onPointerMove onPointerUp onPointerCancel onGotPointerCapture onLostPointerCapture onPointerEnter onPointerLeave onPointerOver onPointerOut class for autofocus
*/
/* eslint-enable max-len */

const ATTRIBUTE_REGEX = /^((?:s(?:uppressContentEditableWarn|croll|pac)|(?:shape|image|text)Render|(?:letter|word)Spac|vHang|hang)ing|(?:on(?:AnimationIteration|C(?:o(?:mposition(?:Update|Start|End)|ntextMenu|py)|anPlayThrough|anPlay|hange|lick|ut)|(?:Animation|Touch|Load|Drag)Start|(?:(?:Duration|Volume|Rate)Chang|(?:MouseLea|(?:Touch|Mouse)Mo|DragLea)v|Paus)e|Loaded(?:Metad|D)ata|(?:(?:T(?:ransition|ouch)|Animation)E|Suspe)nd|DoubleClick|(?:TouchCanc|Whe)el|Lo(?:stPointer|ad)|TimeUpdate|(?:Mouse(?:Ent|Ov)e|Drag(?:Ent|Ov)e|Erro)r|GotPointer|MouseDown|(?:E(?:n(?:crypt|d)|mpti)|S(?:tall|eek))ed|KeyPress|(?:MouseOu|DragExi|S(?:elec|ubmi)|Rese|Inpu)t|P(?:rogress|laying)|DragEnd|Key(?:Down|Up)|(?:MouseU|Dro)p|(?:Wait|Seek)ing|Scroll|Focus|Paste|Abort|Drag|Play|Blur)Captur|alignmentBaselin|(?:limitingConeAng|xlink(?:(?:Arcr|R)o|Tit)|s(?:urfaceSca|ty|ca)|unselectab|baseProfi|fontSty|(?:focus|dragg)ab|multip|profi|tit)l|d(?:ominantBaselin|efaultValu)|onPointerLeav|a(?:uto(?:Capitaliz|Revers|Sav)|dditiv)|(?:(?:formNoValid|xlinkActu|noValid|accumul|rot)a|autoComple|decelera)t|(?:(?:attribute|item)T|datat)yp|onPointerMov|(?:attribute|glyph)Nam|playsInlin|(?:writing|input|edge)Mod|(?:formE|e)ncTyp|(?:amplitu|mo)d|(?:xlinkTy|itemSco|keyTy|slo)p|(?:xmlSpa|non)c|fillRul|(?:dateTi|na)m|r(?:esourc|ol)|xmlBas|wmod)e|(?:glyphOrientationHorizont|loc)al|(?:externalResourcesRequir|select|revers|mut)ed|c(?:o(?:lorInterpolationFilter|ord)s|o(?:lor(?:Interpolation)?|nt(?:rols|ent))|(?:ontentS(?:cript|tyle)Typ|o(?:ntentEditab|lorProfi)l|l(?:assNam|ipRul)|a(?:lcMod|ptur)|it)e|olorRendering|l(?:ipPathUnits|assID)|(?:ontrolsLis|apHeigh)t|h(?:eckedLink|a(?:llenge|rSet)|ildren|ecked)|ell(?:Spac|Padd)ing|o(?:ntextMenu|ls)|(?:rossOrigi|olSpa)n|l(?:ip(?:Path)?|ass)|ursor|[xy])|glyphOrientationVertical|d(?:angerouslySetInnerHTML|efaultChecked|ownload|isabled|isplay|[xy])|(?:s(?:trikethroughThickn|eaml)es|(?:und|ov)erlineThicknes|r(?:equiredExtension|adiu)|(?:requiredFeatur|tableValu|stitchTil|numOctav|filterR)e|key(?:(?:Splin|Tim)e|Param)|auto[Ff]ocu|header|bia)s|(?:(?:st(?:rikethroughPosi|dDevia)|(?:und|ov)erlinePosi|(?:textDecor|elev)a|orienta)tio|(?:strokeLinejo|orig)i|on(?:PointerDow|FocusI)|formActio|zoomAndPa|directio|(?:vers|act)io|rowSpa|begi|ico)n|o(?:n(?:AnimationIteration|C(?:o(?:mposition(?:Update|Start|End)|ntextMenu|py)|anPlayThrough|anPlay|hange|lick|ut)|(?:(?:Duration|Volume|Rate)Chang|(?:MouseLea|(?:Touch|Mouse)Mo|DragLea)v|Paus)e|Loaded(?:Metad|D)ata|(?:Animation|Touch|Load|Drag)Start|(?:(?:T(?:ransition|ouch)|Animation)E|Suspe)nd|DoubleClick|(?:TouchCanc|Whe)el|(?:Mouse(?:Ent|Ov)e|Drag(?:Ent|Ov)e|Erro)r|TimeUpdate|(?:E(?:n(?:crypt|d)|mpti)|S(?:tall|eek))ed|MouseDown|P(?:rogress|laying)|(?:MouseOu|DragExi|S(?:elec|ubmi)|Rese|Inpu)t|KeyPress|DragEnd|Key(?:Down|Up)|(?:Wait|Seek)ing|(?:MouseU|Dro)p|Scroll|Paste|Focus|Abort|Drag|Play|Load|Blur)|rient)|p(?:reserveA(?:spectRatio|lpha)|ointsAt[X-Z]|anose1)|(?:patternContent|ma(?:sk(?:Content)?|rker)|primitive|gradient|pattern|filter)Units|(?:(?:allowTranspar|baseFrequ)enc|re(?:ferrerPolic|adOnl)|(?:(?:st(?:roke|op)O|floodO|fillO|o)pac|integr|secur)it|visibilit|fontFamil|accessKe|propert|summar)y|(?:gradientT|patternT|t)ransform|(?:[xy]ChannelSelect|lightingCol|textAnch|floodCol|stopCol|operat|htmlF)or|(?:strokeMiterlimi|(?:specularConsta|repeatCou|fontVaria)n|(?:(?:specularE|e)xpon|renderingInt|asc)en|d(?:iffuseConsta|esce)n|(?:fontSizeAdju|lengthAdju|manife)s|baselineShif|onPointerOu|vectorEffec|(?:(?:mar(?:ker|gin)|x)H|accentH|fontW)eigh|markerStar|a(?:utoCorrec|bou)|onFocusOu|intercep|restar|forma|inlis|heigh|lis)t|(?:(?:st(?:rokeDasho|artO)|o)ffs|acceptChars|formTarg|viewTarg|srcS)et|k(?:ernel(?:UnitLength|Matrix)|[1-4])|(?:(?:enableBackgrou|markerE)n|s(?:p(?:readMetho|ee)|ee)|formMetho|(?:markerM|onInval)i|preloa|metho|kin)d|strokeDasharray|(?:onPointerCanc|lab)el|(?:allowFullScre|hidd)en|systemLanguage|(?:(?:o(?:nPointer(?:Ent|Ov)|rd)|allowReord|placehold|frameBord|paintOrd|post)e|repeatDu|d(?:efe|u))r|v(?:Mathematical|ert(?:Origin[XY]|AdvY)|alues|ocab)|(?:pointerEve|keyPoi)nts|(?:strokeLineca|onPointerU|itemPro|useMa|wra|loo)p|h(?:oriz(?:Origin|Adv)X|ttpEquiv)|(?:vI|i)deographic|unicodeRange|mathematical|vAlphabetic|u(?:nicodeBidi|[12])|(?:fontStretc|hig)h|(?:(?:mar(?:ker|gin)W|strokeW)id|azimu)th|(?:xmlnsXl|valueL)ink|mediaGroup|spellCheck|(?:text|m(?:in|ax))Length|(?:unitsPerE|optimu|fro)m|r(?:adioGroup|e(?:sults|f[XY]|l)|ows|[xy])|a(?:rabicForm|l(?:phabetic|t)|sync)|pathLength|innerHTML|xlinkShow|(?:xlinkHr|glyphR)ef|(?:tabInde|(?:sand|b)bo|viewBo)x|(?:(?:href|xml|src)La|kerni)ng|autoPlay|o(?:verflow|pen)|f(?:o(?:ntSize|rm?)|il(?:ter|l))|r(?:e(?:quired|sult|f))?|divisor|p(?:attern|oints)|unicode|d(?:efault|ata|ir)?|i(?:temRef|n2|s)|t(?:arget[XY]|o)|srcDoc|s(?:coped|te(?:m[hv]|p)|pan)|(?:width|size)s|prefix|typeof|itemID|s(?:t(?:roke|art)|hape|cope|rc)|t(?:arget|ype)|(?:stri|la)ng|a(?:ccept|llow|s)|m(?:edia|a(?:sk|x)|in)|x(?:mlns)?|width|value|size|href|k(?:ey)?|end|low|by|i[dn]|y[12]|g[12]|x[12]|f[xy]|[yz])$/
/* From DOMProperty */
const ATTRIBUTE_NAME_START_CHAR =
  ':A-Z_a-z\\u00C0-\\u00D6\\u00D8-\\u00F6\\u00F8-\\u02FF\\u0370-\\u037D\\u037F-\\u1FFF\\u200C-\\u200D\\u2070-\\u218F\\u2C00-\\u2FEF\\u3001-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFFD'
const ATTRIBUTE_NAME_CHAR = `${ATTRIBUTE_NAME_START_CHAR}\\-.0-9\\u00B7\\u0300-\\u036F\\u203F-\\u2040`
const isCustomAttribute = RegExp.prototype.test.bind(
  new RegExp(`^(x|data|aria)-[${ATTRIBUTE_NAME_CHAR}]*$`)
)

export default (name: string) =>
  ATTRIBUTE_REGEX.test(name) || isCustomAttribute(name.toLowerCase())
<|endoftext|>


<commit_before>/**
 * @name ExtOverviewMapControl for V3
 * @version 0.1
 * @author: Randy Becker
 * @fileoverview This library adds an overview map to a Google map.
 */
/*!
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *       http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

//TODO: Add corner arrow toggler
//TODO: Make transparant rectangle draggable
//TODO: Programatically construct and style overview div
//TODO: Encapsulate into an object, rather than window.onload
//TODO: Add docstrings
//TODO: Fix bugs near equator, prime meridian, poles
//TODO: Clean up everything

/*global google*/
window.onload = function () {
  // Initialize two maps: one full size and one in a small div in the corner
  // of the large map.
  var map = new google.maps.Map(document.getElementById('map_canvas'), {
    "noClear": true
  });
  var overlayMap = new google.maps.Map(
    document.getElementById('overlayMap'),
    {
      mapTypeId: google.maps.MapTypeId.ROADMAP, // Always show roadmap
      disableDefaultUI: true, // Turn off the controls
      scrollwheel: false, // Disable scrollwheel zooming
      disableDoubleClickZoom: true
    }
  );

  var translucentBox = new google.maps.Polygon({
    strokeColor: "#4444BB",
    strokeOpacity: 0.8,
    strokeWeight: 2,
    fillColor: "#4444BB",
    fillOpacity: 0.25
  });
  translucentBox.setMap(overlayMap);

  var transparentBox = new google.maps.Polygon({
    strokeColor: "#4444BB",
    strokeOpacity: 0.8,
    strokeWeight: 2,
    fillColor: "#4444BB",
    fillOpacity: 0.01
  });
  transparentBox.setMap(overlayMap);

  function pathFromBounds(bounds) {
    var northEastCorner = bounds.getNorthEast();
    var southWestCorner = bounds.getSouthWest();
    var northEastLat = northEastCorner.lat();
    var northEastLng = northEastCorner.lng();
    var southWestLat = southWestCorner.lat();
    var southWestLng = southWestCorner.lng();
    var southEastCorner = new google.maps.LatLng(southWestLat, northEastLng);
    var northWestCorner = new google.maps.LatLng(northEastLat, southWestLng);

    return [
      northEastCorner,
      southEastCorner,
      southWestCorner,
      northWestCorner,
      northEastCorner
    ];
  }

  function updateOverlayMapCenter() {
    var newCenter = map.getCenter();
    if (overlayMap.getCenter() !== newCenter) {
      overlayMap.panTo(newCenter);
    }
  }

  google.maps.event.addListener(map, 'bounds_changed', function () {
    var newBounds = map.getBounds();
    var path = [];
    if (newBounds !== undefined) {
      var mapWidth = null;
      var mapHeight = null;
      (function () {
        var northEastCorner = newBounds.getNorthEast();
        var southWestCorner = newBounds.getSouthWest();
        var northEastLat = northEastCorner.lat();
        var northEastLng = northEastCorner.lng();
        var southWestLat = southWestCorner.lat();
        var southWestLng = southWestCorner.lng();

        mapHeight = Math.abs(180 + northEastLat - southWestLat) - 180;
        mapWidth = Math.abs(360 + northEastLng - southWestLng) - 360;
      })();

      var overlayMapHeight = null;
      var overlayMapWidth = null;
      (function () {
        var overlayBounds = overlayMap.getBounds();
        var northEastCorner = overlayBounds.getNorthEast();
        var southWestCorner = overlayBounds.getSouthWest();
        var northEastLat = northEastCorner.lat();
        var northEastLng = northEastCorner.lng();
        var southWestLat = southWestCorner.lat();
        var southWestLng = southWestCorner.lng();

        overlayMapHeight = Math.abs(180 + northEastLat - southWestLat) - 180;
        overlayMapHeight = overlayMapHeight / 2;
        overlayMapWidth = Math.abs(360 + northEastLng - southWestLng) - 360;
      })();

      var heightOverage = (overlayMapHeight - mapHeight);
      var widthOverage = (overlayMapWidth - mapWidth);
      var margin = 0.2;
      var divisor = (2 + 2 * margin);
      var wayTooBig = false;
      if (
        // margin of one means zoom in when overage is big enough that
        // zooming in would leave > half of width
        // which would be when overage is > three quarters width

        // margin of zero mean zoom in when overage is > half width
        (widthOverage > (divisor - 1) * (overlayMapWidth / divisor)) &&
        (heightOverage > (divisor - 1) * (overlayMapHeight / divisor))
      ) {
        //FIXME: sometimes it isn't enough to change by only 1.
        overlayMap.setZoom(overlayMap.getZoom() + 1);
      } else if (
        // margin of one means, zoom out when overage is < half width
        // margin of half means zoom out when overage is < quarter width
        // margin of zero means zoom out when overage is < 0
        (widthOverage < margin * overlayMapWidth / 2) ||
        (heightOverage < margin * overlayMapHeight / 2)
      ) {
        var overlayZoom = overlayMap.getZoom();
        if (overlayZoom > 0) {
          //FIXME: sometimes it isn't enough to change by only 1.
          overlayMap.setZoom(overlayZoom - 1);
        } else {
          wayTooBig = true;
        }
      }
      if (wayTooBig === false) {
        path = pathFromBounds(newBounds);
      }
    }
    translucentBox.setPath(path);
  });

  function degToRad(degrees) {
    return degrees * Math.PI / 180;
  }

  function latToY(latitude) {
    var lat = degToRad(latitude);
    return Math.log(Math.tan(lat) + 1 / Math.cos(lat));
  }

  function radToDeg(radians) {
    return radians * 180 / Math.PI;
  }

  function yToLat(y) {
    var angle = 2 * Math.atan(Math.pow(Math.E, y)) - Math.PI / 2;
    return radToDeg(angle);
  }

  google.maps.event.addListener(overlayMap, 'bounds_changed', function () {
    var mapBounds = map.getBounds();
    if (mapBounds !== undefined) {
      var northEastCorner = mapBounds.getNorthEast();
      var southWestCorner = mapBounds.getSouthWest();
      var northEastLat = northEastCorner.lat();
      var northEastLng = northEastCorner.lng();
      var southWestLat = southWestCorner.lat();
      var southWestLng = southWestCorner.lng();

      var mapCenter = map.getCenter();
      var overlayCenter = overlayMap.getCenter();
      var lngDelta = overlayCenter.lng() - mapCenter.lng();
      northEastLng += lngDelta;
      southWestLng += lngDelta;

      var overlayMapBounds = overlayMap.getBounds();
      var overlayTopLat = overlayMapBounds.getNorthEast().lat();
      var overlayBottomLat = overlayMapBounds.getSouthWest().lat();
      var overlayTop = latToY(overlayTopLat);
      var overlayBottom = latToY(overlayBottomLat);
      var overlayHeight = Math.abs(overlayTop - overlayBottom);
      var mapHeight = Math.abs(latToY(northEastLat) - latToY(southWestLat));

      var bottomLatDelta = overlayBottom + (overlayHeight - mapHeight) / 2;
      var topLatDelta = overlayTop - (overlayHeight - mapHeight) / 2;
      northEastLat = yToLat(topLatDelta);
      southWestLat = yToLat(bottomLatDelta);

      var sw = new google.maps.LatLng(southWestLat, southWestLng);
      var se = new google.maps.LatLng(southWestLat, northEastLng);
      var ne = new google.maps.LatLng(northEastLat, northEastLng);
      var nw = new google.maps.LatLng(northEastLat, southWestLng);
      transparentBox.setPath([sw, nw, ne, se, sw]);
    }
  });

  google.maps.event.addListener(map, 'zoom_changed', function () {
    var newZoom = Math.max(map.get_zoom() - 4, 0);
    if (overlayMap.getZoom() !== newZoom) {
      overlayMap.setZoom(newZoom);
    }
  });

  var mapDragInProgress = false;
  var panHasBegun = false;

  google.maps.event.addListener(map, 'center_changed', function () {
    if ((mapDragInProgress === false) && (panHasBegun === false)) {
      updateOverlayMapCenter();
    }
  });

  google.maps.event.addListener(map, 'idle', function () {
    if (panHasBegun === true) {
      panHasBegun = false;
      mapDragInProgress = false;
    }
  });

  google.maps.event.addListener(map, 'dragstart', function () {
    panHasBegun = false;
    mapDragInProgress = true;
  });

  google.maps.event.addListener(map, 'dragend', function () {
    updateOverlayMapCenter();
    mapDragInProgress = false;
  });

  google.maps.event.addListener(overlayMap, 'dragstart', function () {
    panHasBegun = false;
    mapDragInProgress = true;
  });

  google.maps.event.addListener(overlayMap, 'dragend', function () {
    panHasBegun = true;
    var newCenter = overlayMap.getCenter();
    if (map.getCenter() !== newCenter) {
      map.panTo(newCenter);
    }
  });

  google.maps.event.addListener(overlayMap, 'dblclick', function (mEvent) {
    mapDragInProgress = true;
    overlayMap.panTo(mEvent.latLng);
    map.panTo(mEvent.latLng);
  });

  google.maps.event.addListener(map, 'maptypeid_changed', function () {
    overlayMap.setOptions({mapTypeId: map.getMapTypeId()});
  });

  // Set map's properties now that all bindings and listeners are set up.
  map.setMapTypeId(google.maps.MapTypeId.ROADMAP);
  map.setZoom(8); // This will trigger a zoom_changed on the map
  var defaultCenter = new google.maps.LatLng(41.889, -87.629);
  map.setCenter(defaultCenter);

  overlayMap.setZoom(4);
  overlayMap.setCenter(defaultCenter);

};
<commit_msg>Fixed old-style[?] accessor name.<commit_after>/**
 * @name ExtOverviewMapControl for V3
 * @version 0.1
 * @author: Randy Becker
 * @fileoverview This library adds an overview map to a Google map.
 */
/*!
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *       http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

//TODO: Add corner arrow toggler
//TODO: Make transparant rectangle draggable
//TODO: Programatically construct and style overview div
//TODO: Encapsulate into an object, rather than window.onload
//TODO: Add docstrings
//TODO: Fix bugs near equator, prime meridian, poles
//TODO: Clean up everything

/*global google*/
window.onload = function () {
  // Initialize two maps: one full size and one in a small div in the corner
  // of the large map.
  var map = new google.maps.Map(document.getElementById('map_canvas'), {
    "noClear": true
  });
  var overlayMap = new google.maps.Map(
    document.getElementById('overlayMap'),
    {
      mapTypeId: google.maps.MapTypeId.ROADMAP, // Always show roadmap
      disableDefaultUI: true, // Turn off the controls
      scrollwheel: false, // Disable scrollwheel zooming
      disableDoubleClickZoom: true
    }
  );

  var translucentBox = new google.maps.Polygon({
    strokeColor: "#4444BB",
    strokeOpacity: 0.8,
    strokeWeight: 2,
    fillColor: "#4444BB",
    fillOpacity: 0.25
  });
  translucentBox.setMap(overlayMap);

  var transparentBox = new google.maps.Polygon({
    strokeColor: "#4444BB",
    strokeOpacity: 0.8,
    strokeWeight: 2,
    fillColor: "#4444BB",
    fillOpacity: 0.01
  });
  transparentBox.setMap(overlayMap);

  function pathFromBounds(bounds) {
    var northEastCorner = bounds.getNorthEast();
    var southWestCorner = bounds.getSouthWest();
    var northEastLat = northEastCorner.lat();
    var northEastLng = northEastCorner.lng();
    var southWestLat = southWestCorner.lat();
    var southWestLng = southWestCorner.lng();
    var southEastCorner = new google.maps.LatLng(southWestLat, northEastLng);
    var northWestCorner = new google.maps.LatLng(northEastLat, southWestLng);

    return [
      northEastCorner,
      southEastCorner,
      southWestCorner,
      northWestCorner,
      northEastCorner
    ];
  }

  function updateOverlayMapCenter() {
    var newCenter = map.getCenter();
    if (overlayMap.getCenter() !== newCenter) {
      overlayMap.panTo(newCenter);
    }
  }

  google.maps.event.addListener(map, 'bounds_changed', function () {
    var newBounds = map.getBounds();
    var path = [];
    if (newBounds !== undefined) {
      var mapWidth = null;
      var mapHeight = null;
      (function () {
        var northEastCorner = newBounds.getNorthEast();
        var southWestCorner = newBounds.getSouthWest();
        var northEastLat = northEastCorner.lat();
        var northEastLng = northEastCorner.lng();
        var southWestLat = southWestCorner.lat();
        var southWestLng = southWestCorner.lng();

        mapHeight = Math.abs(180 + northEastLat - southWestLat) - 180;
        mapWidth = Math.abs(360 + northEastLng - southWestLng) - 360;
      })();

      var overlayMapHeight = null;
      var overlayMapWidth = null;
      (function () {
        var overlayBounds = overlayMap.getBounds();
        var northEastCorner = overlayBounds.getNorthEast();
        var southWestCorner = overlayBounds.getSouthWest();
        var northEastLat = northEastCorner.lat();
        var northEastLng = northEastCorner.lng();
        var southWestLat = southWestCorner.lat();
        var southWestLng = southWestCorner.lng();

        overlayMapHeight = Math.abs(180 + northEastLat - southWestLat) - 180;
        overlayMapHeight = overlayMapHeight / 2;
        overlayMapWidth = Math.abs(360 + northEastLng - southWestLng) - 360;
      })();

      var heightOverage = (overlayMapHeight - mapHeight);
      var widthOverage = (overlayMapWidth - mapWidth);
      var margin = 0.2;
      var divisor = (2 + 2 * margin);
      var wayTooBig = false;
      if (
        // margin of one means zoom in when overage is big enough that
        // zooming in would leave > half of width
        // which would be when overage is > three quarters width

        // margin of zero mean zoom in when overage is > half width
        (widthOverage > (divisor - 1) * (overlayMapWidth / divisor)) &&
        (heightOverage > (divisor - 1) * (overlayMapHeight / divisor))
      ) {
        //FIXME: sometimes it isn't enough to change by only 1.
        overlayMap.setZoom(overlayMap.getZoom() + 1);
      } else if (
        // margin of one means, zoom out when overage is < half width
        // margin of half means zoom out when overage is < quarter width
        // margin of zero means zoom out when overage is < 0
        (widthOverage < margin * overlayMapWidth / 2) ||
        (heightOverage < margin * overlayMapHeight / 2)
      ) {
        var overlayZoom = overlayMap.getZoom();
        if (overlayZoom > 0) {
          //FIXME: sometimes it isn't enough to change by only 1.
          overlayMap.setZoom(overlayZoom - 1);
        } else {
          wayTooBig = true;
        }
      }
      if (wayTooBig === false) {
        path = pathFromBounds(newBounds);
      }
    }
    translucentBox.setPath(path);
  });

  function degToRad(degrees) {
    return degrees * Math.PI / 180;
  }

  function latToY(latitude) {
    var lat = degToRad(latitude);
    return Math.log(Math.tan(lat) + 1 / Math.cos(lat));
  }

  function radToDeg(radians) {
    return radians * 180 / Math.PI;
  }

  function yToLat(y) {
    var angle = 2 * Math.atan(Math.pow(Math.E, y)) - Math.PI / 2;
    return radToDeg(angle);
  }

  google.maps.event.addListener(overlayMap, 'bounds_changed', function () {
    var mapBounds = map.getBounds();
    if (mapBounds !== undefined) {
      var northEastCorner = mapBounds.getNorthEast();
      var southWestCorner = mapBounds.getSouthWest();
      var northEastLat = northEastCorner.lat();
      var northEastLng = northEastCorner.lng();
      var southWestLat = southWestCorner.lat();
      var southWestLng = southWestCorner.lng();

      var mapCenter = map.getCenter();
      var overlayCenter = overlayMap.getCenter();
      var lngDelta = overlayCenter.lng() - mapCenter.lng();
      northEastLng += lngDelta;
      southWestLng += lngDelta;

      var overlayMapBounds = overlayMap.getBounds();
      var overlayTopLat = overlayMapBounds.getNorthEast().lat();
      var overlayBottomLat = overlayMapBounds.getSouthWest().lat();
      var overlayTop = latToY(overlayTopLat);
      var overlayBottom = latToY(overlayBottomLat);
      var overlayHeight = Math.abs(overlayTop - overlayBottom);
      var mapHeight = Math.abs(latToY(northEastLat) - latToY(southWestLat));

      var bottomLatDelta = overlayBottom + (overlayHeight - mapHeight) / 2;
      var topLatDelta = overlayTop - (overlayHeight - mapHeight) / 2;
      northEastLat = yToLat(topLatDelta);
      southWestLat = yToLat(bottomLatDelta);

      var sw = new google.maps.LatLng(southWestLat, southWestLng);
      var se = new google.maps.LatLng(southWestLat, northEastLng);
      var ne = new google.maps.LatLng(northEastLat, northEastLng);
      var nw = new google.maps.LatLng(northEastLat, southWestLng);
      transparentBox.setPath([sw, nw, ne, se, sw]);
    }
  });

  google.maps.event.addListener(map, 'zoom_changed', function () {
    var newZoom = Math.max(map.getZoom() - 4, 0);
    if (overlayMap.getZoom() !== newZoom) {
      overlayMap.setZoom(newZoom);
    }
  });

  var mapDragInProgress = false;
  var panHasBegun = false;

  google.maps.event.addListener(map, 'center_changed', function () {
    if ((mapDragInProgress === false) && (panHasBegun === false)) {
      updateOverlayMapCenter();
    }
  });

  google.maps.event.addListener(map, 'idle', function () {
    if (panHasBegun === true) {
      panHasBegun = false;
      mapDragInProgress = false;
    }
  });

  google.maps.event.addListener(map, 'dragstart', function () {
    panHasBegun = false;
    mapDragInProgress = true;
  });

  google.maps.event.addListener(map, 'dragend', function () {
    updateOverlayMapCenter();
    mapDragInProgress = false;
  });

  google.maps.event.addListener(overlayMap, 'dragstart', function () {
    panHasBegun = false;
    mapDragInProgress = true;
  });

  google.maps.event.addListener(overlayMap, 'dragend', function () {
    panHasBegun = true;
    var newCenter = overlayMap.getCenter();
    if (map.getCenter() !== newCenter) {
      map.panTo(newCenter);
    }
  });

  google.maps.event.addListener(overlayMap, 'dblclick', function (mEvent) {
    mapDragInProgress = true;
    overlayMap.panTo(mEvent.latLng);
    map.panTo(mEvent.latLng);
  });

  google.maps.event.addListener(map, 'maptypeid_changed', function () {
    overlayMap.setOptions({mapTypeId: map.getMapTypeId()});
  });

  // Set map's properties now that all bindings and listeners are set up.
  map.setMapTypeId(google.maps.MapTypeId.ROADMAP);
  map.setZoom(8); // This will trigger a zoom_changed on the map
  var defaultCenter = new google.maps.LatLng(41.889, -87.629);
  map.setCenter(defaultCenter);

  overlayMap.setZoom(4);
  overlayMap.setCenter(defaultCenter);

};
<|endoftext|>