зеркало из https://github.com/mozilla/kitsune.git
[bug 1097168] AAQ - Use about:support API when available.
This commit is contained in:
Родитель
7ceade3307
Коммит
58ad020ed5
|
@ -32,3 +32,32 @@ the heavy lifting of providing automatic updates.
|
|||
|
||||
.. _on Github: https://github.com/0c0w3/troubleshooter
|
||||
.. _on AMO: https://addons.mozilla.org/en-US/firefox/addon/troubleshooter/
|
||||
|
||||
|
||||
about:support API
|
||||
-----------------
|
||||
|
||||
The about:support API replaces the Troubleshooter Add-on and is available
|
||||
starting in Firefox 35. To test this locally during development, you need
|
||||
to run an ssl server and change some permissions in your browser.
|
||||
|
||||
To run the ssl server, first add sslserver to INSTALLED_APPS in
|
||||
settings_local.py::
|
||||
|
||||
INSTALLED_APPS = list(INSTALLED_APPS) + ['sslserver']
|
||||
|
||||
Run the ssl server::
|
||||
|
||||
$ ./manage.py runsslserver
|
||||
|
||||
Then you need to run the following in the Browser Console:
|
||||
|
||||
Services.perms.add(Services.io.newURI("https://localhost:8000", null, null), "remote-troubleshooting", Services.perms.ALLOW_ACTION);
|
||||
|
||||
|
||||
.. Note::
|
||||
|
||||
You need to Enable chrome debugging in developer console settings,
|
||||
so that you can access the browser console.
|
||||
|
||||
See also https://developer.mozilla.org/en-US/docs/Tools/Browser_Console
|
||||
|
|
|
@ -182,6 +182,7 @@ MINIFY_BUNDLES = {
|
|||
'js/markup.js',
|
||||
'js/ajaxvote.js',
|
||||
'js/ajaxpreview.js',
|
||||
'js/remote.js',
|
||||
'js/aaq.js',
|
||||
'js/questions.js',
|
||||
'js/libs/jquery.tokeninput.js',
|
||||
|
|
|
@ -187,43 +187,51 @@
|
|||
|
||||
|
||||
{% macro troubleshooting_instructions(field) %}
|
||||
<a href="{{ settings.TROUBLESHOOTER_ADDON_URL }}" class="btn btn-important" id="install-troubleshooting-addon">
|
||||
{{ _('Automatically add') }}
|
||||
</a>
|
||||
<p class="help-text">{{ field.help_text|safe }}</p>
|
||||
<p id="troubleshooting-manual">
|
||||
{% trans url='#troubleshooting-help,#troubleshooting-field' %}
|
||||
A window will open in the top corner. Click Allow, and then click
|
||||
Install. If the automated way doesn't work,
|
||||
<a class="expander" href="{{ url }}">try these manual steps</a>.
|
||||
{% endtrans %}
|
||||
</p>
|
||||
<span id="troubleshooting-explanation" class="cf">
|
||||
{{ _('This field was populated automatically with the add-on called <em>Troubleshooter</em>.') }}
|
||||
<div id="addon-section">
|
||||
<a href="{{ settings.TROUBLESHOOTER_ADDON_URL }}" class="btn btn-important" id="add-troubleshooting-info">
|
||||
{{ _('Automatically add') }}
|
||||
</a>
|
||||
<p class="help-text">{{ field.help_text|safe }}</p>
|
||||
<p id="troubleshooting-manual">
|
||||
{% trans url='#troubleshooting-help,#troubleshooting-field' %}
|
||||
A window will open in the top corner. Click Allow, and then click
|
||||
Install. If the automated way doesn't work,
|
||||
<a class="expander" href="{{ url }}">try these manual steps</a>.
|
||||
{% endtrans %}
|
||||
</p>
|
||||
<ol id="troubleshooting-help">
|
||||
<li>{{ _('Open <em>Help > Troubleshooting Information</em>.') }}
|
||||
<ul>
|
||||
<li>{{ _('Look at the top of your screen, and click the menu item called <em>Help</em>.') }}</li>
|
||||
<li>{{ _('A small box will open. Click on an item called <em>Troubleshooting Information</em>.') }}</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li>{{ _('A new window will open. Click on a button called <em>Copy text to clipboard</em>.') }}</li>
|
||||
<li>{{ _('Paste the info in the text box below.') }}
|
||||
<ul>
|
||||
<li>{{ _('Click on the empty box above this text.') }}</li>
|
||||
<li>{{ _('Look at the top of your screen, and click the menu item called <em>Edit</em>.') }}</li>
|
||||
<li>
|
||||
{% trans %}
|
||||
A small box will open. Click on the item called <em>Paste</em>.
|
||||
Alternatively, type <em>Ctrl+V</em> or <em>Command+V</em>.
|
||||
{% endtrans %}
|
||||
</li>
|
||||
<li>{{ _('Some text will appear in the empty box.') }}</li>
|
||||
</ul>
|
||||
</li>
|
||||
</ol>
|
||||
</div>
|
||||
<div id="api-section">
|
||||
<a href="#" class="btn btn-important" id="share-data">
|
||||
{{ _('Share Data') }}
|
||||
</a>
|
||||
<p class="help-text">{{ _('This information gives details about the internal workings of your browser that will help in answering your question.') }}</p>
|
||||
</div>
|
||||
<p id="troubleshooting-explanation" class="cf">
|
||||
{{ _('This field was populated automatically.') }}
|
||||
<a href="#troubleshooting-field" class="expander">{{ _('See the data') }}</a>.
|
||||
</span>
|
||||
<ol id="troubleshooting-help">
|
||||
<li>{{ _('Open <em>Help > Troubleshooting Information</em>.') }}
|
||||
<ul>
|
||||
<li>{{ _('Look at the top of your screen, and click the menu item called <em>Help</em>.') }}</li>
|
||||
<li>{{ _('A small box will open. Click on an item called <em>Troubleshooting Information</em>.') }}</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li>{{ _('A new window will open. Click on a button called <em>Copy text to clipboard</em>.') }}</li>
|
||||
<li>{{ _('Paste the info in the text box below.') }}
|
||||
<ul>
|
||||
<li>{{ _('Click on the empty box above this text.') }}</li>
|
||||
<li>{{ _('Look at the top of your screen, and click the menu item called <em>Edit</em>.') }}</li>
|
||||
<li>
|
||||
{% trans %}
|
||||
A small box will open. Click on the item called <em>Paste</em>.
|
||||
Alternatively, type <em>Ctrl+V</em> or <em>Command+V</em>.
|
||||
{% endtrans %}
|
||||
</li>
|
||||
<li>{{ _('Some text will appear in the empty box.') }}</li>
|
||||
</ul>
|
||||
</li>
|
||||
</ol>
|
||||
</p>
|
||||
<p id="troubleshooting-field">
|
||||
{{ field }}
|
||||
</p>
|
||||
|
|
|
@ -49,11 +49,6 @@ AAQSystemInfo.prototype = {
|
|||
$(selector).fadeToggle();
|
||||
});
|
||||
|
||||
$('#troubleshooting-install .btn').on('click', function(ev) {
|
||||
// Do not prevent default.
|
||||
$(this).toggleClass('btn-important btn-disable').html(gettext('Installing...'));
|
||||
});
|
||||
|
||||
$('#show-login a').on('click', function(ev) {
|
||||
$('#login-form').show();
|
||||
$(this).remove();
|
||||
|
@ -153,38 +148,66 @@ AAQSystemInfo.prototype = {
|
|||
},
|
||||
getTroubleshootingInfo: function(addEvent) {
|
||||
var self = this;
|
||||
var browserData;
|
||||
|
||||
if (addEvent === undefined) addEvent = true;
|
||||
// If the troubleshoot input exists, try to find the extension.
|
||||
|
||||
// If the troubleshoot input exists, try to get the data.
|
||||
if ($('#id_troubleshooting').length === 0) {
|
||||
// No troubleshooting form, so no point in looking for the plugin.
|
||||
// No troubleshooting form, so no point in trying to get the data.
|
||||
return;
|
||||
}
|
||||
if ('mozTroubleshoot' in window) {
|
||||
// Yeah! The user has the addon installed, let's use it.
|
||||
$('#troubleshooting-install').remove();
|
||||
window.mozTroubleshoot.snapshotJSON(function(json) {
|
||||
// Parse the JSON, so we can modify it.
|
||||
json = JSON.parse(json);
|
||||
var modifiedPreferences = json.modifiedPreferences;
|
||||
json.modifiedPreferences = {};
|
||||
for (var key in modifiedPreferences) {
|
||||
if (key.indexOf('print.') !== 0) {
|
||||
json.modifiedPreferences[key] = modifiedPreferences[key];
|
||||
|
||||
// First we try to use the builtin API:
|
||||
remoteTroubleshooting.available(function (yesno) {
|
||||
if (yesno) {
|
||||
remoteTroubleshooting.getData(function (data) {
|
||||
browserData = data;
|
||||
});
|
||||
|
||||
$('#addon-section').remove();
|
||||
$('#share-data')
|
||||
.click(function(e) { // The user must click button to save the data.
|
||||
e.preventDefault();
|
||||
handleData(browserData);
|
||||
return false;
|
||||
});
|
||||
|
||||
} else {
|
||||
$('#api-section').remove();
|
||||
|
||||
// If the builtin API isn't available, we try with the addon.
|
||||
if ('mozTroubleshoot' in window) {
|
||||
// Yeah! The user has the addon installed, let's use it.
|
||||
window.mozTroubleshoot.snapshotJSON(function(json) {
|
||||
handleData(JSON.parse(json));
|
||||
});
|
||||
} else {
|
||||
if (addEvent) {
|
||||
// Well, the user might install it later, so set up a listener.
|
||||
window.addEventListener('mozTroubleshootDidBecomeAvailable',
|
||||
self.getTroubleshootingInfo.bind(self, false));
|
||||
}
|
||||
}
|
||||
// The last two parameters cause this to pretty print,
|
||||
// in case anyone looks at it.
|
||||
json = JSON.stringify(json, null, " ");
|
||||
$('#id_troubleshooting').val(json);
|
||||
$('#troubleshooting-manual').remove();
|
||||
$('#troubleshooting-explanation').show();
|
||||
});
|
||||
} else {
|
||||
if (addEvent) {
|
||||
// Well, the user might install it later, so set up a listener.
|
||||
window.addEventListener('mozTroubleshootDidBecomeAvailable',
|
||||
self.getTroubleshootingInfo.bind(self, false));
|
||||
}
|
||||
});
|
||||
|
||||
// Handle the troubleshooting JSON data.
|
||||
function handleData(data) {
|
||||
var modifiedPreferences = data.modifiedPreferences;
|
||||
data.modifiedPreferences = {};
|
||||
for (var key in modifiedPreferences) {
|
||||
if (key.indexOf('print.') !== 0) {
|
||||
data.modifiedPreferences[key] = modifiedPreferences[key];
|
||||
}
|
||||
}
|
||||
// The last two parameters cause this to pretty print,
|
||||
// in case anyone looks at it.
|
||||
data = JSON.stringify(data, null, " ");
|
||||
$('#addon-section').remove();
|
||||
$('#api-section').remove();
|
||||
$('#id_troubleshooting').val(data);
|
||||
$('#troubleshooting-explanation').show();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
|
|
@ -0,0 +1,116 @@
|
|||
window.remoteTroubleshooting = window.remoteTroubleshooting || {};
|
||||
|
||||
(function(window, remoteTroubleshooting) {
|
||||
'use strict';
|
||||
|
||||
var data;
|
||||
|
||||
/**
|
||||
* Async method for retrieving remote-troubleshooting data.
|
||||
*
|
||||
* Tries to console.log problems to help diagnose issues.
|
||||
*
|
||||
* @param {function} callback - Callback function to call when
|
||||
* the data arrives. It should take a single argument which
|
||||
* will be the data packet.
|
||||
*
|
||||
* @param {integer} timeout - Timeout in milliseconds for calling
|
||||
* the callback with {} if the event hasn't yet gotten dispatched.
|
||||
* Defaults to 1000 ms (aka 1 second).
|
||||
*
|
||||
* @returns {object} with data in it or {}
|
||||
*/
|
||||
remoteTroubleshooting.getData = function(callback, timeout) {
|
||||
var timeoutId;
|
||||
|
||||
// If we've already gotten the data, return that.
|
||||
if (data) {
|
||||
window.setTimeout(function() { callback(data); });
|
||||
return;
|
||||
}
|
||||
|
||||
// If the browser is missing certain features, then asking for
|
||||
// remote-troubleshooting data is moot, so just drop out as
|
||||
// soon as we know important things are missing.
|
||||
if (!window.addEventListener) {
|
||||
// console.log('remoteTroubleshooting: browser does not support addEventListener');
|
||||
data = {};
|
||||
window.setTimeout(function() { callback(data); });
|
||||
return;
|
||||
}
|
||||
|
||||
if (!(window.hasOwnProperty('CustomEvent') && typeof window.CustomEvent == 'function')) {
|
||||
// console.log('remoteTroubleshooting: browser does not support CustomEvent');
|
||||
data = {};
|
||||
window.setTimeout(function() { callback(data); });
|
||||
return;
|
||||
}
|
||||
|
||||
timeout = timeout || 1000;
|
||||
|
||||
/**
|
||||
* If the interval passes and the event listener hasn't kicked off then
|
||||
* there's nothing listening, so we abort.
|
||||
*/
|
||||
function eject() {
|
||||
// console.log('remoteTroubleshooting: interval ' + timeout + ' has passed.');
|
||||
data = {};
|
||||
callback(data);
|
||||
}
|
||||
|
||||
// Listen to the WebChannelMessageToContent event and handle
|
||||
// incoming remote-troubleshooting messages.
|
||||
window.addEventListener("WebChannelMessageToContent", function (e) {
|
||||
// FIXME: handle failure cases
|
||||
if (e.detail.id === "remote-troubleshooting") {
|
||||
window.clearTimeout(timeoutId);
|
||||
|
||||
data = e.detail.message;
|
||||
if (data === undefined) {
|
||||
// console.log('remoteTroubleshooting: data is {}. ' +
|
||||
// 'permission error? using http instead of https?');
|
||||
data = {};
|
||||
}
|
||||
|
||||
window.setTimeout(function() { callback(data); });
|
||||
}
|
||||
});
|
||||
|
||||
// Create the remote-troubleshooting event requesting data and
|
||||
// kick it off.
|
||||
var event = new window.CustomEvent("WebChannelMessageToChrome", {
|
||||
detail: {
|
||||
id: "remote-troubleshooting",
|
||||
message: {
|
||||
command: "request"
|
||||
}
|
||||
}
|
||||
});
|
||||
window.dispatchEvent(event);
|
||||
timeoutId = window.setTimeout(eject, timeout);
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns whether or not the remote-troubleshooting data is
|
||||
* available.
|
||||
*
|
||||
* @param {function} callback - Callback function to call when
|
||||
* the data arrives. It should take a single argument which
|
||||
* will be the data packet.
|
||||
*
|
||||
* @param {integer} timeout - Timeout in milliseconds for calling
|
||||
* the callback with {} if the event hasn't yet gotten dispatched.
|
||||
* Defaults to 1000 ms (aka 1 second).
|
||||
*
|
||||
* @returns {bool} true if it's available, false if it isn't
|
||||
*/
|
||||
remoteTroubleshooting.available = function(callback, timeout) {
|
||||
remoteTroubleshooting.getData(function (data) {
|
||||
// FIXME: This relies on the fact that 'application' is a
|
||||
// valid key with data in it. If it's not then, this will
|
||||
// be wrong.
|
||||
callback(!!data.application);
|
||||
}, timeout);
|
||||
};
|
||||
|
||||
}(window, window.remoteTroubleshooting));
|
|
@ -1330,12 +1330,9 @@ h2 {
|
|||
}
|
||||
}
|
||||
|
||||
#troubleshooting-install {
|
||||
margin: 10px 0;
|
||||
}
|
||||
|
||||
#troubleshooting-manual,
|
||||
#troubleshooting-explanation {
|
||||
clear: both;
|
||||
font-size: 13px;
|
||||
margin: 10px 0;
|
||||
}
|
||||
|
@ -1625,7 +1622,7 @@ div.ans-attachments {
|
|||
}
|
||||
|
||||
.edit-question {
|
||||
#troubleshooting-install,
|
||||
#add-troubleshooting-info,
|
||||
#troubleshooting-manual {
|
||||
display: none;
|
||||
}
|
||||
|
@ -1732,3 +1729,7 @@ div.ans-attachments {
|
|||
.content-raw {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.help-text {
|
||||
clear: both;
|
||||
}
|
||||
|
|
|
@ -17,3 +17,6 @@ http://people.mozilla.org/~wkahngreene/pep8/pep8-1.6.0a0-willkg.1.tar.gz#egg=pep
|
|||
|
||||
# sha256: P6gKELNtUWhr93RPXcmWIs1cmM6O1kAi5imGiq_Bd2k
|
||||
pyflakes==0.8.1
|
||||
|
||||
# sha256: Y6KG6ssDzV9kPX60WMbGK3DBEbRjT9jVnyfMrKS3yDo
|
||||
django-sslserver==0.14
|
||||
|
|
Загрузка…
Ссылка в новой задаче