зеркало из https://github.com/mozilla/ubiquity.git
Added SkinFeedPlugin in place of SkinSvc, simplifying things greatly.
This commit is contained in:
Родитель
670de04680
Коммит
af727561cf
|
@ -159,7 +159,7 @@ CmdUtils.CreateCommand({
|
|||
argument: noun_type_skin,
|
||||
execute: function chskin_execute({object: {data: skin}}) {
|
||||
if (skin) {
|
||||
UbiquitySetup.createServices().skinService.changeSkin(skin.localUrl);
|
||||
skin.pick();
|
||||
Utils.tabs.reload(/^about:ubiquity\?settings\b/);
|
||||
}
|
||||
else Utils.focusUrlInBrowser(Settings);
|
||||
|
|
|
@ -66,6 +66,10 @@ var {escapeHtml} = Utils;
|
|||
var {feedManager, commandSource, messageService} = (
|
||||
UbiquitySetup.createServices());
|
||||
|
||||
function getFeeds(type) [
|
||||
feed for each (feed in feedManager["get" + type + "Feeds"]())
|
||||
if ("commands" in feed)];
|
||||
|
||||
function A(url, text, className, attrs) {
|
||||
var a = document.createElement("a");
|
||||
a.href = url;
|
||||
|
@ -231,12 +235,11 @@ function fillTableRowForCmd(row, cmd, className) {
|
|||
|
||||
function updateSubscribedCount() {
|
||||
$("#num-commands").html(commandSource.commandNames.length);
|
||||
$("#num-subscribed-feeds").html(feedManager.getSubscribedFeeds().length);
|
||||
$("#num-subscribed-feeds").text(getFeeds("Subscribed").length);
|
||||
}
|
||||
|
||||
function updateUnsubscribedCount() {
|
||||
$("#num-unsubscribed-feeds").html(
|
||||
feedManager.getUnsubscribedFeeds().length);
|
||||
$("#num-unsubscribed-feeds").text(getFeeds("Unsubscribed").length);
|
||||
}
|
||||
|
||||
function buildTable() {
|
||||
|
@ -267,10 +270,8 @@ function buildTable() {
|
|||
function addCmdToTable(cmd) {
|
||||
let aRow = $("<tr></tr>");
|
||||
let feedCell = $("<td></td>");
|
||||
let feed = getFeedForCommand(feedManager, cmd);
|
||||
if (feed) {
|
||||
fillTableCellForFeed(feedCell, feed);
|
||||
}
|
||||
let feed = feedManager.getFeedForUrl(cmd.feedUri);
|
||||
if (feed) fillTableCellForFeed(feedCell, feed);
|
||||
aRow.append(feedCell);
|
||||
fillTableRowForCmd(aRow, cmd);
|
||||
table.append(aRow);
|
||||
|
@ -279,7 +280,7 @@ function buildTable() {
|
|||
updateSubscribedCount();
|
||||
|
||||
if (/^feed/.test(sortMode))
|
||||
(feedManager.getSubscribedFeeds()
|
||||
(getFeeds("Subscribed")
|
||||
.sort(/date$/.test(sortMode) ? byDate : byTitle)
|
||||
.forEach(addFeedToTable));
|
||||
else
|
||||
|
@ -315,14 +316,6 @@ function sortCmdListBy(cmdList, key) {
|
|||
return cmdList.sort(key === "enabled" ? checksort : alphasort);
|
||||
}
|
||||
|
||||
function getFeedForCommand(feedManager, cmd) {
|
||||
// This is a really hacky implementation -- it involves going through
|
||||
// all feeds looking for one containing a command with a matching name.
|
||||
for each (let feed in feedManager.getSubscribedFeeds())
|
||||
if (cmd.id in (feed.commands || {})) return feed;
|
||||
return null;
|
||||
}
|
||||
|
||||
// Bind this to checkbox "change".
|
||||
function onDisableOrEnableCmd() {
|
||||
// update the preferences, when the user toggles the active
|
||||
|
|
|
@ -45,6 +45,7 @@ Cu.import("resource://ubiquity/modules/localization_utils.js");
|
|||
|
||||
var L = LocalizationUtils.propertySelector(
|
||||
"chrome://ubiquity/locale/aboutubiquity.properties");
|
||||
var H = Utils.escapeHtml;
|
||||
|
||||
var gPrefs = Utils.prefs;
|
||||
|
||||
|
|
|
@ -42,7 +42,6 @@ Cu.import("resource://ubiquity/modules/prefkeys.js")
|
|||
const PREF_NFE = "extensions.ubiquity.doNounFirstExternals";
|
||||
|
||||
var {skinService, messageService} = UbiquitySetup.createServices();
|
||||
var {escapeHtml} = Utils;
|
||||
|
||||
$(onDocumentLoad);
|
||||
|
||||
|
@ -117,107 +116,76 @@ function changeExternalCallSettings() {
|
|||
}
|
||||
|
||||
function loadSkinList() {
|
||||
var {CUSTOM_SKIN, currentSkin, skinList} = skinService;
|
||||
var $list = $("#skin-list").empty();
|
||||
var i = 0;
|
||||
for each (let skin in skinList)
|
||||
if (skin.localUrl === CUSTOM_SKIN)
|
||||
var customSkin = skin;
|
||||
else
|
||||
$list.append(createSkinElement(skin, i++));
|
||||
$list.append(createSkinElement(customSkin, i));
|
||||
checkSkin(currentSkin);
|
||||
// If current skin is custom skin, auto-open the editor
|
||||
if (currentSkin === CUSTOM_SKIN)
|
||||
openSkinEditor();
|
||||
var {skins, currentSkin} = skinService;
|
||||
var $list = $("#skin-list").empty(), id = -1;
|
||||
for each (let skin in Utils.sortBy(skins, function(s) s.uri.spec))
|
||||
$list.append(createSkinElement(skin, ++id, skin === currentSkin));
|
||||
if (currentSkin === skinService.customSkin) openSkinEditor();
|
||||
}
|
||||
|
||||
function createSkinElement(skin, id) {
|
||||
var {localUrl: filepath, downloadUrl: origpath, metaData: skinMeta} = skin;
|
||||
var skinId = "skin_" + id;
|
||||
var skinEl = $(
|
||||
'<div class="command" id="' + skinId + '">' +
|
||||
('<input type="radio" name="skins" id="rad_' + skinId +
|
||||
'" value="' + escapeHtml(filepath) + '"></input>') +
|
||||
'<label class="label light" for="rad_'+ skinId + '">' +
|
||||
'<a class="name"/><br/>' +
|
||||
'<span class="author"></span><br/>' +
|
||||
'<span class="license"></span></label>' +
|
||||
'<div class="email light"></div>' +
|
||||
'<div class="homepage light"></div></div>');
|
||||
function createSkinElement(skin, id, current) {
|
||||
var {metaData} = skin;
|
||||
var $skin = $(
|
||||
'<div class="command light" id="skin_' + id + '">' +
|
||||
('<input type="radio" name="skins" id="rad_skin_' + id + '"' +
|
||||
(current ? ' checked="checked"' : '') + '/>') +
|
||||
'<label class="label" for="rad_skin_'+ id +
|
||||
'"><a class="name"/></label></div>');
|
||||
|
||||
//Add the name and onchange event
|
||||
skinEl.find(".name").text(skinMeta.name);
|
||||
skinEl.find("input").change(function onRadioChange() {
|
||||
skinService.changeSkin(filepath);
|
||||
});
|
||||
$skin.find(".name").text(metaData.name);
|
||||
$skin.find("input").change(function onPick() { skin.pick() });
|
||||
|
||||
if ("author" in skinMeta)
|
||||
skinEl.find(".author").text(L("ubiquity.settings.skinauthor",
|
||||
skinMeta.author));
|
||||
if ("email" in skinMeta) {
|
||||
let ee = escapeHtml(skinMeta.email);
|
||||
skinEl.find(".email")[0].innerHTML = "email: " + ee.link("mailto:" + ee);
|
||||
}
|
||||
if ("license" in skinMeta)
|
||||
skinEl.find(".license").text(L("ubiquity.settings.skinlicense",
|
||||
skinMeta.license));
|
||||
if ("homepage" in skinMeta) {
|
||||
let eh = escapeHtml(skinMeta.homepage);
|
||||
skinEl.find(".homepage")[0].innerHTML = eh.link(eh);
|
||||
}
|
||||
"author" in metaData && $("<div>", {
|
||||
class: "author",
|
||||
text: L("ubiquity.settings.skinauthor", metaData.author),
|
||||
}).appendTo($skin);
|
||||
"license" in metaData && $("<div>", {
|
||||
class: "license",
|
||||
text: L("ubiquity.settings.skinlicense", metaData.license),
|
||||
}).appendTo($skin);
|
||||
"email" in metaData && $("<div>", {
|
||||
class: "email",
|
||||
html: let (ee = H(metaData.email)) "email: " + ee.link("mailto:" + ee),
|
||||
}).appendTo($skin);
|
||||
"homepage" in metaData && $("<div>", {
|
||||
class: "homepage",
|
||||
html: let (eh = H(metaData.homepage)) eh.link(eh),
|
||||
}).appendTo($skin);
|
||||
|
||||
($('<a class="action" target="_blank"></a>')
|
||||
.attr("href", "view-source:" + filepath)
|
||||
.attr("href", "view-source:" + skin.viewSourceUri.spec)
|
||||
.text(L("ubiquity.settings.viewskinsource"))
|
||||
.appendTo(skinEl));
|
||||
if (filepath !== origpath) (
|
||||
.appendTo($skin));
|
||||
|
||||
skin.isBuiltIn || (
|
||||
$('<a class="action"></a>')
|
||||
.text(L("ubiquity.settings.uninstallskin"))
|
||||
.click(function uninstall() {
|
||||
var before = skinService.currentSkin;
|
||||
skinService.uninstall(filepath);
|
||||
var after = skinService.currentSkin;
|
||||
if (before !== after) checkSkin(after);
|
||||
skinEl.slideUp();
|
||||
if (skin === skinService.currentSkin) skinService.defaultSkin.pick();
|
||||
skin.purge();
|
||||
$skin.slideUp();
|
||||
})
|
||||
.appendTo(skinEl.append(" ")));
|
||||
.appendTo($skin.append(" ")));
|
||||
|
||||
return skinEl;
|
||||
}
|
||||
|
||||
function checkSkin(url) {
|
||||
$("#skin-list input:radio").each(function radio() {
|
||||
if (this.value === url) {
|
||||
this.checked = true;
|
||||
return false;
|
||||
}
|
||||
});
|
||||
return $skin;
|
||||
}
|
||||
|
||||
function openSkinEditor() {
|
||||
$("#editor-div").show();
|
||||
$("#skin-editor").val(Utils.getLocalUrl(skinService.CUSTOM_SKIN)).focus();
|
||||
$("#skin-editor").val(skinService.customSkin.css).focus();
|
||||
$("#edit-button").hide();
|
||||
}
|
||||
|
||||
function saveCustomSkin() {
|
||||
try {
|
||||
skinService.saveCustomSkin($("#skin-editor").val());
|
||||
} catch (e) {
|
||||
messageService.displayMessage(L("ubiquity.settings.skinerror"));
|
||||
Cu.reportError(e);
|
||||
return;
|
||||
}
|
||||
var {customSkin} = skinService;
|
||||
customSkin.css = $("#skin-editor").val();
|
||||
messageService.displayMessage(L("ubiquity.settings.skinsaved"));
|
||||
loadSkinList();
|
||||
if (skinService.currentSkin === skinService.CUSTOM_SKIN)
|
||||
skinService.loadCurrentSkin();
|
||||
if (customSkin === skinService.currentSkin) customSkin.pick();
|
||||
}
|
||||
|
||||
function saveAs() {
|
||||
try {
|
||||
skinService.saveAs($("#skin-editor").val(), "custom");
|
||||
skinService.saveAs($("#skin-editor").val(), "custom.css");
|
||||
} catch (e) {
|
||||
messageService.displayMessage(L("ubiquity.settings.skinerror"));
|
||||
Cu.reportError(e);
|
||||
|
@ -228,6 +196,6 @@ function saveAs() {
|
|||
|
||||
function shareSkin() {
|
||||
var data = $("#skin-editor").val()
|
||||
var name = Utils.trim((/@name[ \t]+(.+)/(data) || [, "ubiquity-skin"])[1]);
|
||||
var name = ((/@name[ \t]+(.+)/(data) || [, "ubiquity-skin"])[1]).trim();
|
||||
pasteToGist(name, data, "css");
|
||||
}
|
||||
|
|
|
@ -42,6 +42,8 @@
|
|||
<li><a class="intra-wiki"
|
||||
href="#modules/locked_down_feed_plugin.js">Locked-Down Feed
|
||||
Plugin</a></li>
|
||||
<li><a class="intra-wiki"
|
||||
href="#modules/skin_feed_plugin.js">SkinFeedPlugin</a></li>
|
||||
<li><a class="intra-wiki"
|
||||
href="#modules/parser/new/parser.js">Parser 2</a></li>
|
||||
<li><a class="intra-wiki"
|
||||
|
|
|
@ -528,9 +528,7 @@ var noun_type_disabled_command = {
|
|||
// === {{{ noun_type_skin }}} ===
|
||||
// Suggests each installed skin whose name matches the input.
|
||||
// * {{{text, html}}} : skin name
|
||||
// * {{{data.downloadUrl}}}
|
||||
// * {{{data.localUrl}}}
|
||||
// * {{{data.metaData}}} : meta data dictionary
|
||||
// * {{{data}}} : [[#modules/skin_feed_plugin.js|SkinFeed]] instance
|
||||
|
||||
var noun_type_skin = {
|
||||
label: "name",
|
||||
|
@ -538,7 +536,7 @@ var noun_type_skin = {
|
|||
cacheTime: 0,
|
||||
suggest: function nt_skin_suggest(text, html, cb, selected) {
|
||||
var suggs = [CmdUtils.makeSugg(skin.metaData.name, null, skin)
|
||||
for each (skin in skinService.skinList)];
|
||||
for each (skin in skinService.skins)];
|
||||
return CmdUtils.grepSuggs(text, suggs);
|
||||
},
|
||||
};
|
||||
|
|
|
@ -54,7 +54,7 @@ Cu.import("resource://ubiquity/modules/suggestion_memory.js");
|
|||
Cu.import("resource://ubiquity/modules/feedaggregator.js");
|
||||
Cu.import("resource://ubiquity/modules/webjsm.js");
|
||||
Cu.import("resource://ubiquity/modules/prefcommands.js");
|
||||
Cu.import("resource://ubiquity/modules/skinsvc.js");
|
||||
Cu.import("resource://ubiquity/modules/skin_feed_plugin.js");
|
||||
|
||||
var gServices, gWebJsModule, gPrefs = Utils.prefs;
|
||||
|
||||
|
@ -158,9 +158,6 @@ var UbiquitySetup = {
|
|||
if (annDb.exists())
|
||||
annDb.remove(false);
|
||||
|
||||
// Reset all skins.
|
||||
SkinSvc.reset();
|
||||
|
||||
// We'll reset the preferences for our extension here. Unfortunately,
|
||||
// there doesn't seem to be an easy way to get this from FUEL, so
|
||||
// we'll have to use XPCOM directly.
|
||||
|
@ -187,23 +184,15 @@ var UbiquitySetup = {
|
|||
}
|
||||
},
|
||||
|
||||
getBaseUri: function getBaseUri() {
|
||||
let ioSvc = (Cc["@mozilla.org/network/io-service;1"]
|
||||
.getService(Ci.nsIIOService));
|
||||
let extDir = this.__getExtDir();
|
||||
let baseUri = ioSvc.newFileURI(extDir).spec;
|
||||
|
||||
return baseUri;
|
||||
},
|
||||
getBaseUri: function getBaseUri()
|
||||
Utils.IOService.newFileURI(this.__getExtDir()).spec,
|
||||
|
||||
isInstalledAsXpi: function isInstalledAsXpi() {
|
||||
let profileDir = (Cc["@mozilla.org/file/directory_service;1"]
|
||||
.getService(Ci.nsIProperties)
|
||||
.get("ProfD", Ci.nsIFile));
|
||||
let extDir = this.__getExtDir();
|
||||
if (profileDir.contains(extDir, false))
|
||||
return true;
|
||||
return false;
|
||||
return profileDir.contains(extDir, false);
|
||||
},
|
||||
|
||||
preload: function preload(callback) {
|
||||
|
@ -216,13 +205,10 @@ var UbiquitySetup = {
|
|||
gWebJsModule = new WebJsModule(callback);
|
||||
},
|
||||
|
||||
get isResetScheduled getIsResetScheduled() {
|
||||
return gPrefs.getValue(RESET_SCHEDULED_PREF, false);
|
||||
},
|
||||
|
||||
set isResetScheduled setIsResetScheduled(value) {
|
||||
gPrefs.setValue(RESET_SCHEDULED_PREF, value);
|
||||
},
|
||||
get isResetScheduled getIsResetScheduled()
|
||||
gPrefs.get(RESET_SCHEDULED_PREF, false),
|
||||
set isResetScheduled setIsResetScheduled(value)
|
||||
gPrefs.set(RESET_SCHEDULED_PREF, value),
|
||||
|
||||
__removeExtinctStandardFeeds: function __rmExtinctStdFeeds(feedManager) {
|
||||
var OLD_STD_FEED_URIS = [
|
||||
|
@ -287,14 +273,12 @@ var UbiquitySetup = {
|
|||
);
|
||||
disabledStorage.attach(cmdSource);
|
||||
|
||||
var skinService = new SkinSvc(gWebJsModule, msgService);
|
||||
skinService.updateAllSkins();
|
||||
skinService.loadCurrentSkin();
|
||||
|
||||
gServices = {commandSource: cmdSource,
|
||||
feedManager: feedManager,
|
||||
messageService: msgService,
|
||||
skinService: skinService};
|
||||
gServices = {
|
||||
commandSource: cmdSource,
|
||||
feedManager: feedManager,
|
||||
messageService: msgService,
|
||||
skinService: SkinFeedPlugin(feedManager, msgService, gWebJsModule),
|
||||
};
|
||||
|
||||
this.__setupFinalizer();
|
||||
|
||||
|
@ -321,7 +305,6 @@ var UbiquitySetup = {
|
|||
|
||||
setupWindow: function setupWindow(window) {
|
||||
gServices.feedManager.installToWindow(window);
|
||||
gServices.skinService.installToWindow(window);
|
||||
|
||||
const PAGE_LOAD_PREF = "extensions.ubiquity.enablePageLoadHandlers";
|
||||
|
||||
|
|
|
@ -0,0 +1,240 @@
|
|||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is Ubiquity.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Mozilla.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2007
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Satoshi Murakami <murky.satyr@gmail.com>
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
// = SkinFeedPlugin =
|
||||
// The boss of {{{SkinFeed}}}s, aka {{{skinService}}}.
|
||||
|
||||
var EXPORTED_SYMBOLS = ["SkinFeedPlugin"];
|
||||
|
||||
const {classes: Cc, interfaces: Ci, utils: Cu, results: Cr} = Components;
|
||||
|
||||
Cu.import("resource://ubiquity/modules/utils.js");
|
||||
Cu.import("resource://ubiquity/modules/codesource.js");
|
||||
Cu.import("resource://ubiquity/modules/localization_utils.js");
|
||||
|
||||
const L = LocalizationUtils.propertySelector(
|
||||
"chrome://ubiquity/locale/coreubiquity.properties");
|
||||
const SSS = (Cc["@mozilla.org/content/style-sheet-service;1"]
|
||||
.getService(Ci.nsIStyleSheetService));
|
||||
const PREF_SKIN = "extensions.ubiquity.skin";
|
||||
const PREF_CUSTOM = "extensions.ubiquity.customCss";
|
||||
const PREF_REMOTE_TIMEOUT = "extensions.ubiquity.remoteUriTimeout";
|
||||
const URL_ROOT = "chrome://ubiquity/skin/skins/";
|
||||
const URL_CUSTOM = "ubiquity://custom-skin-css";
|
||||
const URL_DEFAULT = URL_ROOT + "experimental.css";
|
||||
const RE_LEAFNAME = /[^/]*$/;
|
||||
|
||||
var gCurrentCssUri = Utils.uri("data:text/css,");
|
||||
|
||||
function SkinFeedPlugin(feedManager, msgService, webJsm) {
|
||||
SFP._feedManager = feedManager;
|
||||
SFP._msgService = msgService;
|
||||
SFP._webJsm = webJsm;
|
||||
feedManager.registerPlugin(SFP);
|
||||
for each (let url in [
|
||||
URL_CUSTOM, URL_DEFAULT, URL_ROOT + "default.css", URL_ROOT + "old.css"])
|
||||
feedManager.addSubscribedFeed({
|
||||
type: "ubiquity-skin",
|
||||
url: url, sourceUrl: url, title: url,
|
||||
isBuiltIn: true,
|
||||
canAutoUpdate: true,
|
||||
});
|
||||
SFP.customSkin.__defineSetter__("css", function SF_setCustomCss(css) {
|
||||
Utils.prefs.set(PREF_CUSTOM, css);
|
||||
});
|
||||
SFP.currentSkin.pick(true);
|
||||
return SFP;
|
||||
}
|
||||
var SFP = Utils.extend(SkinFeedPlugin.prototype, {
|
||||
type: "ubiquity-skin",
|
||||
notifyMessage: L("ubiquity.skinsvc.newskinfound"),
|
||||
|
||||
makeFeed: function SFP_makeFeed(baseFeed, eventHub)
|
||||
SkinFeed(baseFeed, eventHub, this._msgService),
|
||||
onSubscribeClick: function SFP_onSubscribeClick(pageUrl, link) {
|
||||
var cssUrl = link.href, me = this;
|
||||
me._webJsm.jQuery.ajax({
|
||||
url: link.href,
|
||||
dataType: "text",
|
||||
success: function yay(css) {
|
||||
me._feedManager.addSubscribedFeed({
|
||||
type: "ubiquity-skin",
|
||||
url: cssUrl, sourceUrl: cssUrl,
|
||||
title: url,
|
||||
sourceCode: css,
|
||||
canAutoUpdate: true,
|
||||
}).getFeedForUrl(url).pick();
|
||||
Utils.tabs.reload(/^about:ubiquity\?settings\b/);
|
||||
},
|
||||
error: Utils.log,
|
||||
});
|
||||
},
|
||||
|
||||
// === {{{ SkinFeedPlugin.skins }}} ===
|
||||
// Installed {{{SkinFeed}}}s as array.
|
||||
get skins SFP_getSkins() [
|
||||
feed for each (feed in this._feedManager.getSubscribedFeeds())
|
||||
if (feed.type === "ubiquity-skin")],
|
||||
|
||||
// === {{{ SkinFeedPlugin.customSkin }}} ===
|
||||
get customSkin SFP_getCurrentSkin()
|
||||
this._feedManager.getFeedForUrl(URL_CUSTOM),
|
||||
|
||||
// === {{{ SkinFeedPlugin.defaultSkin }}} ===
|
||||
get defaultSkin SFP_getCurrentSkin()
|
||||
this._feedManager.getFeedForUrl(URL_DEFAULT),
|
||||
|
||||
// === {{{ SkinFeedPlugin.currentSkin }}} ===
|
||||
get currentSkin SFP_getCurrentSkin() (
|
||||
this._feedManager.getFeedForUrl(Utils.prefs.get(PREF_SKIN, URL_DEFAULT)) ||
|
||||
this.defaultSkin),
|
||||
|
||||
// === {{{ SkinFeedPlugin.saveAs(cssText, defaultName) }}} ===
|
||||
// Saves {{{cssText}}} to a file and subscribes to it.
|
||||
saveAs: function SFP_saveAs(cssText, defaultName) {
|
||||
const {nsIFilePicker} = Ci;
|
||||
var fp = Cc["@mozilla.org/filepicker;1"].createInstance(nsIFilePicker);
|
||||
fp.init(Utils.currentChromeWindow,
|
||||
L("ubiquity.skinsvc.saveyourskin"),
|
||||
nsIFilePicker.modeSave);
|
||||
fp.defaultString = defaultName || "";
|
||||
fp.appendFilter("CSS (*.css)", "*.css");
|
||||
var rv = fp.show();
|
||||
if (rv !== nsIFilePicker.returnOK &&
|
||||
rv !== nsIFilePicker.returnReplace) return "";
|
||||
var {file, fileURL: {spec}} = fp;
|
||||
try {
|
||||
let fos = (Cc["@mozilla.org/network/file-output-stream;1"]
|
||||
.createInstance(Ci.nsIFileOutputStream));
|
||||
fos.init(file, 0x02 | 0x08 | 0x20, 0644, 0);
|
||||
fos.write(cssText, cssText.length);
|
||||
fos.close();
|
||||
} catch (e) {
|
||||
//errorToLocalize
|
||||
e.message =
|
||||
"Error writing Ubiquity skin to " + file.path + ": " + e.message;
|
||||
Cu.reportError(e);
|
||||
}
|
||||
this.onSubscribeClick({title: RE_LEAFNAME(spec)[0], URL: spec}, spec);
|
||||
this._feedManager.getFeedForUrl(spec).pick();
|
||||
return file.path;
|
||||
},
|
||||
toString: function SFP_toString() "[object SkinFeedPlugin]",
|
||||
});
|
||||
|
||||
// == SkinFeed ==
|
||||
|
||||
function SkinFeed(baseFeed, eventHub, msgService) Utils.extend({
|
||||
__proto__: baseFeed,
|
||||
_msgService: msgService,
|
||||
_codeSource: (
|
||||
RemoteUriCodeSource.isValidUri(baseFeed.uri)
|
||||
? new RemoteUriCodeSource(baseFeed,
|
||||
Utils.prefs.get(PREF_REMOTE_TIMEOUT, 3e5))
|
||||
: new LocalUriCodeSource(baseFeed.uri.spec)),
|
||||
_dataCache: null,
|
||||
}, SkinFeed.prototype);
|
||||
Utils.extend(SkinFeed.prototype, {
|
||||
// === {{{ SkinFeed#css }}} ===
|
||||
// CSS code of this skin. Settable if custom.
|
||||
get css SF_getCss() {
|
||||
var code = this._codeSource.getCode();
|
||||
if (this._codeSource.updated) this._dataCache = null;
|
||||
return code;
|
||||
},
|
||||
|
||||
// === {{{ SkinFeed#dataUri }}} ===
|
||||
// Data URI object used to register this skin.
|
||||
get dataUri SF_getDataUri()
|
||||
Utils.uri("data:text/css,/*ubiquity-skin*/" + encodeURI(this.css)),
|
||||
|
||||
// === {{{ SkinFeed#metaData }}} ===
|
||||
// Contents of the meta data block ({{{ =skin= ~ =/skin= }}}).
|
||||
get metaData SF_getMetaData() {
|
||||
if (this._dataCache) return this._dataCache;
|
||||
var {css} = this, data = {name: this.title};
|
||||
var [, block] = /=skin=\s*([^]+)\s*=\/skin=/(css) || 0;
|
||||
if (block) {
|
||||
let re = /^[ \t]*@(\w+)[ \t]+(.+)/mg, m;
|
||||
while ((m = re.exec(block))) data[m[1]] = m[2].trim();
|
||||
}
|
||||
if (!("homepage" in data)) data.homepage = this.title;
|
||||
return this._dataCache = data;
|
||||
},
|
||||
|
||||
// === {{{ SkinFeed#pick(silently = false) }}} ===
|
||||
// Applies this skin. Won't notify user if {{{silently}}}.
|
||||
pick: function SF_pick(silently) {
|
||||
try {
|
||||
(SSS.sheetRegistered(gCurrentCssUri, SSS.USER_SHEET) &&
|
||||
SSS.unregisterSheet(gCurrentCssUri, SSS.USER_SHEET));
|
||||
hackCssForBugs(gCurrentCssUri, SSS);
|
||||
var {dataUri, uri} = this;
|
||||
SSS.loadAndRegisterSheet(dataUri, SSS.USER_SHEET);
|
||||
hackCssForBugs(dataUri, SSS, true);
|
||||
gCurrentCssUri = dataUri;
|
||||
Utils.prefs.set(PREF_SKIN, uri.spec);
|
||||
} catch (e) {
|
||||
this._msgService.displayMessage(
|
||||
//errorToLocalize
|
||||
"Error applying Ubiquity skin from " + uri.spec);
|
||||
Cu.reportError(e);
|
||||
}
|
||||
silently ||
|
||||
this._msgService.displayMessage(L("ubiquity.skinsvc.skinchanged"));
|
||||
return this;
|
||||
},
|
||||
refresh: function SF_refresh() this,
|
||||
toString: function SF_toString() "[object SkinFeed<" + this.uri.spec + ">]",
|
||||
});
|
||||
|
||||
function hackCssForBugs(uri, registering) {
|
||||
if (Utils.OS === "Darwin" &&
|
||||
uri.spec === URL_ROOT + "experimental.css") {
|
||||
let hackUri = Utils.uri(URL_ROOT + "experimental-466hack.css");
|
||||
if (registering)
|
||||
SSS.loadAndRegisterSheet(hackUri, SSS.USER_SHEET);
|
||||
else if (SSS.sheetRegistered(hackUri, SSS.USER_SHEET))
|
||||
SSS.unregisterSheet(hackUri, SSS.USER_SHEET);
|
||||
}
|
||||
}
|
||||
|
||||
Cu.import("resource://ubiquity/modules/ubiquity_protocol.js", null).setPath(
|
||||
RE_LEAFNAME(URL_CUSTOM)[0], function customSkinUri() {
|
||||
var css = Utils.prefs.get(PREF_CUSTOM);
|
||||
if (!css) css = Utils.getLocalUrl(URL_ROOT + "custom.css");
|
||||
return "data:text/css," + encodeURI(css);
|
||||
});
|
|
@ -1,375 +0,0 @@
|
|||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is Ubiquity.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Mozilla.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2007
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Abimanyu Raja <abimanyuraja@gmail.com>
|
||||
* Satoshi Murakami <murky.satyr@gmail.com>
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
var EXPORTED_SYMBOLS = ["SkinSvc"];
|
||||
|
||||
const {classes: Cc, interfaces: Ci, utils: Cu} = Components;
|
||||
|
||||
Cu.import("resource://ubiquity/modules/utils.js");
|
||||
Cu.import("resource://ubiquity/modules/dbutils.js");
|
||||
Cu.import("resource://ubiquity/modules/localization_utils.js");
|
||||
|
||||
const SKIN_ROOT = "chrome://ubiquity/skin/skins/";
|
||||
const SKIN_PREF = "extensions.ubiquity.skin";
|
||||
|
||||
var L = LocalizationUtils.propertySelector(
|
||||
"chrome://ubiquity/locale/coreubiquity.properties");
|
||||
|
||||
var gConnection = connect();
|
||||
var gMetaDict = {};
|
||||
|
||||
function connect() DbUtils.connectLite(
|
||||
"ubiquity_skin_memory",
|
||||
{ download_uri: "VARCHAR(256)",
|
||||
local_uri : "VARCHAR(256)" },
|
||||
[let (path = SKIN_ROOT + name + ".css") [path, path]
|
||||
for each (name in ["default", "experimental", "old", "custom"])]);
|
||||
|
||||
function SkinSvc(webJsm, msgService) {
|
||||
this._webJsm = webJsm;
|
||||
this._msgService = msgService;
|
||||
}
|
||||
|
||||
SkinSvc.SkinProto = {
|
||||
get metaData() SkinSvc.readMetaData(this),
|
||||
};
|
||||
|
||||
SkinSvc.readMetaData = function SS_readMetaData(
|
||||
{css, downloadUrl, localUrl, noCache}) {
|
||||
if (!noCache && localUrl in gMetaDict) return gMetaDict[localUrl];
|
||||
var metaData = gMetaDict[localUrl] = {name: localUrl};
|
||||
css || (css = Utils.getLocalUrl(localUrl, "utf-8"));
|
||||
//look for =skin= ~ =/skin= indicating metadata
|
||||
var [, data] = /=skin=\s*([^]+)\s*=\/skin=/(css) || 0;
|
||||
if (data) {
|
||||
let re = /^[ \t]*@(\w+)[ \t]+(.+)/mg, m;
|
||||
while ((m = re.exec(data))) metaData[m[1]] = m[2].trim();
|
||||
}
|
||||
if (!("homepage" in metaData) && /^https?:/.test(downloadUrl))
|
||||
metaData.homepage = downloadUrl;
|
||||
return metaData;
|
||||
};
|
||||
|
||||
SkinSvc.reset = function SS_reset() {
|
||||
var {databaseFile} = gConnection;
|
||||
gConnection.close();
|
||||
databaseFile.exists() && databaseFile.remove(false);
|
||||
gConnection = connect();
|
||||
};
|
||||
|
||||
SkinSvc.prototype = {
|
||||
PREF: SKIN_PREF,
|
||||
DEFAULT_SKIN: SKIN_ROOT + "experimental.css",
|
||||
CUSTOM_SKIN : SKIN_ROOT + "custom.css",
|
||||
|
||||
_createStatement: function SS__createStatement(sql) {
|
||||
try {
|
||||
return gConnection.createStatement(sql);
|
||||
} catch (e) {
|
||||
throw new Error(gConnection.lastErrorString);
|
||||
}
|
||||
},
|
||||
|
||||
_isLocalUrl: function SS__isLocalUrl(skinUrl)
|
||||
/^(?:file|chrome)$/.test(Utils.url(skinUrl).scheme),
|
||||
|
||||
//Navigate to chrome://ubiquity/skin/skins/ and get the folder
|
||||
_getSkinFolder: function SS__getSkinFolder() {
|
||||
var MY_ID = "ubiquity@labs.mozilla.com";
|
||||
var em = (Cc["@mozilla.org/extensions/manager;1"]
|
||||
.getService(Ci.nsIExtensionManager));
|
||||
var file = (em.getInstallLocation(MY_ID)
|
||||
.getItemFile(MY_ID, "chrome/skin/skins/default.css")
|
||||
.parent);
|
||||
return file;
|
||||
},
|
||||
|
||||
// file: nsILocalFile / data: string
|
||||
_writeToFile: function SS__writeToFile(file, data) {
|
||||
try {
|
||||
var foStream = (Cc["@mozilla.org/network/file-output-stream;1"]
|
||||
.createInstance(Ci.nsIFileOutputStream));
|
||||
foStream.init(file, 0x02 | 0x08 | 0x20, 0644, 0);
|
||||
foStream.write(data, data.length);
|
||||
foStream.close();
|
||||
} catch (e) {
|
||||
//errorToLocalize
|
||||
Cu.reportError("Error writing Ubiquity skin to " + file.path +
|
||||
"\n" + e);
|
||||
}
|
||||
},
|
||||
|
||||
_writeToLocalUrl: function SS__writeToLocalUrl(url, data) {
|
||||
var file = this._getSkinFolder();
|
||||
file.append(url.slice(url.lastIndexOf("/") + 1));
|
||||
this._writeToFile(file, data);
|
||||
SkinSvc.readMetaData({css: data, localUrl: url, noCache: true});
|
||||
},
|
||||
|
||||
_randomKey: function SS__randomKey() Math.random().toString(36).slice(-8),
|
||||
|
||||
_hackCssForBug466: function SS__hackCssForBug466(cssPath, sss, action) {
|
||||
if (cssPath.spec === "chrome://ubiquity/skin/skins/experimental.css" &&
|
||||
Utils.OS === "Darwin") {
|
||||
let hackCss =
|
||||
Utils.url("chrome://ubiquity/skin/skins/experimental-466hack.css");
|
||||
if (action === "register")
|
||||
sss.loadAndRegisterSheet(hackCss, sss.USER_SHEET);
|
||||
else if (sss.sheetRegistered(hackCss, sss.USER_SHEET))
|
||||
sss.unregisterSheet(hackCss, sss.USER_SHEET);
|
||||
}
|
||||
},
|
||||
|
||||
_hackCssForBug717: function SS__hackCssForBug717(cssPath, sss, action) {
|
||||
if (cssPath.spec === "chrome://ubiquity/skin/skins/default.css" &&
|
||||
Utils.OS === "Darwin" &&
|
||||
let (VC = (Cc["@mozilla.org/xpcom/version-comparator;1"]
|
||||
.getService(Ci.nsIVersionComparator)),
|
||||
XULAI = (Cc["@mozilla.org/xre/app-info;1"]
|
||||
.getService(Ci.nsIXULAppInfo))
|
||||
) VC.compare(XULAI.version, "3.1") < 0) {
|
||||
let hackCss =
|
||||
Utils.url("chrome://ubiquity/skin/skins/default-717hack.css");
|
||||
if (action === "register")
|
||||
sss.loadAndRegisterSheet(hackCss, sss.USER_SHEET);
|
||||
else if (sss.sheetRegistered(hackCss, sss.USER_SHEET))
|
||||
sss.unregisterSheet(hackCss, sss.USER_SHEET);
|
||||
}
|
||||
},
|
||||
|
||||
//Check if the skin from this URL has already been installed
|
||||
isInstalled: function SS_isInstalled(url) {
|
||||
var selStmt = this._createStatement(
|
||||
"SELECT COUNT(*) FROM ubiquity_skin_memory " +
|
||||
"WHERE download_uri = ?1");
|
||||
selStmt.bindUTF8StringParameter(0, url);
|
||||
var count = selStmt.executeStep() ? selStmt.getInt32(0) : 0;
|
||||
selStmt.finalize();
|
||||
return count !== 0;
|
||||
},
|
||||
|
||||
//Add a new skin record into the database
|
||||
addSkin: function SS_addSkin(downloadUrl, localUrl) {
|
||||
var insStmt = this._createStatement(
|
||||
"INSERT INTO ubiquity_skin_memory VALUES (?1, ?2)");
|
||||
insStmt.bindUTF8StringParameter(0, downloadUrl);
|
||||
insStmt.bindUTF8StringParameter(1, localUrl);
|
||||
insStmt.execute();
|
||||
insStmt.finalize();
|
||||
},
|
||||
|
||||
deleteSkin: function SS_deleteSkin(url) {
|
||||
var delStmt = this._createStatement(
|
||||
"DELETE FROM ubiquity_skin_memory " +
|
||||
"WHERE local_uri = ?1 OR download_uri = ?2");
|
||||
delStmt.bindUTF8StringParameter(0, url);
|
||||
delStmt.bindUTF8StringParameter(1, url);
|
||||
delStmt.execute();
|
||||
delStmt.finalize();
|
||||
},
|
||||
|
||||
//Unregister any current skins
|
||||
//And load this new skin
|
||||
loadSkin: function SS_loadSkin(newSkinPath) {
|
||||
var sss = (Cc["@mozilla.org/content/style-sheet-service;1"]
|
||||
.getService(Ci.nsIStyleSheetService));
|
||||
try {
|
||||
// Remove the previous skin CSS
|
||||
var oldCss = Utils.url(this.currentSkin);
|
||||
if (sss.sheetRegistered(oldCss, sss.USER_SHEET))
|
||||
sss.unregisterSheet(oldCss, sss.USER_SHEET);
|
||||
this._hackCssForBug466(oldCss, sss, "unregister");
|
||||
this._hackCssForBug717(oldCss, sss, "unregister");
|
||||
} catch (e) {} // do nothing
|
||||
//Load the new skin CSS
|
||||
var newCss = Utils.url(newSkinPath);
|
||||
sss.loadAndRegisterSheet(newCss, sss.USER_SHEET);
|
||||
Utils.prefs.setValue(SKIN_PREF, newSkinPath);
|
||||
this._hackCssForBug466(newCss, sss, "register");
|
||||
this._hackCssForBug717(newCss, sss, "register");
|
||||
},
|
||||
|
||||
//Change the skin and notify
|
||||
changeSkin: function SS_changeSkin(newSkinPath) {
|
||||
try {
|
||||
this.loadSkin(newSkinPath);
|
||||
this._msgService.displayMessage(L("ubiquity.skinsvc.skinchanged"));
|
||||
} catch (e) {
|
||||
this.loadSkin(this.DEFAULT_SKIN);
|
||||
//errorToLocalize
|
||||
var msg = "Error applying Ubiquity skin from " + newSkinPath;
|
||||
this._msgService.displayMessage(msg);
|
||||
Cu.reportError(msg + " : " + e);
|
||||
}
|
||||
},
|
||||
|
||||
updateSkin: function SS_updateSkin(downloadUrl, localUrl) {
|
||||
var self = this;
|
||||
this._webJsm.jQuery.get(downloadUrl, null, function onSuccess(data) {
|
||||
self._writeToLocalUrl(localUrl, data);
|
||||
}, "text");
|
||||
},
|
||||
|
||||
updateAllSkins: function SS_updateAllSkins() {
|
||||
//Only have to update/download remote skins
|
||||
//Local skins are pointed at directly
|
||||
for each (var skin in this.skinList)
|
||||
if (skin.localUrl !== skin.downloadUrl)
|
||||
this.updateSkin(skin.downloadUrl, skin.localUrl);
|
||||
},
|
||||
|
||||
loadCurrentSkin: function SS_loadCurrentSkin() {
|
||||
try {
|
||||
this.loadSkin(this.currentSkin);
|
||||
} catch (e) {
|
||||
//If there's any error loading the current skin,
|
||||
//load the default and tell the user about the failure
|
||||
this.loadSkin(this.DEFAULT_SKIN);
|
||||
//errorToLocalize
|
||||
this._msgService.displayMessage(
|
||||
"Loading your current skin failed. The default skin will be loaded.");
|
||||
}
|
||||
},
|
||||
|
||||
install: function SS_install(remote, local) {
|
||||
this.addSkin(remote, local);
|
||||
this.changeSkin(local);
|
||||
Utils.tabs.reload(/^about:ubiquity\?settings\b/);
|
||||
},
|
||||
|
||||
uninstall: function SS_uninstall(url) {
|
||||
var {skinList} = this;
|
||||
EACH_SKIN: {
|
||||
for each (var {localUrl, downloadUrl} in skinList)
|
||||
if (localUrl !== downloadUrl &&
|
||||
localUrl === url || downloadUrl === url)
|
||||
break EACH_SKIN;
|
||||
return;
|
||||
}
|
||||
this.deleteSkin(url);
|
||||
var file = (Cc["@mozilla.org/network/protocol;1?name=file"]
|
||||
.createInstance(Ci.nsIFileProtocolHandler)
|
||||
.getFileFromURLSpec(localUrl));
|
||||
file.remove(false);
|
||||
if (localUrl === this.currentSkin)
|
||||
this.changeSkin(this.DEFAULT_SKIN);
|
||||
},
|
||||
|
||||
saveCustomSkin: function SS_saveCustomSkin(cssText) {
|
||||
this._writeToLocalUrl(this.CUSTOM_SKIN, cssText);
|
||||
},
|
||||
|
||||
saveAs: function SS_saveAs(cssText, defaultName) {
|
||||
const {nsIFilePicker} = Ci;
|
||||
var fp = Cc["@mozilla.org/filepicker;1"].createInstance(nsIFilePicker);
|
||||
fp.init(Utils.currentChromeWindow,
|
||||
L("ubiquity.skinsvc.saveyourskin"),
|
||||
nsIFilePicker.modeSave);
|
||||
fp.defaultString = defaultName || "";
|
||||
fp.appendFilter("CSS (*.css)", "*.css");
|
||||
var rv = fp.show();
|
||||
if (rv !== nsIFilePicker.returnOK &&
|
||||
rv !== nsIFilePicker.returnReplace)
|
||||
return null;
|
||||
this._writeToFile(fp.file, cssText);
|
||||
var {spec} = fp.fileURL;
|
||||
this.addSkin("data:,dev/null/" + this._randomKey(), spec);
|
||||
this.changeSkin(spec);
|
||||
SkinSvc.readMetaData({css: cssText, localUrl: spec, noCache: true});
|
||||
return fp.file.path;
|
||||
},
|
||||
|
||||
get currentSkin SS_getCurrentSkin()
|
||||
Utils.prefs.getValue(SKIN_PREF, this.DEFAULT_SKIN),
|
||||
|
||||
get skinList SS_getSkinList() {
|
||||
var list = [];
|
||||
var selStmt = this._createStatement(
|
||||
"SELECT local_uri, download_uri FROM ubiquity_skin_memory");
|
||||
while (selStmt.executeStep())
|
||||
list.push({
|
||||
localUrl: selStmt.getUTF8String(0),
|
||||
downloadUrl: selStmt.getUTF8String(1),
|
||||
__proto__: SkinSvc.SkinProto,
|
||||
});
|
||||
selStmt.finalize();
|
||||
return list;
|
||||
},
|
||||
};
|
||||
|
||||
SkinSvc.prototype.installToWindow = function installToWindow(window) {
|
||||
var self = this;
|
||||
function showNotification(targetDoc, skinUrl) {
|
||||
Utils.notify({
|
||||
target: targetDoc,
|
||||
label: L("ubiquity.skinsvc.newskinfound"),
|
||||
value: "ubiquity_notify_skin_available",
|
||||
priority: "INFO_MEDIUM",
|
||||
buttons: [{
|
||||
accessKey: "I",
|
||||
callback: onSubscribeClick,
|
||||
label: L("ubiquity.skinsvc.installskin"),
|
||||
}]});
|
||||
function onSubscribeClick(notification, button) {
|
||||
if (self._isLocalUrl(skinUrl)) self.install(skinUrl, skinUrl);
|
||||
else self._webJsm.jQuery.get(skinUrl, null, function onSuccess(data) {
|
||||
//Navigate to chrome://ubiquity/skin/skins/
|
||||
var file = self._getSkinFolder();
|
||||
//Select a random name for the file
|
||||
var filename = self._randomKey() + ".css";
|
||||
//Create the new file
|
||||
file.append(filename);
|
||||
file.createUnique(Ci.nsIFile.NORMAL_FILE_TYPE, 0644);
|
||||
//Write the downloaded CSS to the file
|
||||
self._writeToFile(file, data);
|
||||
var ios = (Cc["@mozilla.org/network/io-service;1"]
|
||||
.getService(Ci.nsIIOService));
|
||||
var {spec} = ios.newFileURI(file);
|
||||
//Add skin to DB and make it the current skin
|
||||
self.install(skinUrl, spec);
|
||||
SkinSvc.readMetaData({
|
||||
css: data, downloadUrl: skinUrl, localUrl: spec, noCache: true});
|
||||
}, "text");
|
||||
}
|
||||
}
|
||||
// Watch for any tags of the form <link rel="ubiquity-skin">
|
||||
// on pages and install the skin for them if they exist.
|
||||
window.addEventListener("DOMLinkAdded", function onLinkAdded({target}) {
|
||||
if (target.rel === "ubiquity-skin" && !self.isInstalled(target.href))
|
||||
showNotification(target.ownerDocument, target.href);
|
||||
}, false);
|
||||
};
|
Загрузка…
Ссылка в новой задаче