<commit_before>/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this file,
 * You can obtain one at http://mozilla.org/MPL/2.0/. */

const React = require('react')
const urlParse = require('url').parse
const windowActions = require('../actions/windowActions')
const appActions = require('../actions/appActions')
const ImmutableComponent = require('./immutableComponent')
const Immutable = require('immutable')
const cx = require('../lib/classSet.js')
const siteUtil = require('../state/siteUtil')
const UrlUtil = require('../lib/urlutil')
const messages = require('../constants/messages.js')
const remote = global.require('electron').remote
const contextMenus = require('../contextMenus')
const config = require('../constants/config.js')
const siteHacks = require('../data/siteHacks')
const ipc = global.require('electron').ipcRenderer
const FullScreenWarning = require('./fullScreenWarning')
const debounce = require('../lib/debounce.js')
const getSetting = require('../settings').getSetting
const settings = require('../constants/settings')
const adInfo = require('../data/adInfo.js')
const FindBar = require('./findbar.js')
const consoleStrings = require('../constants/console')
const { aboutUrls, isSourceAboutUrl, isTargetAboutUrl, getTargetAboutUrl } = require('../lib/appUrlUtil')
const { isFrameError } = require('../lib/errorUtil')

class Frame extends ImmutableComponent {
  constructor () {
    super()
    this.onUpdateWheelZoom = debounce(this.onUpdateWheelZoom.bind(this), 20)
    this.onFind = this.onFind.bind(this)
    this.onFindHide = this.onFindHide.bind(this)
    this.onFocus = this.onFocus.bind(this)
  }

  isAboutPage () {
    return aboutUrls.get(this.props.frame.get('location'))
  }

  updateAboutDetails (prevProps) {
    let location = this.props.frame.get('location')
    if (location === 'about:preferences') {
      this.webview.send(messages.SETTINGS_UPDATED, this.props.settings.toJS())
      this.webview.send(messages.SITE_SETTINGS_UPDATED, this.props.allSiteSettings.toJS())
    } else if (location === 'about:bookmarks') {
      this.webview.send(messages.BOOKMARKS_UPDATED, {
        bookmarks: this.props.bookmarks.toJS(),
        bookmarkFolders: this.props.bookmarkFolders.toJS()
      })
    } else if (location === 'about:downloads') {
      this.webview.send(messages.DOWNLOADS_UPDATED, {
        downloads: this.props.downloads.toJS()
      })
    } else if (location === 'about:passwords') {
      if (prevProps.passwords !== this.props.passwords) {
        this.webview.send(messages.PASSWORD_DETAILS_UPDATED, this.props.passwords.toJS())
      }
      if (prevProps.allSiteSettings !== this.props.allSiteSettings) {
        if (this.props.allSiteSettings) {
          this.webview.send(messages.PASSWORD_SITE_DETAILS_UPDATED,
                            this.props.allSiteSettings.filter((setting) => setting.get('savePasswords') === false).toJS())
        }
      }
    }

    // send state to about pages
    let aboutDetails = this.props.frame.get('aboutDetails')
    if (this.isAboutPage() && aboutDetails) {
      this.webview.send('state-updated', aboutDetails.toJS())
    }
  }

  shouldCreateWebview () {
    return !this.webview || this.webview.allowRunningInsecureContent !== this.allowRunningInsecureContent()
  }

  allowRunningInsecureContent () {
    let hack = siteHacks[urlParse(this.props.frame.get('location')).hostname]
    return !!(hack && hack.allowRunningInsecureContent)
  }

