WebAPI/BrowserAPI: Difference between revisions

no edit summary
No edit summary
No edit summary
 
(42 intermediate revisions by 5 users not shown)
Line 1: Line 1:
= Browser Element & API =
= Browser Element & API =


This is a proposal for Browser API and a new HTML element called "<browser>", which is similar to an iframe but allows the implementation of a fully featured web browser as a web app.
This is a proposal for a Browser API and a new HTML element called "<browser>" or "<webview>", which is similar to an iframe but allows the implementation of a fully featured web browser as a web app.


This feature is being tracked by the meta-bug {{bug|693515}} (alias browser-as-webapp).
This feature is being tracked by the meta-bug {{bug|693515}} (alias browser-api).


This is similar to the [https://developer.mozilla.org/en/XUL/browser XUL browser element].
This is similar to the [https://developer.mozilla.org/en/XUL/browser XUL browser element].
== Roadmap ==
* P1
** {{In progress|}} Nested OOP {{bug|nested-oop}}
** State/Session restore {{bug|1033999}}
** Navigation scope
*** User stories: {{bug|996039}}, {{bug|972320}}, {{bug|1023803}}
*** Reference: https://github.com/w3c/manifest/issues/114
** {{In progress|}} Hardware key events {{bug|989198}}
** Fine-grained visilibity API {{bug|1034001}} (e.g. <code>setVisible(bool)</code> -> <code>setVisible({state: bool, rendering: bool, normalpriority: bool })</code>)
* P2
** <iframe mozbrowser> to <webview> {{bug|738172}}
** Rewrite some browser API using C++
* P3
** Dialog API (http auth, alert, etc)
** OOM Priority API
* P4
** Clean up existing functions
** Password management
** Freeze process
* P5
** Metadata API
* Related
** {{In progress|}} {{Pl|WebAPI/WidgetAPI|WidgetAPI|}} embed-widgets permission and mozwidget attribute {{bug|1005818}}


== Summary ==
== Summary ==
New HTML tag name "<browser>" {{bug|738172}}


{| border="1"
{{Note|Please find the current document on MDN https://developer.mozilla.org/en-US/docs/WebAPI/Browser}}
 
{| class="wikitable"
|+Attributes
|+Attributes
|-
|-
! Name !! Priority !! Bug !! Status
! Name !! Priority !! Bug !! Status
|-
|-
|src || P1 || || IMPLEMENTED
|src || P1 || || {{implemented|}}
|}
|}


{| border="1"
{| class="wikitable"
|+ Methods
|+ Methods
|-
|-
! Name !! Priority !! Bug !! Status
! Name !! Priority !! Bug !! Status
|-
|-
|go || P2 || || NOT STARTED
|go || || || '''not started'''
|-
|stop || P1 || {{bug|709759}} || NOT STARTED
|-
|-
|reload || P2 || {{bug|741717}} || NOT STARTED
|stop || P1 || {{bug|709759}} || {{implemented|}}
|-
|-
|goBack || P2 || || NOT STARTED
|reload || P2 || {{bug|741717}} || {{implemented|}}
|-
|-
|goForward || P2 || || NOT STARTED
|go{Back,Forward}, canGo{Back,Forward} || P2 || {{bug|741755}} || {{implemented|}}
|-
|-
|canGoBack || P2 || {{bug|741755}} || NOT STARTED
|getScreenshot || P1 || {{bug|753595}} || {{implemented|}}
|-
|-
|canGoForward || P2 || {{bug|741755}} || NOT STARTED
|getContentDimensions || || {{bug|757859}} || {{implemented|}}
|-
|-
|getScreenshot || P1 || || IN PROGRESS
|setVisible || || {{bug|702880}}, {{bug|762939}} || {{implemented|}}
|}
|}


{| border="1"
{| class="wikitable"
|+Events
|+Events
|-
|-
! Name !! Priority !! Bug !!Status
! Name !! Priority !! Bug !!Status
|-
|-
|loadstart || P1 || || IMPLEMENTED
|loadstart || P1 || || {{implemented|}}
|-
|loadend || P1 || || {{implemented|}}
|-
|loadprogress || || || '''not started'''
|-
|locationchange || P1 || || {{implemented|}}
|-
|-
|loadend || P1 || || IMPLEMENTED
|titlechange || P1 || || {{implemented|}}
|-
|-
|loadprogress || P3 || || NOT STARTED
|iconchange || P1 || {{bug|719461}} || {{implemented|}}
|-
|-
|locationchange || P1 || || IMPLEMENTED
|alert/prompt/confirm || P1 || {{bug|741587}} || {{implemented|}}
|-
|-
|titlechange || P1 || || IMPLEMENTED
|open || P1 || {{bug|742944}} || {{implemented|}}
|-
|-
|iconchange || P1 || {{bug|719461}} || IMPLEMENTED
|close || P1 || {{bug|757182}} || {{implemented|}}
|-
|-
|alert || P1 || {{bug|741587}} || IN PROGRESS
|securitychange || P1 || {{bug|763694}} || {{implemented|}}
|-
|-
|confirm || P1 || {{bug|741587}} || IN PROGRESS
|contextmenu || P1 || {{bug|756371}} || {{implemented|}}
|-
|-
|prompt || P1 || {{bug|741587}} || IN PROGRESS
|error || || {{bug|768842}} || {{implemented|}}
|-
|-
|open || P1 || {{bug|742944}} || IN PROGRESS
|error:fatal || || {{bug|766437}} || {{implemented|}}
|-
|-
|close || P1 || {{bug|742944}} || IN PROGRESS
|scroll || P1 || {{bug|770847}} || {{implemented|}}
|-|securitychange || P1 || || NOT STARTED
|}
|}


{| border="1"
{| class="wikitable"
|+Other Features
|+Other Related Features (not all necessarily part of Browser API)
|-
|-
! Name !! Priority !! Bug !! Status
! Name !! Priority !! Bug !! Status
|-
|-
|Process separation || P1 || || IN PROGRESS
|Process separation || P1 || {{bug|714861}} || {{implemented|}}
|-
|-
|Framebusting protection || P1 || || IN PROGRESS (implemented but needs improvement)
|Framebusting protection || P1 || {{bug|771273}} || {{implemented|}}
|-
|-
|Touch pan & zoom || P1 || || IN PROGRESS
|Touch pan & zoom || P1 || {{bug|745136}} || {{implemented|}}
|-
|-
|Viewport || P2 || || NOT STARTED
|<meta name="viewport"> tags || P2 || {{bug|746502}} || {{implemented|}}
|-
|-
|Hyperlink targets || P2 || || NOT STARTED
|target=_blank/_top || P2 || {{bug|769254}} || {{implemented|}}
|-
|-
|Context menu || P1 || || NOT STARTED
|Permissions prompts || P1 || || {{implemented|}}
|-
|Clear private data || P1 || || {{implemented|}}
|-
|Turn cookies on/off ||  || || '''not started'''
|-
|<select> popups || P1 || {{bug|759511}} || {{implemented|}}
|}
|}


== Attributes ==
== Example implementation ==
 
'''src'''
 
: The URI of the content to appear in the element.
 
== Methods ==
'''go(URI)'''
 
: Navigate to the URI provided.
 
'''stop()'''
 
: Stop the content from loading. Used by a stop button in a browser app.
 
'''reload()'''
 
: Reload the content in the browser. Used by a refresh button in a browser app. We may in future need other versions of this method (e.g. to bypass the browser cache and do a hard reload).
 
'''goBack()'''
 
: Navigates back one step in the session history. Could have success/failure reported in a callback but this isn't essential. Used by a back button in a browser app.
 
'''goForward()'''
 
: Navigates forward one step in the session history. Could have success/failure reported in a callback but this isn't essential. Used by a forward button in a browser app.
 
'''canGoBack(callback)'''
 
: Tells the app whether there is a history item in the session history to navigate back to. Should return a boolean true or false in a callback. Used by a browser app to decide whether to display a back button.
 
 
'''canGoForward(callback)'''
 
: Tells the app whether there is a history item in the session history to navigate forward to. Should return a boolean true or false in a callback. Used by a browser app to decide whether to display a forward button.
 
 
'''getThumbnail(callback)'''
 
: Generates a thumbnail of the content currently displayed in the browser element. The thumbnail should be returned to the callback as a binary blob, in addition to the URL it corresponds to. This could be used by a browser app to save visual bookmark or history information or as visual information to help in switching between tabs.
 
== Events ==
Events which are fired by a browser element.
 
'''loadstart'''
 
: Indicates that the element started loading content. Used by a browser app to show a loading indicator.
 
'''loadend'''
 
: Indicates that the element finished loading content. Used by a browser app to hide a loading indicator.
 
'''loadprogress'''
 
: Provides an estimate of the percentage of a page loaded. This is tricky but is better for browser apps to provide a determinate rather than indeterminate progress indicator.
 
'''locationchange'''
 
: Indicates that the URI changed, the URI is included as a string in the event payload.
 
'''titlechange'''
 
: Indicates that the title of the page changed, the title is included as a string in the event payload.
 
'''iconchange'''
 
: Indicates the favicon URL of the page changed, the URL of the favicon is included as a string in the event payload.
 
'''alert'''
 
: Indicates that the content requested an alert dialog to be displayed. Used by a browser app to display alerts.
 
'''confirm'''
 
: Indicates that the content requested a confirmation dialog to be displayed. Used by a browser app to display confirmation dialogs.
 
'''prompt'''
 
: Indicates that the content requested a prompt dialog to be displayed. Used by a browser app to display prompt dialogs.
 
'''open'''
 
: Indicates that the content requested a new window to be opened. Used by a browser app to open a new window/tab.
 
'''close'''
 
: Indicates that the content requested the current window to be closed. Used by a browser app to close a window/tab.
 
'''securitychange'''
 
: Indicates that the security status (secure or not) of a web page changed. Not sure how this should work, should we provide all the security details (e.g. SSL or not, certificate) in the event payload or add a getSecurityInfo() method for this?
 
== Other Features ==
'''Process separation'''
 
: Each browser element should be capable of running in its own system process.
 
'''Framebusting protection'''
 
: A browser element should ignore X-Frame-Options HTTP headers and act as a window.top boundary in order to prevent web sites from frame-busting.
 
'''Touch pan & zoom'''


: Users of touch-based devices should be able to zoom with pinch to zoom, zoom in on an element by double-tapping it and pan around the page by dragging their finger across the screen.
This is a minimal implementation of a browser.  When it's complete, it will
exercise the full surface area of the API.


'''Viewport'''
''This code is completely untested at the moment.''


: Should support viewport meta tags to allow web sites to define how they want to be displayed on screens with different pixel densities.
=== HTML ===


'''Hyperlink targets'''
  &lt;div&gt;&lt;span id='location-bar'&gt;&lt;/span&gt; &lt;button onclick='go_button_clicked()'&gt;Go&lt;/button&gt;&lt;/div&gt;
  &lt;div id='load-status'&gt;&lt;/div&gt;
  &lt;div id='security-status'&gt;&lt;/div&gt;
  &lt;img id='favicon'&gt;
  &lt;div id='title'&gt;&lt;/div&gt;
  &lt;iframe mozbrowser id='browser'&gt;&lt;/iframe&gt;


: Open <a target="_top"> and <a target="_blank"> in a new window.
=== JS ===


'''Context menu'''
  function $(id) {
    return document.getElementById(id);
  }
 
  let iframe = $('browser');
 
  iframe.addEventListener('mozbrowserloadstart', function(e) {
    $('load-status').innerText = 'loading...';
  });
 
  iframe.addEventListener('mozbrowserloadend', function(e) {
    $('load-status').innerText = 'done loading';
  });
 
  iframe.addEventListener('mozbrowserlocationchange', function(e) {
    $('location-bar').innerText = e.detail;
  });
 
  iframe.addEventListener('mozbrowsertitlechange', function(e) {
    $('title').innerText = e.detail;
  });
 
  iframe.addEventListener('mozbrowsericonchange', function(e) {
    $('favicon').src = e.detail;
  });
 
  iframe.addEventListener('mozbrowsersecuritychange', function(e) {
    // 'secure', 'insecure', or 'broken'.  'broken' indicates mixed content.
    $('security-status').innerText = e.detail.state;
   
    // There's also e.detail.extendedValidation (boolean), but this will be
    // false until bug 764496 is fixed.
  });
 
  iframe.addEventListener('mozbrowsercontextmenu', function(e) {
    // TODO
  });
 
  iframe.addEventListener('mozbrowsererror', function(e) {
    switch (e.detail.type) {
    case 'other':
      // Something has gone wrong -- we're probably displaying a Gecko error
      // page, e.g. "no network connection" or "invalid SSL cert".  You
      // probably don't need to do anything here.
      break;
    case 'fatal':
      // The tab crashed.  Not implemented yet; see bug 766437.
      break;
    }
  });
 
  iframe.addEventListener('mozbrowserkeyevent', function(e) {
    // TODO.  You probably don't care about this event.
  });
 
  iframe.addEventListener('mozbrowsershowmodalprompt', function(e) {
    // TODO
  });
 
  iframe.addEventListener('mozbrowseropenwindow', function(e) {
    // TODO
  });
 
  iframe.addEventListener('mozbrowserclose', function() {
    // This is really only meaningful for popup windows.
    document.body.removeChild(iframe);
  });
 
  function go_button_clicked() {
    iframe.src = $('location-bar').value;
  }
 
  // TODO:
  //  * getCanGoBack
  //  * getCanGoForward
  //  * goBack
  //  * goForward
  //  * setVisible
  //  * getScreenshot


: Some method of providing a context menu ("open in new tab" etc.), e.g. with a long press.
== Draft Specification ==


== Other Comments ==
Other browser vendors have implementations of a similar API (e.g. [https://developer.chrome.com/apps/tags/webview Chrome]). An early draft proposal for a standardised <webview> element and associated API can be found [http://benfrancis.github.io/webview/ here]. Please provide feedback in the issue tracker [https://github.com/benfrancis/webview/issues here].


Other features that could be required in the future:
[[Category:Web APIs]]
* Find in page
* Download manager
* View source
Confirmed users
1,340

edits