<commit_before>/*
 * PDFJsWindow.java
 *
 * Copyright (C) 2009-14 by RStudio, Inc.
 *
 * Unless you have received this program directly from RStudio pursuant
 * to the terms of a commercial license agreement with RStudio, then
 * this program is licensed to you under the terms of version 3 of the
 * GNU Affero General Public License. This program is distributed WITHOUT
 * ANY EXPRESS OR IMPLIED WARRANTY, INCLUDING THOSE OF NON-INFRINGEMENT,
 * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Please refer to the
 * AGPL (http://www.gnu.org/licenses/agpl-3.0.txt) for more details.
 *
 */
package org.rstudio.studio.client.pdfviewer.model;

import org.rstudio.core.client.dom.DomUtils;
import org.rstudio.core.client.dom.WindowEx;
import org.rstudio.studio.client.common.Value;
import org.rstudio.studio.client.common.synctex.model.PdfLocation;
import org.rstudio.studio.client.pdfviewer.events.LookupSynctexSourceEvent;
import org.rstudio.studio.client.pdfviewer.pdfjs.events.PDFLoadEvent;
import org.rstudio.studio.client.pdfviewer.pdfjs.events.PdfJsLoadEvent;
import org.rstudio.studio.client.pdfviewer.pdfjs.events.PdfJsWindowClosedEvent;

import com.google.gwt.dom.client.DivElement;
import com.google.gwt.dom.client.Element;
import com.google.gwt.dom.client.NativeEvent;
import com.google.gwt.dom.client.Node;
import com.google.gwt.dom.client.Style;
import com.google.gwt.dom.client.Style.Unit;
import com.google.gwt.event.shared.HandlerManager;
import com.google.gwt.event.shared.HandlerRegistration;
import com.google.gwt.core.client.Scheduler.RepeatingCommand;
import com.google.gwt.core.client.Scheduler;

// This class wraps a reference to the window hosting PDF.js, and is intended to
// encapsulate its interface. Any coupling with the UI or internals of PDF.js
// goes here.
public class PdfJsWindow extends WindowEx
{
   protected PdfJsWindow() 
   {
   }
   
