Contents

Want Dracula Theme in Oracle APEX Page Designer? Of course you do… This step-by-step tutorial will show you how to enable it!

Instructions

Here is what you need to do:

1. Install Violentmonkey by clicking on one of the Installation options. Alternatively, if you cannot install Violentmonkey, this method also works absolutely fine in Tampermonkey

2. Open APEX

3. Click the Violentmonkey browser extension icon and click the ➕ icon

4. Replace all the code with this code and click Save & Close

// ==UserScript==
// @name         Oracle APEX Monaco Editor Theme Changer
// @namespace    http://tampermonkey.net/
// @version      24.2.1
// @description  Apply Custom themes to Monaco Editor in Oracle APEX
// @match        *://*/ords/*
// @match        *://*/pls/*
// @grant        GM_addStyle
// @author       Matt Mulvaney - Pretius
// @twitter      @Matt_Mulvaney
// ==/UserScript==

// ===== USER SETTINGS =====
const xyzUserTheme = 'dracula'; // Change this to switch themes
// ==========================

// Monaco Editor Theme Manager
const XYZMonacoThemeManager = (function() {
    // Private theme definitions
    const themes = {
    dracula: {
        base: "vs-dark",
        inherit: false,
        rules: [
        { background: "#282a36" },
        { foreground: "6272a4", token: "comment" },
        { foreground: "f1fa8c", token: "string" },
        { foreground: "bd93f9", token: "constant.numeric" },
        { foreground: "bd93f9", token: "constant.language" },
        { foreground: "bd93f9", token: "constant.character" },
        { foreground: "bd93f9", token: "constant.other" },
        { foreground: "ffb86c", token: "variable.other.readwrite.instance" },
        { foreground: "ff79c6", token: "constant.character.escaped" },
        { foreground: "ff79c6", token: "constant.character.escape" },
        { foreground: "ff79c6", token: "string source" },
        { foreground: "ff79c6", token: "string source.ruby" },
        { foreground: "ff79c6", token: "keyword" },
        { foreground: "ff79c6", token: "storage" },
        { foreground: "8be9fd", fontStyle: "italic", token: "storage.type" },
        { foreground: "50fa7b", fontStyle: "underline", token: "entity.name.class" },
        { foreground: "50fa7b", fontStyle: "italic underline", token: "entity.other.inherited-class" },
        { foreground: "50fa7b", token: "entity.name.function" },
        { foreground: "ffb86c", fontStyle: "italic", token: "variable.parameter" },
        { foreground: "ff79c6", token: "entity.name.tag" },
        { foreground: "50fa7b", token: "entity.other.attribute-name" },
        { foreground: "8be9fd", token: "support.function" },
        { foreground: "6be5fd", token: "support.constant" },
        { foreground: "66d9ef", fontStyle: " italic", token: "support.type" },
        { foreground: "66d9ef", fontStyle: " italic", token: "support.class" },
        { foreground: "f8f8f0", background: "ff79c6", token: "invalid" },
        { foreground: "f8f8f0", background: "bd93f9", token: "invalid.deprecated" },
        { foreground: "cfcfc2", token: "meta.structure.dictionary.json string.quoted.double.json" },
        { foreground: "6272a4", token: "meta.diff" },
        { foreground: "6272a4", token: "meta.diff.header" },
        { foreground: "ff79c6", token: "markup.deleted" },
        { foreground: "50fa7b", token: "markup.inserted" },
        { foreground: "e6db74", token: "markup.changed" },
        { foreground: "bd93f9", token: "constant.numeric.line-number.find-in-files - match" },
        { foreground: "e6db74", token: "entity.name.filename" },
        { foreground: "f83333", token: "message.error" },
        { foreground: "eeeeee", token: "punctuation.definition.string.begin.json - meta.structure.dictionary.value.json" },
        { foreground: "eeeeee", token: "punctuation.definition.string.end.json - meta.structure.dictionary.value.json" },
        { foreground: "8be9fd", token: "meta.structure.dictionary.json string.quoted.double.json" },
        { foreground: "f1fa8c", token: "meta.structure.dictionary.value.json string.quoted.double.json" },
        { foreground: "50fa7b", token: "meta meta meta meta meta meta meta.structure.dictionary.value string" },
        { foreground: "ffb86c", token: "meta meta meta meta meta meta.structure.dictionary.value string" },
        { foreground: "ff79c6", token: "meta meta meta meta meta.structure.dictionary.value string" },
        { foreground: "bd93f9", token: "meta meta meta meta.structure.dictionary.value string" },
        { foreground: "50fa7b", token: "meta meta meta.structure.dictionary.value string" },
        { foreground: "ffb86c", token: "meta meta.structure.dictionary.value string" },
        { foreground: "f8f8f2", token: "atom" },
        { foreground: "f8f8f2", token: "identifier" },
        { foreground: "50fa7b", token: "function" },
        { foreground: "f8f8f2", token: "delimiter" },
        { foreground: "ff79c6", token: "operator" },
        { foreground: "f8f8f2", token: "" },
        { foreground: "f8f8f2", token: "predefined" },
        { foreground: "bd93f9", token: "number" },
        { foreground: "ff79c6", token: "tag" },
        { foreground: "50fa7b", token: "attribute.name" },
        { foreground: "f1fa8c", token: "attribute.value" },
        { foreground: "6272a4", token: "comment.html" },
        { foreground: "f8f8f2", token: "text.html" }
        ],
        colors: {
        "editor.foreground": "#f8f8f2",
        "editor.background": "#282a36",
        "editor.selectionBackground": "#44475a",
        "editor.lineHighlightBackground": "#44475a",
        "editorCursor.foreground": "#f8f8f0",
        "editorWhitespace.foreground": "#3B3A32",
        "editorIndentGuide.activeBackground": "#9D550FB0",
        "editor.selectionHighlightBorder": "#222218"
        }
    },
    // You can add more themes here in the future
    };

    // APEX environment check
    function isApexEnvironmentValid() {
    return typeof apex !== 'undefined' &&
            typeof apex.env !== 'undefined' &&
            typeof apex.env.APP_ID !== 'undefined' &&
            parseInt(apex.env.APP_ID, 10) >= 3000 &&
            parseInt(apex.env.APP_ID, 10) <= 8999;
    }

    // Private methods
    function defineTheme(themeName) {
    const theme = themes[themeName];
    if (theme) {
        monaco.editor.defineTheme(`xyz-${themeName}`, theme);
    } else {
        console.error(`Theme '${themeName}' not found`);
    }
    }

    function switchTheme(themeName) {
    defineTheme(themeName);
    monaco.editor.setTheme(`xyz-${themeName}`);
    }

    // Public methods
    return {
    initializeEditor: function() {
        if (typeof monaco === 'object' && isApexEnvironmentValid()) {
        monaco.editor.onDidCreateEditor(() => {
            this.switchToTheme(xyzUserTheme);
        });
        this.switchToTheme(xyzUserTheme);
        } else {
        window.addEventListener('load', () => this.initializeEditor());
        }
    },
    switchToTheme: function(themeName) {
        setTimeout(() => switchTheme(themeName), 0);
    },
    addTheme: function(themeName, themeDefinition) {
        themes[themeName] = themeDefinition;
    }
    };
})();

// Initialize the Monaco Editor with the theme manager
XYZMonacoThemeManager.initializeEditor();

5. Reload APEX & you’ll see a purple counter

6. Open any Oracle APEX Monaco Code Editor to check that the Dracula Theme is working

7. Enjoy!

Conclusion

And that’s about it. It’s worth mentioning that this method also supports JavaScript, CSS and HTML. Of course, you can get the Dracula Theme for VSCode too. For more APEX-related content, check out some of the other articles on the Pretius blog:

  1. SQLcl Project Reference: A summary of everything you need to know
  2. APEX User Interface Defaults: A deep dive into Table Dictionary and Attribute Dictionary
  3. Globalization in APEX: A deep dive into Multi-Language and Locales
  4. Sorting in APEX: A deep dive into Classic Reports and Card Regions
  5. Oracle APEX deprecated APIs: How to spot them with a simple regex search
Share