зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1025000 - move runtime details and permissions table inside webide. r=jryans
This commit is contained in:
Родитель
a479270d5c
Коммит
116c1bd804
|
@ -13,15 +13,17 @@ window.addEventListener("load", function onLoad() {
|
|||
document.querySelector("#aboutaddons").onclick = function() {
|
||||
window.parent.UI.openInBrowser("about:addons");
|
||||
}
|
||||
document.querySelector("#close").onclick = function() {
|
||||
window.parent.UI.closeLastDeckPanel();
|
||||
}
|
||||
document.querySelector("#close").onclick = CloseUI;
|
||||
GetAvailableAddons().then(BuildUI, (e) => {
|
||||
console.error(e);
|
||||
window.alert(Strings.formatStringFromName("error_cantFetchAddonsJSON", [e], 1));
|
||||
});
|
||||
}, true);
|
||||
|
||||
function CloseUI() {
|
||||
window.parent.UI.openProject();
|
||||
}
|
||||
|
||||
function BuildUI(addons) {
|
||||
BuildItem(addons.adb, true /* is adb */);
|
||||
for (let addon of addons.simulators) {
|
||||
|
|
|
@ -19,7 +19,7 @@
|
|||
|
||||
<div id="controls">
|
||||
<a id="aboutaddons">&addons_aboutaddons;</a>
|
||||
<a id="close">&addons_close;</a>
|
||||
<a id="close">&deck_close;</a>
|
||||
</div>
|
||||
|
||||
<h1>&addons_title;</h1>
|
||||
|
|
|
@ -13,6 +13,10 @@ webide.jar:
|
|||
content/cli.js (cli.js)
|
||||
content/addons.js (addons.js)
|
||||
content/addons.xhtml (addons.xhtml)
|
||||
content/permissionstable.js (permissionstable.js)
|
||||
content/permissionstable.xhtml (permissionstable.xhtml)
|
||||
content/runtimedetails.js (runtimedetails.js)
|
||||
content/runtimedetails.xhtml (runtimedetails.xhtml)
|
||||
|
||||
# Temporarily include locales in content, until we're ready
|
||||
# to localize webide
|
||||
|
|
|
@ -0,0 +1,75 @@
|
|||
/* 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 Cu = Components.utils;
|
||||
const {Services} = Cu.import("resource://gre/modules/Services.jsm");
|
||||
const {require} = Cu.import("resource://gre/modules/devtools/Loader.jsm", {}).devtools;
|
||||
const {AppManager} = require("devtools/webide/app-manager");
|
||||
const {Connection} = require("devtools/client/connection-manager");
|
||||
|
||||
window.addEventListener("load", function onLoad() {
|
||||
window.removeEventListener("load", onLoad);
|
||||
document.querySelector("#close").onclick = CloseUI;
|
||||
AppManager.on("app-manager-update", OnAppManagerUpdate);
|
||||
BuildUI();
|
||||
}, true);
|
||||
|
||||
window.addEventListener("unload", function onUnload() {
|
||||
window.removeEventListener("unload", onUnload);
|
||||
AppManager.off("app-manager-update", OnAppManagerUpdate);
|
||||
});
|
||||
|
||||
function CloseUI() {
|
||||
window.parent.UI.openProject();
|
||||
}
|
||||
|
||||
function OnAppManagerUpdate(event, what) {
|
||||
if (what == "connection" || what == "list-tabs-response") {
|
||||
BuildUI();
|
||||
}
|
||||
}
|
||||
|
||||
let getRawPermissionsTablePromise; // Used by tests
|
||||
function BuildUI() {
|
||||
let table = document.querySelector("table");
|
||||
let lines = table.querySelectorAll(".line");
|
||||
for (let line of lines) {
|
||||
line.remove();
|
||||
}
|
||||
|
||||
if (AppManager.connection &&
|
||||
AppManager.connection.status == Connection.Status.CONNECTED &&
|
||||
AppManager.deviceFront) {
|
||||
getRawPermissionsTablePromise = AppManager.deviceFront.getRawPermissionsTable();
|
||||
getRawPermissionsTablePromise.then(json => {
|
||||
let permissionsTable = json.rawPermissionsTable;
|
||||
for (let name in permissionsTable) {
|
||||
let tr = document.createElement("tr");
|
||||
tr.className = "line";
|
||||
let td = document.createElement("td");
|
||||
td.textContent = name;
|
||||
tr.appendChild(td);
|
||||
for (let type of ["app","privileged","certified"]) {
|
||||
let td = document.createElement("td");
|
||||
if (permissionsTable[name][type] == json.ALLOW_ACTION) {
|
||||
td.textContent = "✓";
|
||||
td.className = "permallow";
|
||||
}
|
||||
if (permissionsTable[name][type] == json.PROMPT_ACTION) {
|
||||
td.textContent = "!";
|
||||
td.className = "permprompt";
|
||||
}
|
||||
if (permissionsTable[name][type] == json.DENY_ACTION) {
|
||||
td.textContent = "✕";
|
||||
td.className = "permdeny"
|
||||
}
|
||||
tr.appendChild(td);
|
||||
}
|
||||
table.appendChild(tr);
|
||||
}
|
||||
});
|
||||
} else {
|
||||
CloseUI();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,35 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
|
||||
<!-- 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/. -->
|
||||
|
||||
<!DOCTYPE html [
|
||||
<!ENTITY % webideDTD SYSTEM "chrome://webide/content/webide.dtd" >
|
||||
%webideDTD;
|
||||
]>
|
||||
|
||||
<html xmlns="http://www.w3.org/1999/xhtml">
|
||||
<head>
|
||||
<meta charset="utf8"/>
|
||||
<link rel="stylesheet" href="chrome://webide/skin/tabledoc.css" type="text/css"/>
|
||||
<script type="application/javascript;version=1.8" src="chrome://webide/content/permissionstable.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<div id="controls">
|
||||
<a id="close">&deck_close;</a>
|
||||
</div>
|
||||
|
||||
<h1>&permissionstable_title;</h1>
|
||||
|
||||
<table class="permissionstable">
|
||||
<tr>
|
||||
<th>&permissionstable_name_header;</th>
|
||||
<th>type:web</th>
|
||||
<th>type:privileged</th>
|
||||
<th>type:certified</th>
|
||||
</tr>
|
||||
</table>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,56 @@
|
|||
/* 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 Cu = Components.utils;
|
||||
const {Services} = Cu.import("resource://gre/modules/Services.jsm");
|
||||
const {require} = Cu.import("resource://gre/modules/devtools/Loader.jsm", {}).devtools;
|
||||
const {AppManager} = require("devtools/webide/app-manager");
|
||||
const {Connection} = require("devtools/client/connection-manager");
|
||||
|
||||
window.addEventListener("load", function onLoad() {
|
||||
window.removeEventListener("load", onLoad);
|
||||
document.querySelector("#close").onclick = CloseUI;
|
||||
AppManager.on("app-manager-update", OnAppManagerUpdate);
|
||||
BuildUI();
|
||||
}, true);
|
||||
|
||||
window.addEventListener("unload", function onUnload() {
|
||||
window.removeEventListener("unload", onUnload);
|
||||
AppManager.off("app-manager-update", OnAppManagerUpdate);
|
||||
});
|
||||
|
||||
function CloseUI() {
|
||||
window.parent.UI.openProject();
|
||||
}
|
||||
|
||||
function OnAppManagerUpdate(event, what) {
|
||||
if (what == "connection" || what == "list-tabs-response") {
|
||||
BuildUI();
|
||||
}
|
||||
}
|
||||
|
||||
let getDescriptionPromise; // Used by tests
|
||||
function BuildUI() {
|
||||
let table = document.querySelector("table");
|
||||
table.innerHTML = "";
|
||||
if (AppManager.connection &&
|
||||
AppManager.connection.status == Connection.Status.CONNECTED &&
|
||||
AppManager.deviceFront) {
|
||||
getDescriptionPromise = AppManager.deviceFront.getDescription();
|
||||
getDescriptionPromise.then(json => {
|
||||
for (let name in json) {
|
||||
let tr = document.createElement("tr");
|
||||
let td = document.createElement("td");
|
||||
td.textContent = name;
|
||||
tr.appendChild(td);
|
||||
td = document.createElement("td");
|
||||
td.textContent = json[name];
|
||||
tr.appendChild(td);
|
||||
table.appendChild(tr);
|
||||
}
|
||||
});
|
||||
} else {
|
||||
CloseUI();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,28 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
|
||||
<!-- 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/. -->
|
||||
|
||||
<!DOCTYPE html [
|
||||
<!ENTITY % webideDTD SYSTEM "chrome://webide/content/webide.dtd" >
|
||||
%webideDTD;
|
||||
]>
|
||||
|
||||
<html xmlns="http://www.w3.org/1999/xhtml">
|
||||
<head>
|
||||
<meta charset="utf8"/>
|
||||
<link rel="stylesheet" href="chrome://webide/skin/tabledoc.css" type="text/css"/>
|
||||
<script type="application/javascript;version=1.8" src="chrome://webide/content/runtimedetails.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<div id="controls">
|
||||
<a id="close">&deck_close;</a>
|
||||
</div>
|
||||
|
||||
<h1>&runtimedetails_title;</h1>
|
||||
|
||||
<table></table>
|
||||
</body>
|
||||
</html>
|
|
@ -399,8 +399,6 @@ let UI = {
|
|||
|
||||
/********** DECK **********/
|
||||
|
||||
_lastSelectedPanels: [],
|
||||
|
||||
resetFocus: function() {
|
||||
document.commandDispatcher.focusedElement = document.documentElement;
|
||||
},
|
||||
|
@ -410,24 +408,12 @@ let UI = {
|
|||
this.resetFocus();
|
||||
let deck = document.querySelector("#deck");
|
||||
let panel = deck.querySelector("#deck-panel-" + id);
|
||||
this._lastSelectedPanels.push(deck.selectedIndex);
|
||||
deck.selectedPanel = panel;
|
||||
},
|
||||
|
||||
closeLastDeckPanel: function() {
|
||||
this.resetFocus();
|
||||
let deck = document.querySelector("#deck");
|
||||
if (this._lastSelectedPanels.length > 0) {
|
||||
deck.selectedIndex = this._lastSelectedPanels.pop();
|
||||
} else {
|
||||
this.resetDeck();
|
||||
}
|
||||
},
|
||||
|
||||
resetDeck: function() {
|
||||
this.resetFocus();
|
||||
let deck = document.querySelector("#deck");
|
||||
this._lastSelectedPanels = [];
|
||||
deck.selectedPanel = null;
|
||||
},
|
||||
|
||||
|
@ -794,81 +780,11 @@ let Cmds = {
|
|||
},
|
||||
|
||||
showPermissionsTable: function() {
|
||||
return UI.busyUntil(AppManager.deviceFront.getRawPermissionsTable().then(json => {
|
||||
let styleContent = "";
|
||||
styleContent += "body {background:white; font-family: monospace}";
|
||||
styleContent += "table {border-collapse: collapse}";
|
||||
styleContent += "th, td {padding: 5px; border: 1px solid #EEE}";
|
||||
styleContent += "th {min-width: 130px}";
|
||||
styleContent += "td {text-align: center}";
|
||||
styleContent += "th:first-of-type, td:first-of-type {text-align:left}";
|
||||
styleContent += ".permallow {color:rgb(152, 207, 57)}";
|
||||
styleContent += ".permprompt {color:rgb(0,158,237)}";
|
||||
styleContent += ".permdeny {color:rgb(204,73,8)}";
|
||||
let style = document.createElementNS(HTML, "style");
|
||||
style.textContent = styleContent;
|
||||
let table = document.createElementNS(HTML, "table");
|
||||
table.innerHTML = "<tr><th>Name</th><th>type:web</th><th>type:privileged</th><th>type:certified</th></tr>";
|
||||
let permissionsTable = json.rawPermissionsTable;
|
||||
for (let name in permissionsTable) {
|
||||
let tr = document.createElementNS(HTML, "tr");
|
||||
let td = document.createElementNS(HTML, "td");
|
||||
td.textContent = name;
|
||||
tr.appendChild(td);
|
||||
for (let type of ["app","privileged","certified"]) {
|
||||
let td = document.createElementNS(HTML, "td");
|
||||
if (permissionsTable[name][type] == json.ALLOW_ACTION) {
|
||||
td.textContent = "✓";
|
||||
td.className = "permallow";
|
||||
}
|
||||
if (permissionsTable[name][type] == json.PROMPT_ACTION) {
|
||||
td.textContent = "!";
|
||||
td.className = "permprompt";
|
||||
}
|
||||
if (permissionsTable[name][type] == json.DENY_ACTION) {
|
||||
td.textContent = "✕";
|
||||
td.className = "permdeny"
|
||||
}
|
||||
tr.appendChild(td);
|
||||
}
|
||||
table.appendChild(tr);
|
||||
}
|
||||
let body = document.createElementNS(HTML, "body");
|
||||
body.appendChild(style);
|
||||
body.appendChild(table);
|
||||
let url = "data:text/html;charset=utf-8,";
|
||||
url += encodeURIComponent(body.outerHTML);
|
||||
UI.openInBrowser(url);
|
||||
}), "showing permission table");
|
||||
UI.selectDeckPanel("permissionstable");
|
||||
},
|
||||
|
||||
showRuntimeDetails: function() {
|
||||
return UI.busyUntil(AppManager.deviceFront.getDescription().then(json => {
|
||||
let styleContent = "";
|
||||
styleContent += "body {background:white; font-family: monospace}";
|
||||
styleContent += "table {border-collapse: collapse}";
|
||||
styleContent += "th, td {padding: 5px; border: 1px solid #EEE}";
|
||||
let style = document.createElementNS(HTML, "style");
|
||||
style.textContent = styleContent;
|
||||
let table = document.createElementNS(HTML, "table");
|
||||
for (let name in json) {
|
||||
let tr = document.createElementNS(HTML, "tr");
|
||||
let td = document.createElementNS(HTML, "td");
|
||||
td.textContent = name;
|
||||
tr.appendChild(td);
|
||||
td = document.createElementNS(HTML, "td");
|
||||
td.textContent = json[name];
|
||||
tr.appendChild(td);
|
||||
table.appendChild(tr);
|
||||
}
|
||||
let body = document.createElementNS(HTML, "body");
|
||||
body.appendChild(style);
|
||||
body.appendChild(table);
|
||||
let url = "data:text/html;charset=utf-8,";
|
||||
url += encodeURIComponent(body.outerHTML);
|
||||
UI.openInBrowser(url);
|
||||
}), "showing runtime details");
|
||||
|
||||
UI.selectDeckPanel("runtimedetails");
|
||||
},
|
||||
|
||||
play: function() {
|
||||
|
|
|
@ -162,6 +162,8 @@
|
|||
<iframe id="deck-panel-details" flex="1" src="details.xhtml"/>
|
||||
<iframe id="deck-panel-projecteditor" flex="1"/>
|
||||
<iframe id="deck-panel-addons" flex="1" src="addons.xhtml"/>
|
||||
<iframe id="deck-panel-permissionstable" flex="1" src="permissionstable.xhtml"/>
|
||||
<iframe id="deck-panel-runtimedetails" flex="1" src="runtimedetails.xhtml"/>
|
||||
</deck>
|
||||
</notificationbox>
|
||||
|
||||
|
|
|
@ -82,7 +82,18 @@
|
|||
<!ENTITY newAppLoadingTemplate "Loading templates…">
|
||||
<!ENTITY newAppProjectName "Project Name:">
|
||||
|
||||
|
||||
<!-- Decks -->
|
||||
|
||||
<!ENTITY deck_close "close">
|
||||
|
||||
<!-- Addons -->
|
||||
<!ENTITY addons_title "Extra Components:">
|
||||
<!ENTITY addons_close "close">
|
||||
<!ENTITY addons_aboutaddons "Open Addons Manager">
|
||||
|
||||
<!-- Permissions Table -->
|
||||
<!ENTITY permissionstable_title "Permissions Table">
|
||||
<!ENTITY permissionstable_name_header "Name">
|
||||
|
||||
<!-- Runtime Details -->
|
||||
<!ENTITY runtimedetails_title "Runtime Info">
|
||||
|
|
|
@ -61,7 +61,6 @@ SimulatorRuntime.prototype = {
|
|||
}
|
||||
|
||||
let gLocalRuntime = {
|
||||
supportApps: false, // Temporary static value
|
||||
connect: function(connection) {
|
||||
if (!DebuggerServer.initialized) {
|
||||
DebuggerServer.init();
|
||||
|
|
|
@ -31,3 +31,4 @@ support-files =
|
|||
[test_cli.html]
|
||||
[test_manifestUpdate.html]
|
||||
[test_addons.html]
|
||||
[test_deviceinfo.html]
|
||||
|
|
|
@ -95,3 +95,18 @@ function nextTick() {
|
|||
|
||||
return deferred.promise;
|
||||
}
|
||||
|
||||
function documentIsLoaded(doc) {
|
||||
let deferred = promise.defer();
|
||||
if (doc.readyState == "complete") {
|
||||
deferred.resolve();
|
||||
} else {
|
||||
doc.addEventListener("readystatechange", function onChange() {
|
||||
if (doc.readyState == "complete") {
|
||||
doc.removeEventListener("readystatechange", onChange);
|
||||
deferred.resolve();
|
||||
}
|
||||
});
|
||||
}
|
||||
return deferred.promise;
|
||||
}
|
||||
|
|
|
@ -0,0 +1,126 @@
|
|||
<!DOCTYPE html>
|
||||
|
||||
<html>
|
||||
|
||||
<head>
|
||||
<meta charset="utf8">
|
||||
<title></title>
|
||||
|
||||
<script type="application/javascript" src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<script type="application/javascript" src="chrome://mochikit/content/chrome-harness.js"></script>
|
||||
<script type="application/javascript;version=1.8" src="head.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css">
|
||||
</head>
|
||||
|
||||
<body>
|
||||
|
||||
<script type="application/javascript;version=1.8">
|
||||
window.onload = function() {
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
|
||||
Task.spawn(function* () {
|
||||
Cu.import("resource://gre/modules/devtools/dbg-server.jsm");
|
||||
DebuggerServer.init(function () { return true; });
|
||||
DebuggerServer.addBrowserActors();
|
||||
|
||||
let win = yield openWebIDE();
|
||||
|
||||
let permIframe = win.document.querySelector("#deck-panel-permissionstable");
|
||||
let infoIframe = win.document.querySelector("#deck-panel-runtimedetails");
|
||||
|
||||
yield documentIsLoaded(permIframe.contentWindow.document);
|
||||
yield documentIsLoaded(infoIframe.contentWindow.document);
|
||||
|
||||
win.AppManager.update("runtimelist");
|
||||
|
||||
let panelNode = win.document.querySelector("#runtime-panel");
|
||||
let items = panelNode.querySelectorAll(".runtime-panel-item-custom");
|
||||
is(items.length, 2, "Found 2 custom runtimes button");
|
||||
|
||||
let deferred = promise.defer();
|
||||
win.AppManager.on("app-manager-update", function onUpdate(e,w) {
|
||||
if (w == "list-tabs-response") {
|
||||
win.AppManager.off("app-manager-update", onUpdate);
|
||||
deferred.resolve();
|
||||
}
|
||||
});
|
||||
|
||||
items[1].click();
|
||||
|
||||
yield deferred.promise;
|
||||
|
||||
yield nextTick();
|
||||
|
||||
let perm = win.document.querySelector("#cmd_showPermissionsTable");
|
||||
let info = win.document.querySelector("#cmd_showRuntimeDetails");
|
||||
|
||||
ok(!perm.hasAttribute("disabled"), "perm cmd enabled");
|
||||
ok(!info.hasAttribute("disabled"), "info cmd enabled");
|
||||
|
||||
let deck = win.document.querySelector("#deck");
|
||||
|
||||
win.Cmds.showRuntimeDetails();
|
||||
is(deck.selectedPanel, infoIframe, "info iframe selected");
|
||||
|
||||
yield infoIframe.contentWindow.getRawPermissionsTablePromise;
|
||||
|
||||
yield nextTick();
|
||||
|
||||
// device info and permissions content is checked in other tests
|
||||
// We just test one value to make sure we get something
|
||||
|
||||
let doc = infoIframe.contentWindow.document;
|
||||
let trs = doc.querySelectorAll("tr");
|
||||
let found = false;
|
||||
|
||||
for (let tr of trs) {
|
||||
let [name,val] = tr.querySelectorAll("td");
|
||||
if (name.textContent == "appid") {
|
||||
found = true;
|
||||
is(val.textContent, Services.appinfo.ID, "appid has the right value");
|
||||
}
|
||||
}
|
||||
ok(found, "Found appid line");
|
||||
|
||||
win.Cmds.showPermissionsTable();
|
||||
is(deck.selectedPanel, permIframe, "permission iframe selected");
|
||||
|
||||
yield infoIframe.contentWindow.getDescriptionPromise;
|
||||
|
||||
yield nextTick();
|
||||
|
||||
doc = permIframe.contentWindow.document;
|
||||
trs = doc.querySelectorAll(".line");
|
||||
found = false;
|
||||
for (let tr of trs) {
|
||||
let [name,v1,v2,v3] = tr.querySelectorAll("td");
|
||||
if (name.textContent == "geolocation") {
|
||||
found = true;
|
||||
is(v1.className, "permprompt", "geolocation perm is valid");
|
||||
is(v2.className, "permprompt", "geolocation perm is valid");
|
||||
is(v3.className, "permprompt", "geolocation perm is valid");
|
||||
}
|
||||
}
|
||||
ok(found, "Found geolocation line");
|
||||
|
||||
doc.querySelector("#close").click();
|
||||
|
||||
ok(!deck.selectedPanel, "No panel selected");
|
||||
|
||||
DebuggerServer.destroy();
|
||||
|
||||
yield closeWebIDE(win);
|
||||
|
||||
SimpleTest.finish();
|
||||
|
||||
|
||||
}).then(null, e => {
|
||||
ok(false, "Exception: " + e);
|
||||
SimpleTest.finish();
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
|
@ -10,3 +10,4 @@ webide.jar:
|
|||
skin/newapp.css (newapp.css)
|
||||
skin/throbber.svg (throbber.svg)
|
||||
skin/addons.css (addons.css)
|
||||
skin/tabledoc.css (tabledoc.css)
|
||||
|
|
|
@ -0,0 +1,54 @@
|
|||
body {
|
||||
background: white;
|
||||
}
|
||||
|
||||
#controls {
|
||||
position: fixed;
|
||||
top: 10px;
|
||||
right: 10px;
|
||||
}
|
||||
|
||||
#controls > a {
|
||||
color: #4C9ED9;
|
||||
font-size: small;
|
||||
cursor: pointer;
|
||||
border-bottom: 1px dotted;
|
||||
}
|
||||
|
||||
#close {
|
||||
margin-left: 10px;
|
||||
}
|
||||
|
||||
table {
|
||||
font-family: monospace;
|
||||
border-collapse: collapse;
|
||||
}
|
||||
|
||||
th, td {
|
||||
padding: 5px;
|
||||
border: 1px solid #EEE;
|
||||
}
|
||||
|
||||
th {
|
||||
min-width: 130px;
|
||||
}
|
||||
|
||||
.permissionstable td {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
th:first-of-type, td:first-of-type {
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
.permallow {
|
||||
color: rgb(152,207,57);
|
||||
}
|
||||
|
||||
.permprompt {
|
||||
color: rgb(0,158,237);
|
||||
}
|
||||
|
||||
.permdeny {
|
||||
color: rgb(204,73,8);
|
||||
}
|
Загрузка…
Ссылка в новой задаче