   public final native void injectUiOnLoad(boolean forDesktop) /*-{
      var win = this;
      
      // runs when we detect that the document has fully loaded
      var initUi = function() {
         // inject our own CSS
         var rstudioCss = win.document.createElement("link");
         rstudioCss.rel = "stylesheet";
         rstudioCss.href = "viewer-rstudio.css";
         win.document.head.appendChild(rstudioCss);
      
         // hide the Open File and Bookmark buttons; these don't make sense in
         // our context
         var openFileButton = win.document.getElementById("openFile");
         if (openFileButton) {
            openFileButton.style.display = "none";
         }
         var bookmarkButton = win.document.getElementById("viewBookmark");
         if (bookmarkButton) {
            bookmarkButton.style.display = "none";
         }

         // create a Jump to Source toolbar button (image and style are applied
         // in viewer-rstudio.css)
         var jumpToSource = win.document.createElement("button");
         jumpToSource.className = "toolbarButton";
         jumpToSource.id = "jumpToSource";
         jumpToSource.title = "Sync editor location to PDF view";
         jumpToSource.addEventListener("click", function(evt) {
            @org.rstudio.studio.client.pdfviewer.model.PdfJsWindow::fireLookupCurrentViewEvent(Lorg/rstudio/studio/client/pdfviewer/model/PdfJsWindow;)(win);
         });

         var jumpToSourceContent = win.document.createElement("span");
         jumpToSourceContent.innerText = "Jump to Source Location";
         jumpToSource.appendChild(jumpToSourceContent);

         // put the Jump to Source button on the right toolbar
         var toolbarRight = win.document.getElementById("toolbarViewerRight");
         if (toolbarRight) {
            toolbarRight.insertBefore(jumpToSource, toolbarRight.firstChild);
         }
         
         // make the sidebar open by default
         win.PDFView.switchSidebarView('thumbs');
         win.PDFView.preferenceSidebarViewOnLoad = 1;
         var container = win.document.getElementById("outerContainer");
         if (container) {
            container.className += " sidebarOpen";
            win.PDFView.sidebarOpen = true;
         }
         var sidebarToggle = win.document.getElementById("sidebarToggle");
         if (sidebarToggle) {
            sidebarToggle.className += " toggled";
         }
         
         win.document.title = "RStudio: View PDF";

         // override the set initial view function so we know when the PDF has 
         // finished loading
         var _pdfView = win.PDFView;
         var _setInitialView = _pdfView.setInitialView;
         _pdfView.setInitialView = function(storedHash, scale) {
            _setInitialView.call(_pdfView, storedHash, scale);
            @org.rstudio.studio.client.pdfviewer.model.PdfJsWindow::firePDFLoadEvent()();
         }
         
         // stub out the set-title functions so our window title sticks
         _pdfView.setTitle = function() {};
         _pdfView.setTitleUsingUrl = function() {};
         
         // fire the load event
         @org.rstudio.studio.client.pdfviewer.model.PdfJsWindow::fireLoadEvent()();
         
         // wire unload event
         var unloadEvt = forDesktop ? "unload" : "beforeunload";
         win.addEventListener(unloadEvt, function() {
            @org.rstudio.studio.client.pdfviewer.model.PdfJsWindow::fireWindowClosedEvent()();
         });
         
         win.addEventListener("click", function(evt) {
            @org.rstudio.studio.client.pdfviewer.model.PdfJsWindow::firePageClickEvent(Lorg/rstudio/studio/client/pdfviewer/model/PdfJsWindow;Lcom/google/gwt/dom/client/NativeEvent;Lcom/google/gwt/dom/client/Element;)(win, evt, evt.target);
         });
      };

      // starts a timer that initializes the UI when the PDFView object appears
      var startInitUiTimer = function()
      {
         var n = 0, t = 0;
         var checkPDFViewAvailable = function() {
            n++;
            if (typeof(win.PDFView) === "object") {
               // PDFView is available now, initialize it
               clearInterval(t);
               initUi();
               return true;
            }
            else if (n > 100) {
               // cap at 100 tries (~5s)
               clearInterval(t);
            }
            return false;
         }
         if (!checkPDFViewAvailable()) {
            // if the PDFView object isn't available yet, check every 50ms 
            // until it is
            t = window.setInterval(checkPDFViewAvailable, 50);
         }
      }

      // if the document is finished loading, start watching for the PDFView
      // object to become available; if not, we can hook the load event 
      if (document.readyState === "complete")
         startInitUiTimer();
      else
         this.addEventListener("load", initUi);<commit_msg>check 'initialized' field before performing init<commit_after>/*
 * PDFJsWindow.java
 *
 * Copyright (C) 2009-14 by RStudio, Inc.
 *
 * Unless you have received this program directly from RStudio pursuant
 * to the terms of a commercial license agreement with RStudio, then
 * this program is licensed to you under the terms of version 3 of the
 * GNU Affero General Public License. This program is distributed WITHOUT
 * ANY EXPRESS OR IMPLIED WARRANTY, INCLUDING THOSE OF NON-INFRINGEMENT,
 * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Please refer to the
 * AGPL (http://www.gnu.org/licenses/agpl-3.0.txt) for more details.
 *
 */
package org.rstudio.studio.client.pdfviewer.model;

import org.rstudio.core.client.dom.DomUtils;
import org.rstudio.core.client.dom.WindowEx;
import org.rstudio.studio.client.common.Value;
import org.rstudio.studio.client.common.synctex.model.PdfLocation;
import org.rstudio.studio.client.pdfviewer.events.LookupSynctexSourceEvent;
import org.rstudio.studio.client.pdfviewer.pdfjs.events.PDFLoadEvent;
import org.rstudio.studio.client.pdfviewer.pdfjs.events.PdfJsLoadEvent;
import org.rstudio.studio.client.pdfviewer.pdfjs.events.PdfJsWindowClosedEvent;

import com.google.gwt.dom.client.DivElement;
import com.google.gwt.dom.client.Element;
import com.google.gwt.dom.client.NativeEvent;
import com.google.gwt.dom.client.Node;
import com.google.gwt.dom.client.Style;
import com.google.gwt.dom.client.Style.Unit;
import com.google.gwt.event.shared.HandlerManager;
import com.google.gwt.event.shared.HandlerRegistration;
import com.google.gwt.core.client.Scheduler.RepeatingCommand;
import com.google.gwt.core.client.Scheduler;

// This class wraps a reference to the window hosting PDF.js, and is intended to
// encapsulate its interface. Any coupling with the UI or internals of PDF.js
// goes here.
public class PdfJsWindow extends WindowEx
{
   protected PdfJsWindow() 
   {
   }
   
   public final native void injectUiOnLoad(boolean forDesktop) /*-{
      var win = this;
      
      // runs when we detect that the document has fully loaded
      var initUi = function() {
         // inject our own CSS
         var rstudioCss = win.document.createElement("link");
         rstudioCss.rel = "stylesheet";
         rstudioCss.href = "viewer-rstudio.css";
         win.document.head.appendChild(rstudioCss);
      
         // hide the Open File and Bookmark buttons; these don't make sense in
         // our context
         var openFileButton = win.document.getElementById("openFile");
         if (openFileButton) {
            openFileButton.style.display = "none";
         }
         var bookmarkButton = win.document.getElementById("viewBookmark");
         if (bookmarkButton) {
            bookmarkButton.style.display = "none";
         }

         // create a Jump to Source toolbar button (image and style are applied
         // in viewer-rstudio.css)
         var jumpToSource = win.document.createElement("button");
         jumpToSource.className = "toolbarButton";
         jumpToSource.id = "jumpToSource";
         jumpToSource.title = "Sync editor location to PDF view";
         jumpToSource.addEventListener("click", function(evt) {
            @org.rstudio.studio.client.pdfviewer.model.PdfJsWindow::fireLookupCurrentViewEvent(Lorg/rstudio/studio/client/pdfviewer/model/PdfJsWindow;)(win);
         });

         var jumpToSourceContent = win.document.createElement("span");
         jumpToSourceContent.innerText = "Jump to Source Location";
         jumpToSource.appendChild(jumpToSourceContent);

         // put the Jump to Source button on the right toolbar
         var toolbarRight = win.document.getElementById("toolbarViewerRight");
         if (toolbarRight) {
            toolbarRight.insertBefore(jumpToSource, toolbarRight.firstChild);
         }
         
         // make the sidebar open by default
         win.PDFView.switchSidebarView('thumbs');
         win.PDFView.preferenceSidebarViewOnLoad = 1;
         var container = win.document.getElementById("outerContainer");
         if (container) {
            container.className += " sidebarOpen";
            win.PDFView.sidebarOpen = true;
         }
         var sidebarToggle = win.document.getElementById("sidebarToggle");
         if (sidebarToggle) {
            sidebarToggle.className += " toggled";
         }
         
         win.document.title = "RStudio: View PDF";

         // override the set initial view function so we know when the PDF has 
         // finished loading
         var _pdfView = win.PDFView;
         var _setInitialView = _pdfView.setInitialView;
         _pdfView.setInitialView = function(storedHash, scale) {
            _setInitialView.call(_pdfView, storedHash, scale);
            @org.rstudio.studio.client.pdfviewer.model.PdfJsWindow::firePDFLoadEvent()();
         }
         
         // stub out the set-title functions so our window title sticks
         _pdfView.setTitle = function() {};
         _pdfView.setTitleUsingUrl = function() {};
         
         // fire the load event
         @org.rstudio.studio.client.pdfviewer.model.PdfJsWindow::fireLoadEvent()();
         
         // wire unload event
         var unloadEvt = forDesktop ? "unload" : "beforeunload";
         win.addEventListener(unloadEvt, function() {
            @org.rstudio.studio.client.pdfviewer.model.PdfJsWindow::fireWindowClosedEvent()();
         });
         
         win.addEventListener("click", function(evt) {
            @org.rstudio.studio.client.pdfviewer.model.PdfJsWindow::firePageClickEvent(Lorg/rstudio/studio/client/pdfviewer/model/PdfJsWindow;Lcom/google/gwt/dom/client/NativeEvent;Lcom/google/gwt/dom/client/Element;)(win, evt, evt.target);
         });
      };

      // starts a timer that initializes the UI when the PDFView object appears
      var startInitUiTimer = function()
      {
         var n = 0, t = 0;
         var checkPDFViewAvailable = function() {
            n++;
            if (typeof(win.PDFView) === "object" && win.PDFView.initialized) {
               // PDFView is available now, initialize it
               clearInterval(t);
               initUi();
               return true;
            }
            else if (n > 100) {
               // cap at 100 tries (~5s)
               clearInterval(t);
            }
            return false;
         }
         if (!checkPDFViewAvailable()) {
            // if the PDFView object isn't available yet, check every 50ms 
            // until it is
            t = window.setInterval(checkPDFViewAvailable, 50);
         }
      }

      // if the document is finished loading, start watching for the PDFView
      // object to become available; if not, we can hook the load event 
      if (document.readyState === "complete")
         startInitUiTimer();
      else
         this.addEventListener("load", initUi);
{'fraction_non_alphanumeric': 0.09969347540505036, 'fraction_numerical': 0.00335717413516275, 'mean_word_length': 2.529881504379186, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 5, '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': '2498351', 'n_tokens_mistral': 3926, 'n_tokens_neox': 3811, 'n_words': 923}