<commit_before>/**
  * Copyright (C) 2017 Orbeon, Inc.
  *
  * This program is free software; you can redistribute it and/or modify it under the terms of the
  * GNU Lesser General Public License as published by the Free Software Foundation; either version
  *  2.1 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 Lesser General Public License for more details.
  *
  * The full text of the license is available at http://www.gnu.org/copyleft/lesser.html
  */
package org.orbeon.fr

import org.orbeon.oxf.fr.{ControlOps, Names}
import org.orbeon.xforms.{$, AjaxServerEvent, Page, Support, XFormsId}
import org.scalajs.dom
import org.scalajs.dom.ext._
import org.scalajs.dom.{XMLHttpRequest, html}

import scala.scalajs.js
import scala.scalajs.js.JSConverters._
import scala.scalajs.js.annotation.{JSExportAll, JSExportTopLevel}
@JSExportTopLevel("ORBEON.fr.API")
@JSExportAll
object FormRunnerAPI {

  def findControlsByName(
    controlName : String,
    formElem    : js.UndefOr[html.Form] = js.undefined
  ): js.Array[html.Element] = {

    $(Support.formElemOrDefaultForm(formElem))
      .find(s".xforms-control[id *= '$controlName-control'], .xbl-component[id *= '$controlName-control']")
      .toArray() collect {
      // The result must be an `html.Element` already
      case e: html.Element ⇒ e
    } filter {
      // Check the id matches the requested name
      e ⇒ (e.id ne null) && (ControlOps.controlNameFromIdOpt(XFormsId.getStaticIdFromId(e.id)) contains controlName)
    } toJSArray
  }

  def isFormDataSafe(
    formElem    : js.UndefOr[html.Form] = js.undefined
  ): Boolean =
    Page.getForm(Support.formElemOrDefaultForm(formElem).id).isFormDataSafe

  def destroyForm(container: html.Element): Unit = {
    Option(container.querySelector("form")).foreach { (formElem) ⇒
      val form = Page.getForm(formElem.id)
      while (form.xblInstances.nonEmpty) {
        org.scalajs.dom.console.log("Destroying", form.xblInstances.last)
        form.xblInstances.last.destroy()
      }
    }
  }

  def embedForm(
    container   : html.Element,
    context     : String,
    app         : String,
    form        : String,
    action      : String,
    documentId  : js.UndefOr[String],
    queryString : js.UndefOr[String]
  ): Unit = {

    destroyForm(container)
    val xhr = new XMLHttpRequest()
    xhr.open(
      method = "GET",
      url = s"$context/fr/$app/$form/$action?orbeon-embeddable=true"
    )
    xhr.onload = { (_) ⇒
      if (xhr.status == 200) {

        // Find scripts we already have in the page, so not to include the same script more than once
        val existingScripts =
          dom.document.head
            .querySelectorAll("script")
            .map(_.asInstanceOf[html.Script])
            .map(_.src)

        // Insert HTML and find scripts
        container.innerHTML = xhr.responseText
        val innerScriptElements =
          container
            .querySelectorAll("script")
            .map(_.asInstanceOf[html.Script])

        // Add new scripts to the `<head>`
        innerScriptElements.foreach { innerScriptElement: html.Script ⇒
          val src = innerScriptElement.src
          if (! existingScripts.contains(src)) {
            val headScript =
              dom.document
                .createElement("script")
                .asInstanceOf[html.Script]
            headScript.src = innerScriptElement.src
            dom.document.head.appendChild(headScript)
          }
        }
      }
    }
    xhr.send()
  }
}

@JSExportTopLevel("ORBEON.fr.API.wizard")
@JSExportAll
object FormRunnerWizardAPI {

  def focus(
    controlName   : String,
    repeatIndexes : js.UndefOr[js.Array[Int]] = js.undefined
  ): Unit = {

    // Separate variable due to type inference fail when put inline below
    val indexesString = repeatIndexes map (_.mkString(" ")) getOrElse ""

    AjaxServerEvent.dispatchEvent(
      AjaxServerEvent(
        eventName  = "fr-wizard-focus",
        targetId   = Names.ViewComponent,
        properties = Map(
          "fr-control-name"   → controlName,
          "fr-repeat-indexes" → indexesString
        )
      )
    )
  }
}
<commit_msg>For #1577: remove `embedForm()` and `destroyForm()`<commit_after>/**
  * Copyright (C) 2017 Orbeon, Inc.
  *
  * This program is free software; you can redistribute it and/or modify it under the terms of the
  * GNU Lesser General Public License as published by the Free Software Foundation; either version
  *  2.1 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 Lesser General Public License for more details.
  *
  * The full text of the license is available at http://www.gnu.org/copyleft/lesser.html
  */
package org.orbeon.fr

import org.orbeon.oxf.fr.{ControlOps, Names}
import org.orbeon.xforms._
import org.scalajs.dom.html

import scala.scalajs.js
import scala.scalajs.js.JSConverters._
import scala.scalajs.js.annotation.{JSExportAll, JSExportTopLevel}
@JSExportTopLevel("ORBEON.fr.API")
@JSExportAll
object FormRunnerAPI {

  def findControlsByName(
    controlName : String,
    formElem    : js.UndefOr[html.Form] = js.undefined
  ): js.Array[html.Element] = {

    $(Support.formElemOrDefaultForm(formElem))
      .find(s".xforms-control[id *= '$controlName-control'], .xbl-component[id *= '$controlName-control']")
      .toArray() collect {
      // The result must be an `html.Element` already
      case e: html.Element ⇒ e
    } filter {
      // Check the id matches the requested name
      e ⇒ (e.id ne null) && (ControlOps.controlNameFromIdOpt(XFormsId.getStaticIdFromId(e.id)) contains controlName)
    } toJSArray
  }

  def isFormDataSafe(
    formElem    : js.UndefOr[html.Form] = js.undefined
  ): Boolean =
    Page.getForm(Support.formElemOrDefaultForm(formElem).id).isFormDataSafe

}

@JSExportTopLevel("ORBEON.fr.API.wizard")
@JSExportAll
object FormRunnerWizardAPI {

  def focus(
    controlName   : String,
    repeatIndexes : js.UndefOr[js.Array[Int]] = js.undefined
  ): Unit = {

    // Separate variable due to type inference fail when put inline below
    val indexesString = repeatIndexes map (_.mkString(" ")) getOrElse ""

    AjaxServerEvent.dispatchEvent(
      AjaxServerEvent(
        eventName  = "fr-wizard-focus",
        targetId   = Names.ViewComponent,
        properties = Map(
          "fr-control-name"   → controlName,
          "fr-repeat-indexes" → indexesString
        )
      )
    )
  }
}

{'fraction_non_alphanumeric': 0.10623353819139596, 'fraction_numerical': 0.002780216564237635, 'mean_word_length': 2.8248461108002236, 'pattern_counts': {'":': 0, '<': 4, '<?xml version=': 0, '>': 4, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1889170', 'n_tokens_mistral': 2137, 'n_tokens_neox': 2099, 'n_words': 543}