// Copyright (C) 2017 The Android Open Source Project
//
// 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.

Gerrit.install(function(self) {
  // TODO: ideally we want to turn off find owners when code owners enabled
  // but since they are two plugins right now, we just keep find owners around
  // for a while
  // const ENABLED_EXPERIMENTS = window.ENABLED_EXPERIMENTS || [];
  // if (ENABLED_EXPERIMENTS.includes('UiFeature__plugin_code_owners')) {
  //   // Disable if experiment UiFeature__plugin_code_owners is enabled
  //   // Also hide previous 'Find Owners' button under 'MORE'.
  //   function removeFindOwnerFromSecondaryActions() {
  //     var changeActions = self.changeActions();
  //     changeActions.setActionHidden('revision', 'find-owners~find-owners', true);
  //   }
  //   self.on('showchange', removeFindOwnerFromSecondaryActions);
  //   return;
  // }

  // If context.popup API exists and popup content is small,
  // use the API and set useContextPopup,
  // otherwise, use pageDiv and set its visibility.
  var useContextPopup = false;
  var pageDiv = document.createElement('div');
  document.body.appendChild(pageDiv);
  function hideFindOwnersPage() {
    pageDiv.style.visibility = 'hidden';
  }
  function popupFindOwnersPage(context, change, revision, onSubmit) {
    const PADDING = 5;
    const LARGE_PAGE_STYLE = Gerrit.css(
        'visibility: hidden;' +
        'background: rgba(200, 200, 200, 0.95);' +
        'border: 3px solid;' +
        'border-color: #c8c8c8;' +
        'border-radius: 3px;' +
        'position: fixed;' +
        'z-index: 100;' +
        'overflow: auto;' +
        'padding: ' + PADDING + 'px;');
    const BUTTON_STYLE = Gerrit.css(
        'background-color: #4d90fe;' +
        'border: 2px solid;' +
        'border-color: #4d90fe;' +
        'margin: 2px 10px 2px 10px;' +
        'text-align: center;' +
        'font-size: 8pt;' +
        'font-weight: bold;' +
        'color: #fff;' +
        '-webkit-border-radius: 2px;' +
        'cursor: pointer;');
    const createElWithText = (tagName, text) => {
      const el = document.createElement(tagName);
      if (text) el.textContent = text;
      return el;
    };

    const createBulletEl = () => {
      return createElWithText('small', '\u2605');  // a Black Star
    };
    const createIsExemptedEl = () => {
      return createElWithText('b', 'This change is Exempt-From-Owner-Approval.');
    };

    const createNoOwnerEl = () => {
      return createElWithText('b', 'No owner was found for changed files.');
    };

    const createOnSubmitHeader = () => {
      return createElWithText(
          'b', 'WARNING: Need owner Code-Review vote before submit.');
    };

    const createOwnersHeaderEl = () => {
      return createElWithText('b', 'Owners in alphabetical order:');
    };

    const createSelectReviewersEl = (minCRVote) => {
      const el = document.createElement('p');
      el.appendChild(createElWithText(
          'b',
          'Check the box before owner names to select reviewers, ' +
              'then click the "Apply" button.'));
      el.appendChild(createElWithText('br'));
      const smallEl = createElWithText(
          'small',
          'If owner-approval requirement is enabled, ' +
              `each file needs at least one Code-Review +${minCRVote} vote from an owner. ` +
              'Owners listed after a file are ordered by their importance. ' +
              '(Or declare "');
      const smallerEl = createElWithText('b', 'Exempt-From-Owner-Approval:');
      smallerEl.style.fontSize = '80%';
      smallEl.appendChild(smallerEl);
      smallEl.appendChild(createElWithText('i', 'reasons...'));
      smallEl.appendChild(document.createTextNode('" in the commit message.)'));
      el.appendChild(smallEl);
      el.appendChild(createElWithText('br'));
      return el;
    };

    // Changed files are put into groups.
    // Each group has a unique list of owners and
    // belongs to one of the 5 types based on owner status.
    // Groups of a type are displayed in one HTML section.
    // Group type names are mapped to ordered numbers starting from 0.
    const GROUP_TYPE = {
      'NEED_REVIEWER': 0,   // no owner in Reviewers list yet
      'NEED_APPROVAL': 1,   // no owner Code-Review +1 yet
      'STAR_APPROVED': 2,   // has '*', no need of owner vote
      'OWNER_APPROVED': 3,  // has owner approval
      'HAS_NO_OWNER': 4,    // no owner at all, only shown with other types
    };
    const NUM_GROUP_TYPES = 5;

    const createGroupTypeHeaderEl = (text) => {
      const el = createElWithText('span');
      el.appendChild(createElWithText('hr'));
      el.appendChild(createElWithText('b', text));
      el.appendChild(createElWithText('br'));
      return el;
    };
    const HTML_GROUP_TYPE_HEADER = [
      createGroupTypeHeaderEl(
          'Files with owners but no owner is in the Reviewers list:'),
      createGroupTypeHeaderEl(
          'Files with owners but no Code-Review vote from an owner:'),
      createGroupTypeHeaderEl(
          'Files with owners but can be approved by anyone (*):'),
      createGroupTypeHeaderEl('Files with required Code-Review vote from owners:'),
      createGroupTypeHeaderEl('Files without any named owner:'),
    ];

    const GROUP_TYPE_DIV_ID = [
      'FindOwners:NeedReviewer',
      'FindOwners:NeedApproval',
      'FindOwners:StarApproved',
      'FindOwners:OwnerApproved',
      'FindOwners:HasNoOwner',
    ];

    const APPLY_BUTTON_ID = 'FindOwners:Apply';
    const CHECKBOX_ID = 'FindOwners:CheckBox';
    const HEADER_DIV_ID = 'FindOwners:Header';
    const OWNERS_DIV_ID = 'FindOwners:Owners';

    // Aliases to values in the context.
    const branch = change.branch;
    const changeId = change._number;
    const changeOwner = change.owner;
    const message = revision.commit.message;
    const project = change.project;

    var minVoteLevel = 1;   // could be changed by server returned results.
    var reviewerId = {};    // map from a reviewer's email to account id.
    var reviewerVote = {};  // map from a reviewer's email to Code-Review vote.

    // addList and removeList are used only under applySelections.
    var addList = [];         // remain emails to add to reviewers
    var removeList = [];      // remain emails to remove from reviewers
    var needRefresh = false;  // true if to refresh after checkAddRemoveLists

    function getElement(id) {
      return document.getElementById(id);
    }
    function restApiGet(url, callback) {
      self.restApi().get('/../..' + url).then(callback);
    }
    function restApiPost(url, data, callback) {
      self.restApi().post('/../..' + url, data).then(callback);
    }
    function restApiDelete(url, callback, errMessage) {
      self.restApi().delete('/../..' + url).then(callback).catch((e) => {
        alert(errMessage);
      });
    }
    function getReviewers(change, callBack) {
      restApiGet('/changes/' + change + '/reviewers', callBack);
    }
    function setupReviewersMap(reviewerList) {
      reviewerId = {};
      reviewerVote = {};
      reviewerList.forEach(function(reviewer) {
        if ('email' in reviewer && '_account_id' in reviewer) {
          reviewerId[reviewer.email] = reviewer._account_id;
          reviewerVote[reviewer.email] = 0;
          if ('approvals' in reviewer && 'Code-Review' in reviewer.approvals) {
            reviewerVote[reviewer.email] =
                parseInt(reviewer.approvals['Code-Review']);
            // The 'Code-Review' values could be "-2", "-1", " 0", "+1", "+2"
          }
        }
      });
      // Give CL author a default minVoteLevel vote.
      if (changeOwner != null && 'email' in changeOwner &&
          '_account_id' in changeOwner &&
          (!(changeOwner.email in reviewerId) ||
           reviewerVote[changeOwner.email] == 0)) {
        reviewerId[changeOwner.email] = changeOwner._account_id;
        reviewerVote[changeOwner.email] = minVoteLevel;
      }
    }
    function checkAddRemoveLists() {
      // Gerrit.post and delete are asynchronous.
      // Do one at a time, with checkAddRemoveLists as callBack.
      for (var i = 0; i < addList.length; i++) {
        var email = addList[i];
        if (!(email in reviewerId)) {
          addList = addList.slice(i + 1, addList.length);
          // A post request can fail if given reviewer email is invalid.
          // Gerrit core UI shows the error dialog and does not provide
          // a way for plugins to handle the error yet.
          needRefresh = true;
          restApiPost(
              '/changes/' + changeId + '/reviewers', {'reviewer': email},
              checkAddRemoveLists);
          return;
        }
      }
      for (var i = 0; i < removeList.length; i++) {
        var email = removeList[i];
        if (email in reviewerId) {
          removeList = removeList.slice(i + 1, removeList.length);
          needRefresh = true;
          restApiDelete(
              '/changes/' + changeId + '/reviewers/' + reviewerId[email],
              checkAddRemoveLists, 'Cannot delete reviewer: ' + email);
          return;
        }
      }
      hideFindOwnersPage();
      if (needRefresh) {
        needRefresh = false;
        (!!Gerrit.refresh) ? Gerrit.refresh() : location.reload();
      }
      callServer(showFindOwnersResults);
    }
    function applyGetReviewers(reviewerList) {
      setupReviewersMap(reviewerList);
      checkAddRemoveLists();  // update and pop up window at the end
    }
    function hasStar(owners) {
      return owners.some(function(owner) {
        return owner == '*';
      });
    }
    function hasNamedOwner(owners) {
      return owners.some(function(owner) {
        return owner != '*';
      });
    }
    function hasOwnerReviewer(reviewers, owners) {
      return owners.some(function(owner) {
        return owner in reviewers;
      });
    }
    function hasOwnerApproval(votes, owners) {
      var foundApproval = false;
      for (var j = 0; j < owners.length; j++) {
        if (owners[j] in votes) {
          var v = votes[owners[j]];
          if (v < 0) {
            return false;  // cannot have any negative vote
          }
          foundApproval |= v >= minVoteLevel;
        }
      }
      return foundApproval;
    }
    function isExemptedFromOwnerApproval() {
      return message.match(/(Exempted|Exempt)-From-Owner-Approval:/);
    }
    function strElement(s) {
      var e = document.createElement('span');
      e.innerHTML = s;
      return e;
    }
    function newButton(name, action) {
      var b = document.createElement('button');
      b.appendChild(document.createTextNode(name));
      b.className = BUTTON_STYLE;
      b.onclick = action;
      b.style.display = 'inline';
      b.style.float = 'right';
      return b;
    }
    function showJsonLines(args, key, obj) {
      showBoldKeyValueLines(args, key, JSON.stringify(obj, null, 2));
    }
    function showBoldKeyValueLines(args, key, value) {
      args.push(
          createElWithText('hr'), strElement('<b>' + key + '</b>:'),
          createElWithText('br'));
      value.split('\n').forEach(function(line) {
        args.push(strElement(line), createElWithText('br'));
      });
    }
    function showDebugMessages(result, args) {
      function addKeyValue(key, value) {
        args.push(strElement('<b>' + key + '</b>: ' + value + '<br>'));
      }
      args.push(createElWithText('hr'));
      addKeyValue('changeId', changeId);
      addKeyValue('project', project);
      addKeyValue('branch', branch);
      addKeyValue('changeOwner.email', changeOwner.email);
      addKeyValue('Gerrit.url', Gerrit.url());
      addKeyValue('self.url', self.url());
      showJsonLines(args, 'changeOwner', change.owner);
      showBoldKeyValueLines(args, 'commit.message', message);
      showJsonLines(args, 'Client reviewers Ids', reviewerId);
      showJsonLines(args, 'Client reviewers Votes', reviewerVote);
      Object.keys(result).forEach(function(k) {
        showJsonLines(args, 'Server.' + k, result[k]);
      });
    }
    function showFilesAndOwners(result, args) {
      var sortedOwners = result.owners.map(function(ownerInfo) {
        return ownerInfo.email;
      });
      var groups = {};  // a map from group_name to
                        // {'type': 0..(NUM_GROUP_TYPES-1),
                        //  'size': num_of_files_in_this_group,
                        //  'owners': space_separated_owner_emails}
      var header = emptyDiv(HEADER_DIV_ID);
      var groupTypeDiv = Array(NUM_GROUP_TYPES);
      for (var i = 0; i < NUM_GROUP_TYPES; i++) {
        groupTypeDiv[i] = emptyDiv(GROUP_TYPE_DIV_ID[i]);
      }

      var cancelButton = newButton('Cancel', hideFindOwnersPage);
      header.appendChild(cancelButton);
      addApplyButton();

      var ownersDiv = emptyDiv(OWNERS_DIV_ID);
      var numCheckBoxes = 0;
      var owner2boxes = {};  // owner name ==> array of checkbox id
      var owner2email = {};  // owner name ==> email address
      minVoteLevel =
          ('minOwnerVoteLevel' in result ? result.minOwnerVoteLevel : 1);

      function addApplyButton() {
        var apply = newButton('Apply', doApplyButton);
        apply.id = APPLY_BUTTON_ID;
        apply.style.display = 'none';
        header.appendChild(apply);
      }
      function emptyDiv(id) {
        var e = document.createElement('div');
        e.id = id;
        e.style.display = 'none';
        args.push(e);
        return e;
      }
      function colorSpan(str, color) {
        const el = createElWithText('span', str)
        el.style.color = color;
        return el;
      }
      function doApplyButton() {
        addList = [];
        removeList = [];
        // add each owner's email address to addList or removeList
        Object.keys(owner2boxes).forEach(function(owner) {
          (getElement(owner2boxes[owner][0]).checked ? addList : removeList)
              .push(owner2email[owner]);
        });
        getReviewers(changeId, applyGetReviewers);
      }
      function clickBox(event) {
        var name = event.target.value;
        var checked = event.target.checked;
        var others = owner2boxes[name];
        others.forEach(function(id) {
          getElement(id).checked = checked;
        });
        getElement(APPLY_BUTTON_ID).style.display = 'inline';
      }
      function addGroupsToDiv(div, keys, titleEl) {
        if (keys.length <= 0) {
          div.style.display = 'none';
          return;
        }
        div.innerHTML = '';
        div.style.display = 'inline';
        div.appendChild(titleEl);
        function addOwner(itemDiv, ownerEmail) {
          if (ownerEmail == '*') {
            return;  // no need to list/select '*'
          }
          numCheckBoxes++;
          var name = ownerEmail.replace(/@[^ ]*/g, '');
          owner2email[name] = ownerEmail;
          var id = CHECKBOX_ID + ':' + numCheckBoxes;
          if (!(name in owner2boxes)) {
            owner2boxes[name] = [];
          }
          owner2boxes[name].push(id);

          var box = document.createElement('input');
          box.type = 'checkbox';
          box.checked = (ownerEmail in reviewerId);
          box.id = id;
          box.value = name;
          box.onclick = clickBox;
          itemDiv.appendChild(createElWithText('span', '\u00a0\u00a0'));
          var nobr = document.createElement('nobr');
          nobr.appendChild(box);
          nobr.appendChild(strElement(name));
          itemDiv.appendChild(nobr);
        }
        keys.forEach(function(key) {
          var owners = groups[key].owners;  // string of owner emails
          var numFiles = groups[key].size;

          var itemEl = createElWithText('span');
          itemEl.appendChild(createBulletEl());
          itemEl.appendChild(document.createTextNode('\u00a0'));
          itemEl.appendChild(createElWithText('b', key));
          itemEl.appendChild(document.createTextNode(
              ((numFiles > 1) ? (' (' + numFiles + ' files)') : '')));
          var setOfOwners = new Set(owners.split(' '));
          function add2list(list, email) {
            if (setOfOwners.has(email)) {
              list.push(email);
            }
            return list;
          }
          var reducedList = sortedOwners.reduce(add2list, []);
          if (hasNamedOwner(reducedList)) {
            itemEl.appendChild(document.createTextNode(':'));
          }

          let itemDiv = document.createElement('div');
          itemDiv.style.paddingTop = '0.5em';
          itemDiv.appendChild(itemEl);
          itemDiv.appendChild(createElWithText('br'));
          reducedList.forEach(addOwner.bind(this, itemDiv));
          div.appendChild(itemDiv);
        });
        div.lastElementChild.style.paddingBottom = '0.5em';
      }
      function addOwnersDiv(div, titleEl) {
        div.textContent = '';
        div.style.display = 'inline';
        div.appendChild(titleEl);
        div.appendChild(createElWithText('br'));
        function compareOwnerInfo(o1, o2) {
          return o1.email.localeCompare(o2.email);
        }
        result.owners.sort(compareOwnerInfo).forEach(function(ownerInfo) {
          var email = ownerInfo.email;
          var emailEl = createElWithText('span', email);
          if (email != '*') {  // do not list special email *
            var vote = reviewerVote[email];
            if ((email in reviewerVote) && vote != 0) {
              if (vote > 0) {
                emailEl.appendChild(
                    colorSpan('\u00a0(+' + vote + ')', 'green'));
              } else {
                emailEl.appendChild(colorSpan('\u00a0(' + vote + ')', 'red'));
              }
            }
            const spanEl = createElWithText('span');
            spanEl.appendChild(document.createTextNode('\u00a0\u00a0'));
            spanEl.appendChild(emailEl);
            spanEl.appendChild(createElWithText('br'));
            div.appendChild(spanEl);
          }
        });
      }
      function updateDivContent() {
        var listOfGroup = Array(NUM_GROUP_TYPES);
        for (var i = 0; i < NUM_GROUP_TYPES; i++) {
          listOfGroup[i] = [];
        }
        Object.keys(groups).sort().forEach(function(key) {
          listOfGroup[groups[key].type].push(key);
        });

        // Add message to header div and make visible.
        let headerMessageDiv = document.createElement('div');
        if (isExemptedFromOwnerApproval()) {
          headerMessageDiv.appendChild(createIsExemptedEl());
        } else {
          if (onSubmit) {
            headerMessageDiv.appendChild(createOnSubmitHeader());
          }
          headerMessageDiv.appendChild(createSelectReviewersEl(minVoteLevel));
        }
        header.appendChild(headerMessageDiv);
        header.style.display = 'inline';

        numCheckBoxes = 0;
        owner2boxes = {};
        for (var i = 0; i < NUM_GROUP_TYPES; i++) {
          addGroupsToDiv(
              groupTypeDiv[i], listOfGroup[i], HTML_GROUP_TYPE_HEADER[i]);
        }
        addOwnersDiv(ownersDiv, createOwnersHeaderEl());
      }
      function createGroups() {
        var owners2group = {};  // owner list to group name
        var firstNoOwnerFile = null;
        var keysOfFile2Owners = Object.keys(result.file2owners);
        keysOfFile2Owners.sort().forEach(function(name) {
          var splitOwners = result.file2owners[name];
          var owners = splitOwners.join(' ');
          if (owners in owners2group) {
            groups[owners2group[owners]].size += 1;
          } else {
            owners2group[owners] = name;
            var type;
            if (!hasNamedOwner(splitOwners)) {
              firstNoOwnerFile = name;
              type = GROUP_TYPE.HAS_NO_OWNER;
            } else if (hasOwnerApproval(reviewerVote, splitOwners)) {
              type = GROUP_TYPE.OWNER_APPROVED;
            } else if (hasStar(splitOwners)) {
              type = GROUP_TYPE.STAR_APPROVED;
            } else if (!hasOwnerReviewer(reviewerId, splitOwners)) {
              type = GROUP_TYPE.NEED_REVIEWER;
            } else {
              type = GROUP_TYPE.NEED_APPROVAL;
            }
            groups[name] = {'type': type, 'size': 1, 'owners': owners};
          }
        });
        var numNoOwnerFiles = result.files.length - keysOfFile2Owners.length;
        if (keysOfFile2Owners.length > 0 && numNoOwnerFiles > 0) {
          if (!!firstNoOwnerFile) {
            // count other files as HAS_NO_OWNER
            groups[firstNoOwnerFile].size += numNoOwnerFiles;
          } else {
            // use one of the no-owner-file as group name
            for (var i = 0; i < result.files.length; i++) {
              var name = result.files[i];
              if (!(name in result.file2owners) &&
                  !(('./' + name) in result.file2owners)) {
                groups[name] = {
                  'type': GROUP_TYPE.HAS_NO_OWNER,
                  'size': numNoOwnerFiles,
                  'owners': '*',
                };
                break;
              }
            }
          }
        }
      }
      createGroups();
      updateDivContent();
    }
    function showFindOwnersResults(result) {
      function prepareElements() {
        var elems = [];
        var textEl =
            Object.keys(result.file2owners).length <= 0 ? createNoOwnerEl() : null;
        useContextPopup = !!context && !!textEl && !!context.popup;
        if (!!textEl) {
          if (useContextPopup) {
            elems.push(createElWithText('hr'), textEl, createElWithText('hr'));
            var onClick = function() {
              context.hide();
            };
            elems.push(
                context.button('OK', {onclick: onClick}), createElWithText('hr'));
          } else {
            elems.push(textEl, newButton('OK', hideFindOwnersPage));
          }
        } else {
          showFilesAndOwners(result, elems);
          if (result.addDebugMsg) {
            showDebugMessages(result, elems);
          }
        }
        return elems;
      }
      function popupWindow(reviewerList) {
        setupReviewersMap(reviewerList);
        var elems = prepareElements();
        if (useContextPopup) {
          context.popup(context.div.apply(this, elems));
        } else {
          while (pageDiv.firstChild) {
            pageDiv.removeChild(pageDiv.firstChild);
          }
          elems.forEach(function(e) {
            pageDiv.appendChild(e);
          });
          pageDiv.className = LARGE_PAGE_STYLE;
          // Calculate required height, limited to 85% of window height,
          // and required width, limited to 75% of window width.
          var maxHeight = Math.round(window.innerHeight * 0.85);
          var maxWidth = Math.round(window.innerWidth * 0.75);
          pageDiv.style.top = '5%';
          pageDiv.style.height = 'auto';
          pageDiv.style.left = '10%';
          pageDiv.style.width = 'auto';
          var rect = pageDiv.getBoundingClientRect();
          if (rect.width > maxWidth) {
            pageDiv.style.width = maxWidth + 'px';
            rect = pageDiv.getBoundingClientRect();
          }
          pageDiv.style.left =
              Math.round((window.innerWidth - rect.width) / 2) + 'px';
          if (rect.height > maxHeight) {
            pageDiv.style.height = maxHeight + 'px';
            rect = pageDiv.getBoundingClientRect();
          }
          pageDiv.style.top =
              Math.round((window.innerHeight - rect.height) / 2) + 'px';
          pageDiv.style.visibility = 'visible';
        }
      }
      getReviewers(changeId, popupWindow);
    }
    function callServer(callBack) {
      // Use the plugin REST API; pass only changeId;
      // let server get current patch set, project and branch info.
      restApiGet('/changes/' + changeId + '/owners', callBack);
    }

    callServer(showFindOwnersResults);
  }
  function onSubmit(change, revision) {
    const OWNER_REVIEW_LABEL = 'Owner-Review-Vote';
    if (change.labels.hasOwnProperty(OWNER_REVIEW_LABEL)) {
      // Pop up Find Owners page; do not submit.
      popupFindOwnersPage(null, change, revision, true);
      return false;
    }
    return true;  // Okay to submit.
  }
  var actionKey = null;
  function onShowChangePolyGerrit(change, revision) {
    var changeActions = self.changeActions();
    // Hide previous 'Find Owners' button under 'MORE'.
    changeActions.setActionHidden('revision', 'find-owners~find-owners', true);
    if (!!actionKey) {
      changeActions.removeTapListener(actionKey);
      changeActions.remove(actionKey);
    }
    actionKey = changeActions.add('revision', '[FIND OWNERS]');
    changeActions.setIcon(actionKey, 'robot');
    changeActions.setTitle(actionKey, 'Find owners of changed files');
    changeActions.addTapListener(actionKey, (e) => {
      if (e) e.stopPropagation();

      popupFindOwnersPage(null, change, revision, false);
    });
  }
  function onClick(event) {
    if (pageDiv.style.visibility != 'hidden' && !useContextPopup) {
      var x = event.clientX;
      var y = event.clientY;
      var rect = pageDiv.getBoundingClientRect();
      if (x < rect.left || x >= rect.left + rect.width || y < rect.top ||
          y >= rect.top + rect.height) {
        hideFindOwnersPage();
      }
    }
  }
  if (window.Polymer) {
    self.on('showchange', onShowChangePolyGerrit);
  } else {
    console.log('WARNING, no [FIND OWNERS] button');
  }
  // When the "Submit" button is clicked, call onSubmit.
  self.on('submitchange', onSubmit);
  // Clicks outside the pop up window should close the window.
  document.body.addEventListener('click', onClick);
  // Leaving page should close the window.
  window.addEventListener('popstate', hideFindOwnersPage);
});
