[Resolve merge conflicts
This commit is contained in:
commit
443310b1c4
22 changed files with 76 additions and 129 deletions
|
|
@ -1,7 +1,7 @@
|
|||
# This Evennia workflow will install Python dependencies, run tests with a variety of Python versions
|
||||
# For more information see: https://help.github.com/actions/language-and-framework-guides/using-python-with-github-actions
|
||||
|
||||
name: Evennia test-suite and coveralls
|
||||
name: test-suite
|
||||
|
||||
on:
|
||||
push:
|
||||
|
|
@ -14,11 +14,10 @@ jobs:
|
|||
runs-on: ubuntu-latest
|
||||
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
python-version: [3.7, 3.8]
|
||||
# TODO: mysql disabled, not able to connect to it so far
|
||||
TESTING_DB: ['sqlite3', 'postgresql'] # , 'mysql']
|
||||
fail-fast: False
|
||||
TESTING_DB: ['sqlite3', 'postgresql', 'mysql']
|
||||
|
||||
steps:
|
||||
|
||||
|
|
@ -36,7 +35,7 @@ jobs:
|
|||
uses: mirromutth/mysql-action@v1.1
|
||||
if: ${{ matrix.TESTING_DB == 'mysql'}}
|
||||
with:
|
||||
mysql version: '5.7'
|
||||
host port: 3306
|
||||
character set server: 'utf8mb4'
|
||||
collation server: 'utf8mb4_unicode_ci'
|
||||
mysql database: 'evennia'
|
||||
|
|
@ -72,10 +71,10 @@ jobs:
|
|||
- name: Install extra dependencies
|
||||
run: pip install -r requirements_extra.txt
|
||||
|
||||
- name: Install and initialize evennia
|
||||
- name: Initialize evennia
|
||||
run: |
|
||||
evennia --init testing_mygame
|
||||
cp .travis/${{ matrix.TESTING_DB }}_settings.py testing_mygame/server/conf/settings.py
|
||||
cp .github/workflows/${{ matrix.TESTING_DB }}_settings.py testing_mygame/server/conf/settings.py
|
||||
cd testing_mygame
|
||||
evennia migrate
|
||||
evennia collectstatic --noinput
|
||||
|
|
@ -86,18 +85,21 @@ jobs:
|
|||
coverage run --source=../evennia --omit=*/migrations/*,*/urls.py,*/test*.py,*.sh,*.txt,*.md,*.pyc,*.service ../bin/unix/evennia test --settings=settings --keepdb evennia
|
||||
coverage xml
|
||||
|
||||
# we only want to run coverall once, so we only do it for one of the matrix combinations
|
||||
# we only want to run coverall/codacy once, so we only do it for one of the matrix combinations
|
||||
# it's also not critical if pushing to either service fails (happens for PRs since env is not
|
||||
# available outside of the evennia org)
|
||||
- name: Send data to Coveralls
|
||||
if: ${{ matrix.TESTING_DB == 'sqlite3' && matrix.python-version == 3.7 }}
|
||||
continue-on-error: true
|
||||
continue-on-error: true
|
||||
env:
|
||||
COVERALLS_REPO_TOKEN: ${{ secrets.COVERALLS_REPO_TOKEN }}
|
||||
run: |
|
||||
cd testing_mygame
|
||||
coveralls
|
||||
|
||||
- name: Send data to Codacy
|
||||
if: ${{ matrix.TESTING_DB == 'sqlite3' && matrix.python-version == 3.7 }}
|
||||
continue-on-error: true
|
||||
continue-on-error: true
|
||||
uses: codacy/codacy-coverage-reporter-action@master
|
||||
with:
|
||||
project-token: ${{ secrets.CODACY_PROJECT_TOKEN }}
|
||||
|
|
@ -44,18 +44,17 @@ DATABASES = {
|
|||
"NAME": "evennia",
|
||||
"USER": "evennia",
|
||||
"PASSWORD": "password",
|
||||
"HOST": "localhost",
|
||||
"HOST": "127.0.0.1",
|
||||
"PORT": "", # use default port
|
||||
"OPTIONS": {
|
||||
"charset": "utf8mb4",
|
||||
"init_command": "set collation_connection=utf8mb4_unicode_ci",
|
||||
},
|
||||
"TEST": {
|
||||
"NAME": "default",
|
||||
"NAME": "evennia",
|
||||
"OPTIONS": {
|
||||
"charset": "utf8mb4",
|
||||
# 'init_command': 'set collation_connection=utf8mb4_unicode_ci'
|
||||
"init_command": "SET NAMES 'utf8mb4'",
|
||||
"init_command": "set collation_connection=utf8mb4_unicode_ci",
|
||||
},
|
||||
},
|
||||
}
|
||||
52
.travis.yml
52
.travis.yml
|
|
@ -1,52 +0,0 @@
|
|||
dist: xenial
|
||||
language: python
|
||||
cache: pip
|
||||
|
||||
services:
|
||||
- postgresql
|
||||
- mysql
|
||||
|
||||
python:
|
||||
- "3.7"
|
||||
- "3.8"
|
||||
|
||||
env:
|
||||
- TESTING_DB=sqlite3
|
||||
- TESTING_DB=postgresql
|
||||
- TESTING_DB=mysql
|
||||
|
||||
before_install:
|
||||
|
||||
# - psql -U postgres -c "GRANT ALL PRIVILEGES ON DATABASE evennia TO evennia;"
|
||||
- psql --version
|
||||
- psql -U postgres -c "CREATE DATABASE evennia;"
|
||||
- psql -U postgres -c "CREATE USER evennia WITH PASSWORD 'password';"
|
||||
- psql -U postgres -c "ALTER USER evennia CREATEDB;"
|
||||
- mysql --version
|
||||
- mysql -u root -e "CREATE DATABASE evennia CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;"
|
||||
- mysql -u root -e "CREATE USER 'evennia'@'localhost' IDENTIFIED BY 'password';"
|
||||
- mysql -u root -e "GRANT ALL ON *.* TO 'evennia'@'localhost' IDENTIFIED BY 'password';"
|
||||
|
||||
install:
|
||||
- pip install psycopg2-binary
|
||||
- pip install mysqlclient
|
||||
- pip install coveralls
|
||||
- pip install codacy-coverage
|
||||
- pip install -e .
|
||||
- pip install -r requirements_extra.txt
|
||||
|
||||
before_script:
|
||||
- make format
|
||||
- evennia --init testing_mygame
|
||||
- cp .travis/${TESTING_DB}_settings.py testing_mygame/server/conf/settings.py
|
||||
- cd testing_mygame
|
||||
- evennia migrate
|
||||
- evennia collectstatic --noinput
|
||||
|
||||
script:
|
||||
- coverage run --source=../evennia --omit=*/migrations/*,*/urls.py,*/test*.py,*.sh,*.txt,*.md,*.pyc,*.service ../bin/unix/evennia test --settings=settings --keepdb evennia
|
||||
|
||||
after_success:
|
||||
- coveralls
|
||||
- coverage xml
|
||||
- python-codacy-coverage -r coverage.xml
|
||||
|
|
@ -1 +0,0 @@
|
|||
init_connect='SET collation_connection = utf8_general_ci; SET NAMES utf8;'
|
||||
|
|
@ -1,5 +1,6 @@
|
|||
# Evennia MUD/MU\* Creation System ![evennia logo][logo]
|
||||
[![Build Status][travisimg]][travislink] [![Coverage Status][coverimg]][coverlink]
|
||||
[![Build Status][unittestciimg]][unittestcilink] [![Coverage Status][coverimg]][coverlink]
|
||||
|
||||
|
||||
*Evennia* is a modern library for creating [online multiplayer text
|
||||
games][wikimudpage] (MUD, MUSH, MUX, MUCK, MOO etc) in pure Python. It
|
||||
|
|
@ -69,8 +70,8 @@ Welcome!
|
|||
[wiki]: https://github.com/evennia/evennia/wiki
|
||||
[screenshot]: https://user-images.githubusercontent.com/294267/30773728-ea45afb6-a076-11e7-8820-49be2168a6b8.png
|
||||
[logo]: https://github.com/evennia/evennia/blob/master/evennia/web/website/static/website/images/evennia_logo.png
|
||||
[travisimg]: https://travis-ci.org/evennia/evennia.svg?branch=master
|
||||
[travislink]: https://travis-ci.org/evennia/evennia
|
||||
[unittestciimg]: https://github.com/evennia/evennia/workflows/test-suite/badge.svg
|
||||
[unittestcilink]: https://github.com/evennia/evennia/actions?query=workflow%3Atest-suite
|
||||
[coverimg]: https://coveralls.io/repos/github/evennia/evennia/badge.svg?branch=master
|
||||
[coverlink]: https://coveralls.io/github/evennia/evennia?branch=master
|
||||
[introduction]: https://github.com/evennia/evennia/wiki/Evennia-Introduction
|
||||
|
|
|
|||
|
|
@ -3077,6 +3077,7 @@ class CmdScript(COMMAND_DEFAULT_CLASS):
|
|||
elif not self.switches:
|
||||
# view all scripts
|
||||
from evennia.commands.default.system import ScriptEvMore
|
||||
|
||||
ScriptEvMore(self.caller, scripts.order_by("id"), session=self.session)
|
||||
return
|
||||
elif "start" in self.switches:
|
||||
|
|
|
|||
|
|
@ -40,7 +40,6 @@ __all__ = (
|
|||
"CmdIRCStatus",
|
||||
"CmdRSS2Chan",
|
||||
"CmdGrapevine2Chan",
|
||||
|
||||
)
|
||||
_DEFAULT_WIDTH = settings.CLIENT_DEFAULT_WIDTH
|
||||
|
||||
|
|
|
|||
|
|
@ -441,7 +441,7 @@ class ScriptEvMore(EvMore):
|
|||
"|wdesc|n",
|
||||
align="r",
|
||||
border="tablecols",
|
||||
width=self.width
|
||||
width=self.width,
|
||||
)
|
||||
|
||||
for script in scripts:
|
||||
|
|
@ -572,7 +572,7 @@ class CmdScripts(COMMAND_DEFAULT_CLASS):
|
|||
caller.msg(string)
|
||||
else:
|
||||
# No stopping or validation. We just want to view things.
|
||||
ScriptEvMore(caller, scripts.order_by('id'), session=self.session)
|
||||
ScriptEvMore(caller, scripts.order_by("id"), session=self.session)
|
||||
|
||||
|
||||
class CmdObjects(COMMAND_DEFAULT_CLASS):
|
||||
|
|
|
|||
|
|
@ -1252,7 +1252,6 @@ class TestBuilding(CommandTest):
|
|||
)
|
||||
|
||||
def test_spawn(self):
|
||||
|
||||
def get_object(commandTest, obj_key):
|
||||
# A helper function to get a spawned object and
|
||||
# check that it exists in the process.
|
||||
|
|
|
|||
|
|
@ -893,7 +893,7 @@ class TestDice(CommandTest):
|
|||
# Test email-login
|
||||
|
||||
|
||||
from evennia.contrib import email_login # noqa
|
||||
from evennia.contrib import email_login # noqa
|
||||
|
||||
|
||||
class TestEmailLogin(CommandTest):
|
||||
|
|
|
|||
|
|
@ -39,7 +39,7 @@
|
|||
#
|
||||
|
||||
|
||||
#HEADER
|
||||
# HEADER
|
||||
|
||||
# everything in this block will be appended to the beginning of
|
||||
# all other #CODE blocks when they are executed.
|
||||
|
|
@ -51,7 +51,7 @@ from evennia import DefaultObject
|
|||
limbo = search_object("Limbo")[0]
|
||||
|
||||
|
||||
#CODE
|
||||
# CODE
|
||||
|
||||
# This is the first code block. Within each block, Python
|
||||
# code works as normal. Note how we make use if imports and
|
||||
|
|
@ -67,7 +67,7 @@ red_button = create_object(
|
|||
# we take a look at what we created
|
||||
caller.msg("A %s was created." % red_button.key)
|
||||
|
||||
#CODE
|
||||
# CODE
|
||||
|
||||
# this code block has 'table' and 'chair' set as deletable
|
||||
# objects. This means that when the batchcode processor runs in
|
||||
|
|
|
|||
|
|
@ -167,8 +167,9 @@ for mod in settings.PROTOTYPE_MODULES:
|
|||
if "prototype_locks" in prot
|
||||
else "use:all();edit:false()"
|
||||
),
|
||||
"prototype_tags": list(set(list(
|
||||
make_iter(prot.get("prototype_tags", []))) + ["module"])),
|
||||
"prototype_tags": list(
|
||||
set(list(make_iter(prot.get("prototype_tags", []))) + ["module"])
|
||||
),
|
||||
}
|
||||
)
|
||||
_MODULE_PROTOTYPES[actual_prot_key] = prot
|
||||
|
|
@ -392,35 +393,23 @@ def search_prototype(key=None, tags=None, require_single=False, return_iterators
|
|||
# exact match on tag(s)
|
||||
tags = make_iter(tags)
|
||||
tag_categories = ["db_prototype" for _ in tags]
|
||||
db_matches = DbPrototype.objects.get_by_tag(
|
||||
tags, tag_categories)
|
||||
db_matches = DbPrototype.objects.get_by_tag(tags, tag_categories)
|
||||
else:
|
||||
db_matches = DbPrototype.objects.all()
|
||||
|
||||
if key:
|
||||
# exact or partial match on key
|
||||
exact_match = (
|
||||
db_matches
|
||||
.filter(
|
||||
Q(db_key__iexact=key))
|
||||
.order_by("db_key")
|
||||
)
|
||||
exact_match = db_matches.filter(Q(db_key__iexact=key)).order_by("db_key")
|
||||
if not exact_match:
|
||||
# try with partial match instead
|
||||
db_matches = (
|
||||
db_matches
|
||||
.filter(
|
||||
Q(db_key__icontains=key))
|
||||
.order_by("db_key")
|
||||
)
|
||||
db_matches = db_matches.filter(Q(db_key__icontains=key)).order_by("db_key")
|
||||
else:
|
||||
db_matches = exact_match
|
||||
|
||||
# convert to prototype
|
||||
db_ids = db_matches.values_list("id", flat=True)
|
||||
db_matches = (
|
||||
Attribute.objects
|
||||
.filter(scriptdb__pk__in=db_ids, db_key="prototype")
|
||||
Attribute.objects.filter(scriptdb__pk__in=db_ids, db_key="prototype")
|
||||
.values_list("db_value", flat=True)
|
||||
.order_by("scriptdb__db_key")
|
||||
)
|
||||
|
|
@ -501,7 +490,7 @@ class PrototypeEvMore(EvMore):
|
|||
else:
|
||||
# get the correct slice, adjusted for the db-prototypes
|
||||
pageno = max(0, pageno - self._npages_db)
|
||||
return modprot_list[pageno * self.height: pageno * self.height + self.height]
|
||||
return modprot_list[pageno * self.height : pageno * self.height + self.height]
|
||||
|
||||
def page_formatter(self, page):
|
||||
"""Input is a queryset page from django.Paginator"""
|
||||
|
|
@ -517,7 +506,7 @@ class PrototypeEvMore(EvMore):
|
|||
"|wDesc|n",
|
||||
border="tablecols",
|
||||
crop=True,
|
||||
width=self.width
|
||||
width=self.width,
|
||||
)
|
||||
|
||||
for prototype in page:
|
||||
|
|
@ -554,8 +543,9 @@ class PrototypeEvMore(EvMore):
|
|||
return str(table)
|
||||
|
||||
|
||||
def list_prototypes(caller, key=None, tags=None, show_non_use=False,
|
||||
show_non_edit=True, session=None):
|
||||
def list_prototypes(
|
||||
caller, key=None, tags=None, show_non_use=False, show_non_edit=True, session=None
|
||||
):
|
||||
"""
|
||||
Collate a list of found prototypes based on search criteria and access.
|
||||
|
||||
|
|
@ -581,10 +571,14 @@ def list_prototypes(caller, key=None, tags=None, show_non_use=False,
|
|||
return None
|
||||
|
||||
# get specific prototype (one value or exception)
|
||||
return PrototypeEvMore(caller, (dbprot_query, modprot_list),
|
||||
session=session,
|
||||
show_non_use=show_non_use,
|
||||
show_non_edit=show_non_edit)
|
||||
return PrototypeEvMore(
|
||||
caller,
|
||||
(dbprot_query, modprot_list),
|
||||
session=session,
|
||||
show_non_use=show_non_use,
|
||||
show_non_edit=show_non_edit,
|
||||
)
|
||||
|
||||
|
||||
def validate_prototype(
|
||||
prototype, protkey=None, protparents=None, is_prototype_base=True, strict=True, _flags=None
|
||||
|
|
|
|||
|
|
@ -630,10 +630,8 @@ class TestPrototypeStorage(EvenniaTest):
|
|||
|
||||
# partial match
|
||||
with mock.patch("evennia.prototypes.prototypes._MODULE_PROTOTYPES", {}):
|
||||
self.assertCountEqual(
|
||||
protlib.search_prototype("prot"), [prot1b, prot2, prot3])
|
||||
self.assertCountEqual(
|
||||
protlib.search_prototype(tags="foo1"), [prot1b, prot2, prot3])
|
||||
self.assertCountEqual(protlib.search_prototype("prot"), [prot1b, prot2, prot3])
|
||||
self.assertCountEqual(protlib.search_prototype(tags="foo1"), [prot1b, prot2, prot3])
|
||||
|
||||
self.assertTrue(str(str(protlib.list_prototypes(self.char1))))
|
||||
|
||||
|
|
@ -1078,6 +1076,7 @@ class TestOLCMenu(TestEvMenu):
|
|||
],
|
||||
]
|
||||
|
||||
|
||||
class PrototypeCrashTest(EvenniaTest):
|
||||
|
||||
# increase this to 1000 for optimization testing
|
||||
|
|
@ -1089,9 +1088,9 @@ class PrototypeCrashTest(EvenniaTest):
|
|||
# print(f"Creating {num} additional prototypes...")
|
||||
for x in range(num):
|
||||
prot = {
|
||||
'prototype_key': str(uuid.uuid4()),
|
||||
'some_attributes': [str(uuid.uuid4()) for x in range(10)],
|
||||
'prototype_tags': list(sample(['demo', 'test', 'stuff'], 2)),
|
||||
"prototype_key": str(uuid.uuid4()),
|
||||
"some_attributes": [str(uuid.uuid4()) for x in range(10)],
|
||||
"prototype_tags": list(sample(["demo", "test", "stuff"], 2)),
|
||||
}
|
||||
protlib.save_prototype(prot)
|
||||
|
||||
|
|
@ -1101,5 +1100,5 @@ class PrototypeCrashTest(EvenniaTest):
|
|||
self.create(num_prototypes)
|
||||
# print("Attempting to list prototypes...")
|
||||
# start_time = time()
|
||||
self.char1.execute_cmd('spawn/list')
|
||||
self.char1.execute_cmd("spawn/list")
|
||||
# print(f"Prototypes listed in {time()-start_time} seconds.")
|
||||
|
|
|
|||
|
|
@ -344,8 +344,10 @@ class TickerHandler(object):
|
|||
raise TypeError(f"{callback} is not a callable function or method.")
|
||||
|
||||
if outobj and not inherits_from(outobj, "evennia.typeclasses.models.TypedObject"):
|
||||
raise TypeError(f"{callback} is a method on a normal object - it must "
|
||||
"be either a method on a typeclass, or a stand-alone function.")
|
||||
raise TypeError(
|
||||
f"{callback} is a method on a normal object - it must "
|
||||
"be either a method on a typeclass, or a stand-alone function."
|
||||
)
|
||||
|
||||
return outobj, outpath, outcallfunc
|
||||
|
||||
|
|
|
|||
|
|
@ -176,17 +176,14 @@ def node_start(wizard):
|
|||
node_game_index_start,
|
||||
{},
|
||||
),
|
||||
"2": ("MSSP setup (for mud-list crawlers)",
|
||||
node_mssp_start, {}
|
||||
),
|
||||
"2": ("MSSP setup (for mud-list crawlers)", node_mssp_start, {}),
|
||||
# "3": ("Add Grapevine listing",
|
||||
# node_grapevine_start, {}),
|
||||
# "4": ("Add IRC link",
|
||||
# "node_irc_start", {}),
|
||||
# "5" ("Add RSS feed",
|
||||
# "node_rss_start", {}),
|
||||
"s": ("View and (optionally) Save created settings",
|
||||
node_view_and_apply_settings, {}),
|
||||
"s": ("View and (optionally) Save created settings", node_view_and_apply_settings, {}),
|
||||
"q": ("Quit", lambda *args: sys.exit(), {}),
|
||||
}
|
||||
|
||||
|
|
@ -263,7 +260,7 @@ def node_game_index_fields(wizard, status=None):
|
|||
return True
|
||||
|
||||
wizard.display(text)
|
||||
wizard.game_index_listing['game_name'] = wizard.ask_input(
|
||||
wizard.game_index_listing["game_name"] = wizard.ask_input(
|
||||
default=name_default, validator=name_validator
|
||||
)
|
||||
|
||||
|
|
@ -494,8 +491,9 @@ def node_view_and_apply_settings(wizard):
|
|||
|
||||
# game index
|
||||
game_index_save_text = ""
|
||||
game_index_listing = (wizard.game_index_listing if
|
||||
hasattr(wizard, "game_index_listing") else None)
|
||||
game_index_listing = (
|
||||
wizard.game_index_listing if hasattr(wizard, "game_index_listing") else None
|
||||
)
|
||||
if not game_index_listing and settings.GAME_INDEX_ENABLED:
|
||||
game_index_listing = settings.GAME_INDEX_LISTING
|
||||
if game_index_listing:
|
||||
|
|
|
|||
|
|
@ -1278,8 +1278,11 @@ def check_main_evennia_dependencies():
|
|||
# only the main version (1.5, not 1.5.4.0)
|
||||
dversion_main = ".".join(dversion.split(".")[:2])
|
||||
if LooseVersion(dversion) < LooseVersion(DJANGO_MIN):
|
||||
print(ERROR_DJANGO_MIN.format(dversion=dversion_main, django_min=DJANGO_MIN,
|
||||
django_lt=DJANGO_LT))
|
||||
print(
|
||||
ERROR_DJANGO_MIN.format(
|
||||
dversion=dversion_main, django_min=DJANGO_MIN, django_lt=DJANGO_LT
|
||||
)
|
||||
)
|
||||
error = True
|
||||
elif LooseVersion(DJANGO_LT) <= LooseVersion(dversion_main):
|
||||
print(NOTE_DJANGO_NEW.format(dversion=dversion_main, django_rec=DJANGO_LT))
|
||||
|
|
|
|||
|
|
@ -87,6 +87,7 @@ class TelnetProtocol(Telnet, StatefulTelnetProtocol, _BASE_SESSION_CLASS):
|
|||
super().dataReceived(data)
|
||||
except ValueError as err:
|
||||
from evennia.utils import logger
|
||||
|
||||
logger.log_err(f"Malformed telnet input: {err}")
|
||||
|
||||
def connectionMade(self):
|
||||
|
|
|
|||
|
|
@ -339,7 +339,6 @@ class EvMore(object):
|
|||
# goto top of the text
|
||||
self.page_top()
|
||||
|
||||
|
||||
# default paginators - responsible for extracting a specific page number
|
||||
|
||||
def paginator_index(self, pageno):
|
||||
|
|
@ -351,7 +350,7 @@ class EvMore(object):
|
|||
Paginate by slice. This is done with an eye on memory efficiency (usually for
|
||||
querysets); to avoid fetching all objects at the same time.
|
||||
"""
|
||||
return self._data[pageno * self.height: pageno * self.height + self.height]
|
||||
return self._data[pageno * self.height : pageno * self.height + self.height]
|
||||
|
||||
def paginator_django(self, pageno):
|
||||
"""
|
||||
|
|
|
|||
|
|
@ -2100,9 +2100,11 @@ def at_search_result(matches, caller, query="", quiet=False, **kwargs):
|
|||
# we need to consider Commands, where .aliases is a list
|
||||
aliases = result.aliases.all() if hasattr(result.aliases, "all") else result.aliases
|
||||
# remove any pluralization aliases
|
||||
aliases = [alias for alias in aliases if
|
||||
hasattr(alias, "category")
|
||||
and alias.category not in ("plural_key", )]
|
||||
aliases = [
|
||||
alias
|
||||
for alias in aliases
|
||||
if hasattr(alias, "category") and alias.category not in ("plural_key",)
|
||||
]
|
||||
error += _MULTIMATCH_TEMPLATE.format(
|
||||
number=num + 1,
|
||||
name=result.get_display_name(caller)
|
||||
|
|
|
|||
|
|
@ -535,6 +535,7 @@ let goldenlayout = (function () {
|
|||
onText: onText,
|
||||
getGL: function () { return myLayout; },
|
||||
addKnownType: addKnownType,
|
||||
onTabCreate: onTabCreate,
|
||||
}
|
||||
}());
|
||||
window.plugin_handler.add("goldenlayout", goldenlayout);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue