Safari Reference Library Apple Developer
Search

Adding a Global HTML Page

A global HTML page is a place for you to put JavaScript code, data tables, and other resources requiring no user interface that your extension needs to load only once per Safari session. The global page is not mandatory. You can have at most one global page per extension.

The main uses for a global page are:

Adding a Global Page in Extension Builder

First create the global HTML page. The global HTML page is an HTML file that is loaded but never displayed. It can contain JavaScript functions declared in script elements or in external .js files included using the script element’s src attribute. The .js files can be located inside the extension folder and referenced by relative URL.

If you have not already done so, click + in Extension Builder and choose New Extension. You are prompted to give the extension a name and choose a location for it. Extension Builder creates a folder with the name you choose and the file extension .safariextension.

Drag the HTML file that you want to use as your global page into the extension folder using the Finder or Windows file system. Drag in any external .js files or other resources the global page needs as well.

Click Global Page File in Extension Builder and choose the file from the pop-up menu.

Handling Toolbar Items

The global page is the ideal place for the logic that handles toolbar items. You can also put the logic in an extension bar, but since the logic doesn’t need to be loaded on a per-window basis and doesn’t need any display space, it usually belongs in a global page.

To handle toolbar items, add a listener function for “command” events in your global page. Have the listener function test the event name to see if it is the name of the command you specified for the toolbar item in Extension Builder. If the event name is your command name, the user has clicked your toolbar item and you should execute the command.

If there is any possibility that the toolbar item should be disabled, add a listener function for the “validate” function as well. If the event name is the same as your command name, determine whether the toolbar item should be disabled. If so, set event.target.disabled = true.

For details and examples, see “Adding Buttons to the Main Safari Toolbar.”

Handling Contextual Menu Items

The global page is also the ideal place for the logic that handles contextual menu items. Again, you can put the logic in an extension bar, but since the logic doesn’t need to be loaded on a per-window basis and it doesn’t need any display space, it usually belongs in a global page.

To handle contextual menu items, add a listener function for “command” events in your global page. Have the listener function test the event name to see if it is the name of the command you specified for the contextual menu item in Extension Builder. If the event name is your command name, the user has chosen your contextual menu item and you should execute the command.

If there is any possibility that the contextual menu item should not be displayed, add a listener function for the “validate” function as well. If the event name is the same as your command name, determine whether the contextual menu item should be displayed. If not, set event.target.disabled = true.

If you need to obtain information from the webpage, such as the element that was clicked to initiate the contextual menu, you can add event listeners for the “contextmenu” event in the global page and an injected script. The script’s listener is called first, and can set pass information to the global page.

For details and examples, see “Adding Contextual Menu Items.”

Support Logic for Extension Bars

Functions and global variables declared in the global page can be accessed directly from extension bars, as properties of safari.extension.globalPage.contentWindow. So, for example, if you define a myCalc() function in your global page, you can call it from an extension bar using safari.extension.globalPage.contentWindow.myCalc().

To simplify things, declare a constant in your extension bar such as:

const myGlobal = safari.extension.globalPage.contentWindow;

You can then access the myCalc() function from your extension var using myGlobal.myCalc().

The global page has access to the same API as an extension bar, so it can do all the same things, except that it has no visible display area of its own. Consequently, it’s easy to move large chunks of code from an extension bar to your global page. The following Listing 5-1, shows how.

This is an example of an extension bar that has a button. Clicking the button performs a simple calculation.

Listing 5-1  Moving logic to your global page

<!DOCTYPE HTML>
<html>
<head>
   <title>old extension bar page</title>
   <script type="text/javascript">
 
   var theAnswer = 0;
    function calcThis(x) {
       x++;
       theAnswer = x;
    }
 
    function doButton() {
       calcThis(theAnswer);
       var mButton = document.getElementById("myButton");
       mButton.value = ("Increment " + theAnswer);
    }
   </script>
</head>
<body>
   <input type="button" value="Increment 0"
    onclick="doButton();" id="myButton" >
</body>
</html>

Here’s a version of the same extension bar, with the calculation moved to the global page. The code exported to the global file is unchanged. A constant is defined in the extension bar and prepended to anything called in the global file.

<!DOCTYPE HTML>
<html>
<head>
   <title>global page</title>
   <script type="text/javascript">
 
    var theAnswer = 0;
    function calcThis(x) {
      x++;
      theAnswer = x;
    }
 
   </script>
</head>
<body> </body>
</html>
 
<!DOCTYPE HTML>
<html>
<head>
   <title>extension bar page</title>
   <script type="text/javascript">
 
   const myGlobal = safari.extension.globalPage.contentWindow;
 
   function doButton() {
     myGlobal.calcThis(myGlobal.theAnswer);
     var mButton = document.getElementById("myButton");
     mButton.value = ("Increment " + myGlobal.theAnswer);
    }
 
   </script>
</head>
<body>
   <input type="button" value="Increment 0"
    onclick="doButton();" id="myButton" >
</body>
</html>

You can also make function calls from the global page into an extension bar. Calling functions in this direction is slightly more complex. There is one instance of the extension bar and all its functions per open window. Your global page needs to identify which instance it wants to access, or iterate through them to access them all.

For example, the following snippet iterates through the extension bars and calls the doSomething() function defined in each one, but calls the doSomethingSpecial() function only in the active window’s extension bar:

const myBars = safari.extension.bars;
function updateAllBars {
   for (var i = 0; i < myBars.length; ++i) {
       var barWindow = myBars[i].contentWindow;
       barWindow.doSomething();
       var myWindow = safari.application.activeBrowserWindow;
       if (myBars[i].browserWindow == myWindow)
         {
          barWindow.doSomethingSpecial();
         }
    }
}

Support Logic for Injected Scripts

JavaScript functions and variables in your global page cannot be called directly from injected scripts, but injected scripts can send messages that trigger functions in the global page, and the global page can send messages to injected scripts that trigger functions or contain the result of calculations.

For details and examples, see “Messages and Proxies” and

Working with Windows and Tabs

Note: Be sure to set your extension‚Äôs website access to Some or All in Extension Builder before working with tabs‚Äîmost tab properties return undefined unless your extension has access to the domain of the URL loaded in the tab.

The global HTML page itself is not displayed, but it can open windows and tabs and use them to display content. The standard window.open() method cannot be used to open a new tab and widow from the global HTML page, however. Instead, the global page has access to the SafariApplication, SafariBrowserWindow, and SafariBrowserTab classes, which allow you to open, close, activate and manipulate windows and tabs.

For example, this opens a window and returns the active tab:

var newTab = safari.application.openBrowserWindow().activeTab;

For details, see “The Windows and Tabs API”




Last updated: 2010-08-03

Did this document help you? Yes It's good, but... Not helpful...