  updateWebview (cb) {
    // lazy load webview
    if (!this.webview && !this.props.isActive && !this.props.isPreview &&
        // don't lazy load about pages
        !aboutUrls.get(this.props.frame.get('src')) &&
        // pinned tabs don't serialize their state so the icon is lost for lazy loading
        !this.props.frame.get('pinnedLocation')) {
      return
    }

    let src = this.props.frame.get('src')
    let location = this.props.frame.get('location')

    // Create the webview dynamically because React doesn't whitelist all
    // of the attributes we need
    let webviewAdded = false
    let guestInstanceId = this.props.frame.get('guestInstanceId')
    if (this.shouldCreateWebview()) {
      // don't reuse the guestInstanceId when replacing webviews
      if (this.webview != null) {
        guestInstanceId = null
      }
      while (this.webviewContainer.firstChild) {
        this.webviewContainer.removeChild(this.webviewContainer.firstChild)
      }
      this.webview = document.createElement('webview')
      src = location
      webviewAdded = true
    }
    this.webview.setAttribute('allowDisplayingInsecureContent', true)
    this.webview.setAttribute('data-frame-key', this.props.frame.get('key'))
    this.webview.setAttribute('useragent', getSetting(settings.USERAGENT) || '')

    let partition
    if (this.props.frame.get('isPrivate')) {
      partition = 'private-1'
    } else if (this.props.frame.get('partitionNumber')) {
      partition = `persist:partition-${this.props.frame.get('partitionNumber')}`<commit_msg>don't reuse guestInstanceId when reloading webview fixes #1161<commit_after>/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this file,
 * You can obtain one at http://mozilla.org/MPL/2.0/. */

const React = require('react')
const urlParse = require('url').parse
const windowActions = require('../actions/windowActions')
const appActions = require('../actions/appActions')
const ImmutableComponent = require('./immutableComponent')
const Immutable = require('immutable')
const cx = require('../lib/classSet.js')
const siteUtil = require('../state/siteUtil')
const UrlUtil = require('../lib/urlutil')
const messages = require('../constants/messages.js')
const remote = global.require('electron').remote
const contextMenus = require('../contextMenus')
const config = require('../constants/config.js')
const siteHacks = require('../data/siteHacks')
const ipc = global.require('electron').ipcRenderer
const FullScreenWarning = require('./fullScreenWarning')
const debounce = require('../lib/debounce.js')
const getSetting = require('../settings').getSetting
const settings = require('../constants/settings')
const adInfo = require('../data/adInfo.js')
const FindBar = require('./findbar.js')
const consoleStrings = require('../constants/console')
const { aboutUrls, isSourceAboutUrl, isTargetAboutUrl, getTargetAboutUrl } = require('../lib/appUrlUtil')
const { isFrameError } = require('../lib/errorUtil')

class Frame extends ImmutableComponent {
  constructor () {
    super()
    this.onUpdateWheelZoom = debounce(this.onUpdateWheelZoom.bind(this), 20)
    this.onFind = this.onFind.bind(this)
    this.onFindHide = this.onFindHide.bind(this)
    this.onFocus = this.onFocus.bind(this)
  }

  isAboutPage () {
    return aboutUrls.get(this.props.frame.get('location'))
  }

  updateAboutDetails (prevProps) {
    let location = this.props.frame.get('location')
    if (location === 'about:preferences') {
      this.webview.send(messages.SETTINGS_UPDATED, this.props.settings.toJS())
      this.webview.send(messages.SITE_SETTINGS_UPDATED, this.props.allSiteSettings.toJS())
    } else if (location === 'about:bookmarks') {
      this.webview.send(messages.BOOKMARKS_UPDATED, {
        bookmarks: this.props.bookmarks.toJS(),
        bookmarkFolders: this.props.bookmarkFolders.toJS()
      })
    } else if (location === 'about:downloads') {
      this.webview.send(messages.DOWNLOADS_UPDATED, {
        downloads: this.props.downloads.toJS()
      })
    } else if (location === 'about:passwords') {
      if (prevProps.passwords !== this.props.passwords) {
        this.webview.send(messages.PASSWORD_DETAILS_UPDATED, this.props.passwords.toJS())
      }
      if (prevProps.allSiteSettings !== this.props.allSiteSettings) {
        if (this.props.allSiteSettings) {
          this.webview.send(messages.PASSWORD_SITE_DETAILS_UPDATED,
                            this.props.allSiteSettings.filter((setting) => setting.get('savePasswords') === false).toJS())
        }
      }
    }

    // send state to about pages
    let aboutDetails = this.props.frame.get('aboutDetails')
    if (this.isAboutPage() && aboutDetails) {
      this.webview.send('state-updated', aboutDetails.toJS())
    }
  }

  shouldCreateWebview () {
    return !this.webview || this.webview.allowRunningInsecureContent !== this.allowRunningInsecureContent()
  }

  allowRunningInsecureContent () {
    let hack = siteHacks[urlParse(this.props.frame.get('location')).hostname]
    return !!(hack && hack.allowRunningInsecureContent)
  }

  updateWebview (cb) {
    // lazy load webview
    if (!this.webview && !this.props.isActive && !this.props.isPreview &&
        // don't lazy load about pages
        !aboutUrls.get(this.props.frame.get('src')) &&
        // pinned tabs don't serialize their state so the icon is lost for lazy loading
        !this.props.frame.get('pinnedLocation')) {
      return
    }

    let src = this.props.frame.get('src')
    let location = this.props.frame.get('location')

    // Create the webview dynamically because React doesn't whitelist all
    // of the attributes we need
    let webviewAdded = false
    let guestInstanceId = null
    if (this.shouldCreateWebview()) {
      // only set the guestInstanceId if this is a new frame
      if (this.webview == null) {
        guestInstanceId = this.props.frame.get('guestInstanceId')
      }
      while (this.webviewContainer.firstChild) {
        this.webviewContainer.removeChild(this.webviewContainer.firstChild)
      }
      this.webview = document.createElement('webview')
      src = location
      webviewAdded = true
    }
    this.webview.setAttribute('allowDisplayingInsecureContent', true)
    this.webview.setAttribute('data-frame-key', this.props.frame.get('key'))
    this.webview.setAttribute('useragent', getSetting(settings.USERAGENT) || '')

    let partition
    if (this.props.frame.get('isPrivate')) {
      partition = 'private-1'
    } else if (this.props.frame.get('partitionNumber')) {
      partition = `persist:partition-${this.props.frame.get('partitionNumber')}`
{'fraction_non_alphanumeric': 0.13990041979888704, 'fraction_numerical': 0.0017572976666992092, 'mean_word_length': 3.6040449438202247, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 5, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 6, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2812099', 'n_tokens_mistral': 3087, 'n_tokens_neox': 3055, 'n_words': 601}