-
Notifications
You must be signed in to change notification settings - Fork 91
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
firefox-scripts dont work on 136.0b2 #341
Comments
se here: #333 FF Nightly 136a With the fixes mentioned in the thread, got these scripts working as of feb 3:
Supposed to work:
These scripts are still broken:
if a script isn't listed here is because I don't use it. On the other hand All legacy extensions that I use (save file to, rehost image, pilfer, norwell history, downthemall, dorando keyconfig and backtrack tab history) have been disabled with no option to enable, about:config option to ignore signatures is greyed out, would need to wait for extensions updates |
StyloaiX works partially. The browser can "read" the codes and apply them, but it's not possible to activate, deactivate, create or edit styles. |
Try edit files in \utils\styloaix autocomplete.js /* 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/. */
"use strict";
const AutocompletePopup = require('devtools/client/shared/autocomplete-popup');
let loader;
try {
({ loader } = ChromeUtils.importESModule('resource://devtools/shared/loader/Loader.sys.mjs'));
} catch (e) {
// tb91
({ loader } = ChromeUtils.importESModule('resource://devtools/shared/Loader.sys.mjs'));
}
loader.lazyRequireGetter(
this,
"KeyCodes",
"devtools/client/shared/keycodes",
true
);
loader.lazyRequireGetter(
this,
"CSSCompleter",
"devtools/client/shared/sourceeditor/css-autocompleter"
);
const autocompleteMap = new WeakMap();
/**
* Prepares an editor instance for autocompletion.
*/
function initializeAutoCompletion(ctx, options = {}) {
const { cm, ed, Editor } = ctx;
if (autocompleteMap.has(ed)) {
return;
}
const win = ed.container.contentWindow.wrappedJSObject;
const { CodeMirror } = win;
let completer = null;
const autocompleteKey =
"Ctrl-" + Editor.keyFor("autocompletion", { noaccel: true });
if (ed.config.mode == Editor.modes.css) {
completer = new CSSCompleter({
walker: options.walker,
cssProperties: options.cssProperties,
maxEntries: 1000,
});
}
function insertSelectedPopupItem() {
const autocompleteState = autocompleteMap.get(ed);
if (!popup || !popup.isOpen || !autocompleteState) {
return false;
}
if (!autocompleteState.suggestionInsertedOnce && popup.selectedItem) {
autocompleteMap.get(ed).insertingSuggestion = true;
insertPopupItem(ed, popup.selectedItem);
}
popup.once("popup-closed", () => {
// This event is used in tests.
ed.emit("popup-hidden");
});
popup.hidePopup();
return true;
}
// Give each popup a new name to avoid sharing the elements.
let popup = new AutocompletePopup(win.parent.document, {
position: "bottom",
autoSelect: true,
onClick: insertSelectedPopupItem,
});
const cycle = reverse => {
if (popup?.isOpen) {
// eslint-disable-next-line mozilla/no-compare-against-boolean-literals
cycleSuggestions(ed, reverse == true);
return null;
}
return CodeMirror.Pass;
};
let keyMap = {
Tab: cycle,
Down: cycle,
"Shift-Tab": cycle.bind(null, true),
Up: cycle.bind(null, true),
Enter: () => {
const wasHandled = insertSelectedPopupItem();
return wasHandled ? true : CodeMirror.Pass;
},
};
const autoCompleteCallback = autoComplete.bind(null, ctx);
const keypressCallback = onEditorKeypress.bind(null, ctx);
keyMap[autocompleteKey] = autoCompleteCallback;
cm.addKeyMap(keyMap);
cm.on("keydown", keypressCallback);
ed.on("change", autoCompleteCallback);
ed.on("destroy", destroy);
function destroy() {
ed.off("destroy", destroy);
cm.off("keydown", keypressCallback);
ed.off("change", autoCompleteCallback);
cm.removeKeyMap(keyMap);
popup.destroy();
keyMap = popup = completer = null;
autocompleteMap.delete(ed);
}
autocompleteMap.set(ed, {
popup: popup,
completer: completer,
keyMap: keyMap,
destroy: destroy,
insertingSuggestion: false,
suggestionInsertedOnce: false,
});
}
/**
* Provides suggestions to autocomplete the current token/word being typed.
*/
function autoComplete({ ed, cm }) {
const autocompleteOpts = autocompleteMap.get(ed);
const { completer, popup } = autocompleteOpts;
if (
!completer ||
autocompleteOpts.insertingSuggestion ||
autocompleteOpts.doNotAutocomplete
) {
autocompleteOpts.insertingSuggestion = false;
return;
}
const cur = ed.getCursor();
completer
.complete(cm.getRange({ line: 0, ch: 0 }, cur), cur)
.then(suggestions => {
if (
!suggestions ||
!suggestions.length ||
suggestions[0].preLabel == null
) {
autocompleteOpts.suggestionInsertedOnce = false;
popup.once("popup-closed", () => {
// This event is used in tests.
ed.emit("after-suggest");
});
popup.hidePopup();
return;
}
// The cursor is at the end of the currently entered part of the token,
// like "backgr|" but we need to open the popup at the beginning of the
// character "b". Thus we need to calculate the width of the entered part
// of the token ("backgr" here).
const cursorElement = cm.display.cursorDiv.querySelector(
".CodeMirror-cursor"
);
const left = suggestions[0].preLabel.length * cm.defaultCharWidth();
popup.hidePopup();
popup.setItems(suggestions);
popup.once("popup-opened", () => {
// This event is used in tests.
ed.emit("after-suggest");
});
popup.openPopup(cursorElement, -1 * left, 0);
autocompleteOpts.suggestionInsertedOnce = false;
})
.catch(console.error);
}
/**
* Inserts a popup item into the current cursor location
* in the editor.
*/
function insertPopupItem(ed, popupItem) {
const { preLabel, text } = popupItem;
const cur = ed.getCursor();
const textBeforeCursor = ed.getText(cur.line).substring(0, cur.ch);
const backwardsTextBeforeCursor = textBeforeCursor
.split("")
.reverse()
.join("");
const backwardsPreLabel = preLabel
.split("")
.reverse()
.join("");
// If there is additional text in the preLabel vs the line, then
// just insert the entire autocomplete text. An example:
// if you type 'a' and select '#about' from the autocomplete menu,
// then the final text needs to the end up as '#about'.
if (backwardsPreLabel.indexOf(backwardsTextBeforeCursor) === 0) {
ed.replaceText(text, { line: cur.line, ch: 0 }, cur);
} else {
ed.replaceText(text.slice(preLabel.length), cur, cur);
}
}
/**
* Cycles through provided suggestions by the popup in a top to bottom manner
* when `reverse` is not true. Opposite otherwise.
*/
function cycleSuggestions(ed, reverse) {
const autocompleteOpts = autocompleteMap.get(ed);
const { popup } = autocompleteOpts;
const cur = ed.getCursor();
autocompleteOpts.insertingSuggestion = true;
if (!autocompleteOpts.suggestionInsertedOnce) {
autocompleteOpts.suggestionInsertedOnce = true;
let firstItem;
if (reverse) {
firstItem = popup.getItemAtIndex(popup.itemCount - 1);
popup.selectPreviousItem();
} else {
firstItem = popup.getItemAtIndex(0);
if (firstItem.label == firstItem.preLabel && popup.itemCount > 1) {
firstItem = popup.getItemAtIndex(1);
popup.selectNextItem();
}
}
if (popup.itemCount == 1) {
popup.hidePopup();
}
insertPopupItem(ed, firstItem);
} else {
const fromCur = {
line: cur.line,
ch: cur.ch - popup.selectedItem.text.length,
};
if (reverse) {
popup.selectPreviousItem();
} else {
popup.selectNextItem();
}
ed.replaceText(popup.selectedItem.text, fromCur, cur);
}
// This event is used in tests.
ed.emit("suggestion-entered");
}
/**
* onkeydown handler for the editor instance to prevent autocompleting on some
* keypresses.
*/
function onEditorKeypress({ ed, Editor }, cm, event) {
const autocompleteOpts = autocompleteMap.get(ed);
// Do not try to autocomplete with multiple selections.
if (ed.hasMultipleSelections()) {
autocompleteOpts.doNotAutocomplete = true;
autocompleteOpts.popup.hidePopup();
return;
}
if (
(event.ctrlKey || event.metaKey) &&
event.keyCode == KeyCodes.DOM_VK_SPACE
) {
// When Ctrl/Cmd + Space is pressed, two simultaneous keypresses are emitted
// first one for just the Ctrl/Cmd and second one for combo. The first one
// leave the autocompleteOpts.doNotAutocomplete as true, so we have to make
// it false
autocompleteOpts.doNotAutocomplete = false;
return;
}
if (event.ctrlKey || event.metaKey || event.altKey) {
autocompleteOpts.doNotAutocomplete = true;
autocompleteOpts.popup.hidePopup();
return;
}
switch (event.keyCode) {
case KeyCodes.DOM_VK_RETURN:
autocompleteOpts.doNotAutocomplete = true;
break;
case KeyCodes.DOM_VK_ESCAPE:
if (autocompleteOpts.popup.isOpen) {
// Prevent the Console input to open, but still remove the autocomplete popup.
autocompleteOpts.doNotAutocomplete = true;
autocompleteOpts.popup.hidePopup();
event.preventDefault();
}
break;
case KeyCodes.DOM_VK_LEFT:
case KeyCodes.DOM_VK_RIGHT:
case KeyCodes.DOM_VK_HOME:
case KeyCodes.DOM_VK_END:
autocompleteOpts.doNotAutocomplete = true;
autocompleteOpts.popup.hidePopup();
break;
case KeyCodes.DOM_VK_BACK_SPACE:
case KeyCodes.DOM_VK_DELETE:
if (ed.config.mode == Editor.modes.css) {
autocompleteOpts.completer.invalidateCache(ed.getCursor().line);
}
autocompleteOpts.doNotAutocomplete = true;
autocompleteOpts.popup.hidePopup();
break;
default:
autocompleteOpts.doNotAutocomplete = false;
}
}
// Export functions
exports.initializeAutoCompletion = initializeAutoCompletion; edit.js const { NetUtil } = ChromeUtils.importESModule('resource://gre/modules/NetUtil.sys.mjs');
const { require } = ChromeUtils.importESModule('resource://devtools/shared/loader/Loader.sys.mjs');
docShell.cssErrorReportingEnabled = true;
function require_mini (m) {
let scope = {
exports: {}
};
Services.scriptloader.loadSubScript('chrome://' + m + '.js', scope);
return scope.exports;
};
let url;
let type;
let id;
let style;
if (isChromeWindow) {
let params = window.arguments[0];
url = params.url;
type = params.type;
id = params.id;
} else {
let params = new URLSearchParams(location.search);
url = params.get('url');
type = params.get('type');
id = params.get('id');
}
origin = 1;
let lastOrigin;
let unsaved = false;
let previewCode;
let previewOrigin;
let previewActive = false;
let isInstantPreview;
let isInstantCheck;
let timeoutRunning = false;
let interval;
let nameE;
let initialCode = '';
let sourceEditor;
function init () {
if (id)
style = UC.styloaix.styles.get(id);
if (style) {
origin = style.type;
readFile(style.url, initEditor);
} else {
if (url)
initialCode = '@-moz-document ' + type + '("' + url + '") {\n\n\n}';
initEditor();
}
nameE = document.getElementById('name');
nameE.value = style?.name || '';
updateTitle();
nameE.addEventListener('input', function () {
unsaved = true;
toggleUI('save-button', true);
});
document.getElementById('origin').value = origin;
document.getElementById('errors').addEventListener('click', function (e) {
if (e.target == this)
this.style.display = 'none';
});
isInstantPreview = xPref.get(UC.styloaix.PREF_INSTANTPREVIEW);
document.getElementById('instant-preview').checked = isInstantPreview;
isInstantCheck = xPref.get(UC.styloaix.PREF_INSTANTCHECK);
document.getElementById('instant-check').checked = isInstantCheck;
if (style?.enabled === false)
toggleUI('preview-button', true);
interval = xPref.get(UC.styloaix.PREF_INSTANTINTERVAL);
xPref.addListener(UC.styloaix.PREF_INSTANTINTERVAL, function (ms) {
interval = ms;
});
}
function initEditor () {
const Editor = require('devtools/client/shared/sourceeditor/editor');
const extraKeys = {
[Editor.accel('S')]: save,
'F3': 'findNext',
'Shift-F3': 'findPrev'
};
const lineWrapping = xPref.get(UC.styloaix.PREF_LINEWRAPPING);
document.getElementById('wrap-lines').checked = lineWrapping;
sourceEditor = new Editor({
mode: Editor.modes.css,
contextMenu: 'sourceEditorContextMenu',
extraKeys: extraKeys,
lineNumbers: true,
lineWrapping: lineWrapping,
value: initialCode,
maxHighlightLength: 10000
});
// https://searchfox.org/mozilla-central/source/devtools/client/shared/test/shared-head.js#2284-2295
function getClientCssProperties() {
const {
generateCssProperties,
} = require('resource://devtools/server/actors/css-properties.js');
const {
CssProperties,
normalizeCssData,
} = require('resource://devtools/client/fronts/css-properties.js');
return new CssProperties(
normalizeCssData({ properties: generateCssProperties(document) })
);
}
sourceEditor.setupAutoCompletion = function () {
this.extend(require_mini('userchromejs/content/styloaix/autocomplete'));
this.initializeAutoCompletion({ cssProperties: getClientCssProperties() });
};
document.getElementById('editor').selectedIndex = 1;
sourceEditor.appendTo(document.getElementById('sourceeditor')).then(function () {
sourceEditor.insertCommandsController();
sourceEditor.focus();
if (isInstantCheck)
checkForErrors();
});
sourceEditor.on('change', function () {
changed();
if (!isInstantCheck)
toggleUI('check-for-errors-button', true);
});
}
function readFile (url, fun) {
NetUtil.asyncFetch(
{
uri: url,
loadingNode: document,
securityFlags: Ci.nsILoadInfo.SEC_ALLOW_CROSS_ORIGIN_INHERITS_SEC_CONTEXT || Ci.nsILoadInfo.SEC_ALLOW_CROSS_ORIGIN_DATA_INHERITS,
contentPolicyType: Ci.nsIContentPolicy.TYPE_OTHER,
},
async function (stream) {
const bstream = Cc['@mozilla.org/binaryinputstream;1'].createInstance(Ci.nsIBinaryInputStream);
bstream.setInputStream(stream);
try {
initialCode = bstream.readBytes(bstream.available());
} catch {}
stream.close();
try {
const converter = Cc['@mozilla.org/intl/scriptableunicodeconverter'].createInstance(Ci.nsIScriptableUnicodeConverter);
converter.charset = 'utf-8';
initialCode = converter.ConvertToUnicode(initialCode);
} catch {}
fun?.();
}
);
}
function changed () {
if ((isInstantPreview || isInstantCheck) && !timeoutRunning)
instantTimeout();
unsaved = true;
toggleUI('save-button', true);
if (!isInstantPreview)
toggleUI('preview-button', true);
}
function instantTimeout () {
timeoutRunning = true;
setTimeout(() => {
if (isInstantPreview) {
processPreview();
toggleUI('preview-button', false);
if (origin === _uc.sss.AGENT_SHEET || lastOrigin === _uc.sss.AGENT_SHEET) {
lastOrigin = origin;
UC.styloaix.forceRefresh();
}
}
if (isInstantCheck)
checkForErrors();
timeoutRunning = false;
}, interval)
}
function save () {
if (!nameE.value)
return alert('Style name must not be empty.');
if (style)
style.unregister();
const finalTitle = nameE.value + (origin == 0 ? '.as' : origin == 1 ? '.us' : '') + '.css';
const file = UC.styloaix.CSSDIR.clone();
file.append(finalTitle);
if (!file.exists())
file.createUnique(Ci.nsIFile.NORMAL_FILE_TYPE, 0o644/*FileUtils.PERMS_FILE*/);
const ostream = Cc['@mozilla.org/network/file-output-stream;1'].createInstance(Ci.nsIFileOutputStream);
ostream.init(file, -1, -1, 0);
const istream = Cc["@mozilla.org/io/string-input-stream;1"].createInstance(Ci.nsIStringInputStream);
istream.setUTF8Data(codeElementWrapper.value);
NetUtil.asyncCopy(istream, ostream, function (aResult) {
if (Components.isSuccessCode(aResult)) {
const enabled = style ? style.enabled : true;
if (style && finalTitle != style.fullName) {
const oldFile = UC.styloaix.CSSDIR.clone()
oldFile.append(style.fullName);
oldFile.remove(false);
UC.styloaix.styles.delete(style.fullName);
if (!enabled) {
UC.styloaix.disabledStyles.add(finalTitle);
UC.styloaix.disabledStyles.delete(oldFile.leafName);
}
}
style = new UC.styloaix.UserStyle(file);
style.enabled = enabled;
updateTitle();
UC.styloaix.styles.set(style.fullName, style);
if (UC.styloaix.enabled && enabled) {
style.register();
toggleUI('preview-button', false);
if (previewActive) {
_uc.sss.unregisterSheet(previewCode, previewOrigin);
previewActive = false;
if (origin === _uc.sss.AGENT_SHEET || lastOrigin === _uc.sss.AGENT_SHEET)
UC.styloaix.forceRefresh();
}
}
unsaved = false;
toggleUI('save-button', false);
} else {
alert('Error!');
}
})
sourceEditor.focus();
}
function updateTitle () {
document.title = (style?.fullName || 'New Style') + ' - StyloaiX Editor';
}
function toggleUI (id, state) {
document.getElementById(id).disabled = !state;
}
function processPreview () {
let lastPreviewCode = previewCode;
let lastpreviewOrigin = previewOrigin;
previewCode = Services.io.newURI('data:text/css;charset=UTF-8,' + encodeURIComponent(codeElementWrapper.value));
previewOrigin = origin;
_uc.sss.loadAndRegisterSheet(previewCode, previewOrigin);
if (previewActive)
_uc.sss.unregisterSheet(lastPreviewCode, lastpreviewOrigin);
else if (style?.enabled)
style.unregister();
previewActive = true;
}
function preview () {
processPreview();
if (origin === _uc.sss.AGENT_SHEET || lastOrigin === _uc.sss.AGENT_SHEET) {
lastOrigin = origin;
UC.styloaix.forceRefresh();
}
checkForErrors();
toggleUI('preview-button', false);
sourceEditor.focus();
}
function checkForErrors () {
const errors = document.getElementById('errors');
errors.style.display = 'none';
while (errors.hasChildNodes())
errors.lastChild.remove();
let count = 0;
const errorListener = {
observe: (message) => {
if (!count)
errors.style.display = 'block';
const error = message.QueryInterface(Ci.nsIScriptError);
const errMsg = error.lineNumber + ':' + error.columnNumber + ' - ' + error.errorMessage;
const label = document.createElement('label');
label.appendChild(document.createTextNode(errMsg));
label.addEventListener('click', function () {
goToLine(error.lineNumber, error.columnNumber);
});
errors.appendChild(label);
errors.appendChild(document.createElement('br'));
count++;
if (count == 10) {
errors.appendChild(document.createTextNode('...'));
Services.console.unregisterListener(this);
}
}
}
Services.console.registerListener(errorListener);
const styleEl = document.createElement('style');
styleEl.appendChild(document.createTextNode(codeElementWrapper.value));
document.documentElement.appendChild(styleEl);
styleEl.remove();
setTimeout(() => {
if (count < 10)
Services.console.unregisterListener(errorListener);
});
toggleUI('check-for-errors-button', false);
sourceEditor.focus();
}
function goToLine (line, col) {
sourceEditor.focus();
sourceEditor.setCursor({line: line - 1, ch: col});
}
function insertCodeAtStart (snippet) {
let position = codeElementWrapper.value.indexOf(snippet);
if (position == -1) {
codeElementWrapper.value = snippet + '\n' + codeElementWrapper.value;
position = 0;
}
const positionEnd = position + snippet.length;
codeElementWrapper.setSelectionRange(positionEnd, positionEnd);
sourceEditor.focus();
}
function insertCodeAtCaret (snippet) {
const selectionStart = codeElementWrapper.selectionStart;
const selectionEnd = selectionStart + snippet.length;
codeElementWrapper.value = codeElementWrapper.value.substring(0, codeElementWrapper.selectionStart) + snippet + codeElementWrapper.value.substring(codeElementWrapper.selectionEnd, codeElementWrapper.value.length);
codeElementWrapper.setSelectionRange(selectionEnd, selectionEnd);
sourceEditor.focus();
}
function changeWordWrap (bool, persist) {
if (persist)
xPref.set(UC.styloaix.PREF_LINEWRAPPING, bool);
sourceEditor.setOption('lineWrapping', bool);
sourceEditor.focus();
}
function instantPreview (bool, persist) {
if (persist)
xPref.set(UC.styloaix.PREF_INSTANTPREVIEW, bool);
isInstantPreview = bool
if (isInstantPreview && !timeoutRunning)
instantTimeout();
sourceEditor.focus();
}
function instantCheck (bool, persist) {
if (persist)
xPref.set(UC.styloaix.PREF_INSTANTCHECK, bool);
isInstantCheck = bool
if (isInstantCheck && !timeoutRunning)
instantTimeout();
sourceEditor.focus();
}
function insertDataURI() {
const fp = Cc['@mozilla.org/filepicker;1'].createInstance(Ci.nsIFilePicker);
fp.init(window, 'Choose File…', Ci.nsIFilePicker.modeOpen);
fp.open(res => {
if (res != Ci.nsIFilePicker.returnOK)
return;
const contentType = Cc['@mozilla.org/mime;1'].getService(Ci.nsIMIMEService).getTypeFromFile(fp.file);
const inputStream = Cc['@mozilla.org/network/file-input-stream;1'].createInstance(Ci.nsIFileInputStream);
inputStream.init(fp.file, parseInt('01', 16), parseInt('0600', 8), 0);
const stream = Cc['@mozilla.org/binaryinputstream;1'].createInstance(Ci.nsIBinaryInputStream);
stream.setInputStream(inputStream);
const encoded = btoa(stream.readBytes(stream.available()));
stream.close();
inputStream.close();
insertCodeAtCaret('data:' + contentType + ';base64,' + encoded);
});
}
const codeElementWrapper = {
get value() {
return sourceEditor.getText();
},
set value(v) {
sourceEditor.setText(v);
},
setSelectionRange: function (start, end) {
sourceEditor.setSelection(sourceEditor.getPosition(start), sourceEditor.getPosition(end));
},
get selectionStart() {
return sourceEditor.getOffset(sourceEditor.getCursor('start'));
},
get selectionEnd() {
return sourceEditor.getOffset(sourceEditor.getCursor('end'));
},
}
const closeFn = window.close;
let shouldHandle = true;
function closeWithoutAsking () {
shouldHandle = false;
closeFn();
}
function confirmClose () {
if (confirm('Do you want to close and lose unsaved changes?')) {
shouldHandle = false;
setTimeout(closeFn);
}
}
if (isChromeWindow) {
window.close = function () {
if (!unsaved)
return closeWithoutAsking();
if (style) {
readFile(style.url, function () {
const hasChanges = initialCode !== codeElementWrapper.value;
hasChanges ? confirmClose() : closeWithoutAsking();
});
} else {
codeElementWrapper.value ? confirmClose() : closeWithoutAsking();
}
}
}
window.addEventListener('close', function (e) {
e.preventDefault();
window.close();
})
window.addEventListener('beforeunload', function (e) {
if (shouldHandle && unsaved)
e.preventDefault();
});
window.addEventListener('unload', function (event) {
if (style?.enabled && previewActive)
style.register();
if (previewActive) {
_uc.sss.unregisterSheet(previewCode, previewOrigin);
if (origin === _uc.sss.AGENT_SHEET || lastOrigin === _uc.sss.AGENT_SHEET)
UC.styloaix.forceRefresh();
}
});
window.addEventListener('DOMContentLoaded', init, {once: true}); |
Thanks for trying to help. I used these modifications but it didn't work. The same problems I already reported continue. |
In the latest 136.0b2 update, firefox-scripts stopped working. I tried installing again with file replacement.
The text was updated successfully, but these errors were encountered: