}
}
--
cgit v1.2.3-70-g09d2
From 02c5628bdaf43100a6e40baab781342bc27df464 Mon Sep 17 00:00:00 2001
From: 0x85FB9C51 <77808164+0x85FB9C51@users.noreply.github.com>
Date: Wed, 21 Jul 2021 12:46:13 -0400
Subject: fixed the fact that text, number, and boolean were ignoring input
types when accepting input
---
.../collectionSchema/CollectionSchemaCells.tsx | 114 +++++++++++++--------
1 file changed, 69 insertions(+), 45 deletions(-)
(limited to 'src')
diff --git a/src/client/views/collections/collectionSchema/CollectionSchemaCells.tsx b/src/client/views/collections/collectionSchema/CollectionSchemaCells.tsx
index a8d901f4d..8b7fb9be8 100644
--- a/src/client/views/collections/collectionSchema/CollectionSchemaCells.tsx
+++ b/src/client/views/collections/collectionSchema/CollectionSchemaCells.tsx
@@ -214,6 +214,55 @@ export class CollectionSchemaCell extends React.Component {
positions.pop();
}
}
+
+ // handles input procedures for string cells
+ let stringInput = (value: string, retVal: boolean): void => {
+ let valueSansQuotes = value;
+ if (this._isEditing) {
+ const vsqLength = valueSansQuotes.length;
+ // get rid of outer quotes
+ valueSansQuotes = valueSansQuotes.substring(value.startsWith("\"") ? 1 : 0,
+ valueSansQuotes.charAt(vsqLength - 1) == "\"" ? vsqLength - 1 : vsqLength);
+ }
+ let inputAsString = '"';
+ // escape any quotes in the string
+ for (const i of valueSansQuotes) {
+ if (i == '"') {
+ inputAsString += '\\"';
+ } else {
+ inputAsString += i;
+ }
+ }
+ // add a closing quote
+ inputAsString += '"';
+ //two options here: we can strip off outer quotes or we can figure out what's going on with the script
+ const script = CompileScript(inputAsString, { requiredType: type, typecheck: false, editable: true, addReturn: true, params: { this: Doc.name, $r: "number", $c: "number", $: "any" } });
+ const changeMade = inputAsString.length !== value.length || inputAsString.length - 2 !== value.length
+ script.compiled && (retVal = this.applyToDoc(changeMade ? this._rowDoc : this._rowDataDoc, this.props.row, this.props.col, script.run));
+ }
+
+ // handles input procedure for number cells
+ let numberInput = (value: string, retVal: boolean): void => {
+ const inputscript = value.substring(value.startsWith("=") ? 1 : 0);
+ // if commas are not stripped, the parser only considers the numbers after the last comma
+ let inputSansCommas = "";
+ for (let s of inputscript) {
+ if (!(s == ",")) {
+ inputSansCommas += s;
+ }
+ }
+ const script = CompileScript(inputSansCommas, { requiredType: type, typecheck: false, editable: true, addReturn: true, params: { this: Doc.name, $r: "number", $c: "number", $: "any" } });
+ const changeMade = value.length !== value.length || value.length - 2 !== value.length
+ script.compiled && (retVal = this.applyToDoc(changeMade ? this._rowDoc : this._rowDataDoc, this.props.row, this.props.col, script.run));
+ }
+
+ // handles input procedure for boolean cells
+ let boolInput = (value: string, retVal: boolean): void => {
+ const script = CompileScript(value, { requiredType: type, typecheck: false, editable: true, addReturn: true, params: { this: Doc.name, $r: "number", $c: "number", $: "any" } });
+ const changeMade = value.length !== value.length || value.length - 2 !== value.length
+ script.compiled && (retVal = this.applyToDoc(changeMade ? this._rowDoc : this._rowDataDoc, this.props.row, this.props.col, script.run));
+ }
+
const placeholder = type === "number" ? "0" : contents === "" ? "--" : "undefined";
return (
{
}
// check if the input is a boolean
let inputIsBool: boolean = value == "false" || value == "true";
- // what to do in the case
- if (!inputIsNum && !inputIsBool && !value.startsWith("=")) {
- // if it's not a number, it's a string, and should be processed as such
- // strips the string of quotes when it is edited to prevent quotes form being added to the text automatically
- // after each edit
- let valueSansQuotes = value;
- if (this._isEditing) {
- const vsqLength = valueSansQuotes.length;
- // get rid of outer quotes
- valueSansQuotes = valueSansQuotes.substring(value.startsWith("\"") ? 1 : 0,
- valueSansQuotes.charAt(vsqLength - 1) == "\"" ? vsqLength - 1 : vsqLength);
- }
- let inputAsString = '"';
- // escape any quotes in the string
- for (const i of valueSansQuotes) {
- if (i == '"') {
- inputAsString += '\\"';
- } else {
- inputAsString += i;
- }
- }
- // add a closing quote
- inputAsString += '"';
- //two options here: we can strip off outer quotes or we can figure out what's going on with the script
- const script = CompileScript(inputAsString, { requiredType: type, typecheck: false, editable: true, addReturn: true, params: { this: Doc.name, $r: "number", $c: "number", $: "any" } });
- const changeMade = inputAsString.length !== value.length || inputAsString.length - 2 !== value.length
- script.compiled && (retVal = this.applyToDoc(changeMade ? this._rowDoc : this._rowDataDoc, this.props.row, this.props.col, script.run));
- // handle numbers and expressions
- } else if (inputIsNum || value.startsWith("=")) {
- //TODO: make accept numbers
- const inputscript = value.substring(value.startsWith("=") ? 1 : 0);
- // if commas are not stripped, the parser only considers the numbers after the last comma
- let inputSansCommas = "";
- for (let s of inputscript) {
- if (!(s == ",")) {
- inputSansCommas += s;
- }
+
+ if (type == undefined) {
+ // what to do in the case
+ if (!inputIsNum && !inputIsBool && !value.startsWith("=")) {
+ // if it's not a number, it's a string, and should be processed as such
+ // strips the string of quotes when it is edited to prevent quotes form being added to the text automatically
+ // after each edit
+ stringInput(value, retVal);
+ // handle numbers and expressions
+ } else if (inputIsNum || value.startsWith("=")) {
+ numberInput(value, retVal);
+ // handle booleans
+ } else if (inputIsBool) {
+ boolInput(value, retVal);
}
- const script = CompileScript(inputSansCommas, { requiredType: type, typecheck: false, editable: true, addReturn: true, params: { this: Doc.name, $r: "number", $c: "number", $: "any" } });
- const changeMade = value.length !== value.length || value.length - 2 !== value.length
- script.compiled && (retVal = this.applyToDoc(changeMade ? this._rowDoc : this._rowDataDoc, this.props.row, this.props.col, script.run));
- // handle booleans
- } else if (inputIsBool) {
- const script = CompileScript(value, { requiredType: type, typecheck: false, editable: true, addReturn: true, params: { this: Doc.name, $r: "number", $c: "number", $: "any" } });
- const changeMade = value.length !== value.length || value.length - 2 !== value.length
- script.compiled && (retVal = this.applyToDoc(changeMade ? this._rowDoc : this._rowDataDoc, this.props.row, this.props.col, script.run));
+ } else if (type == "string") {
+ stringInput(value, retVal);
+ } else if (type == "number" && inputIsNum) {
+ numberInput(value, retVal);
+ } else if (type == "boolean" && inputIsBool) {
+ boolInput(value, retVal);
}
}
if (retVal) {
--
cgit v1.2.3-70-g09d2
From ee0e2c6c53db65c5524b67ed09369cc0e0e6f173 Mon Sep 17 00:00:00 2001
From: 0x85FB9C51 <77808164+0x85FB9C51@users.noreply.github.com>
Date: Wed, 21 Jul 2021 16:10:04 -0400
Subject: Fixed minor bugs
---
.../collectionSchema/CollectionSchemaCells.tsx | 27 ++++++++++++++++++----
1 file changed, 23 insertions(+), 4 deletions(-)
(limited to 'src')
diff --git a/src/client/views/collections/collectionSchema/CollectionSchemaCells.tsx b/src/client/views/collections/collectionSchema/CollectionSchemaCells.tsx
index 8b7fb9be8..f7dfaaeb4 100644
--- a/src/client/views/collections/collectionSchema/CollectionSchemaCells.tsx
+++ b/src/client/views/collections/collectionSchema/CollectionSchemaCells.tsx
@@ -300,8 +300,16 @@ export class CollectionSchemaCell extends React.Component {
inputIsNum = false;
}
}
+
+ let contentsAreNum = true;
+ for (let s of contents) {
+ if (isNaN(parseInt(s)) && !(s == ".") && !(s == ",")) {
+ contentsAreNum = false;
+ }
+ }
// check if the input is a boolean
let inputIsBool: boolean = value == "false" || value == "true";
+ let contentsAreBool: boolean = contents == "false" || contents == "true";
if (type == undefined) {
// what to do in the case
@@ -317,12 +325,23 @@ export class CollectionSchemaCell extends React.Component {
} else if (inputIsBool) {
boolInput(value, retVal);
}
+ // if the cell type is a string
} else if (type == "string") {
stringInput(value, retVal);
- } else if (type == "number" && inputIsNum) {
- numberInput(value, retVal);
- } else if (type == "boolean" && inputIsBool) {
- boolInput(value, retVal);
+ // if the cell type is a number
+ } else if (type == "number") {
+ if (inputIsNum) {
+ numberInput(value, retVal);
+ } else if (!contentsAreNum) {
+ stringInput("", retVal);
+ }
+ // if the cell type is a boolean
+ } else if (type == "boolean") {
+ if (inputIsBool) {
+ boolInput(value, retVal);
+ } else if (!contentsAreBool) {
+ stringInput("", retVal);
+ }
}
}
if (retVal) {
--
cgit v1.2.3-70-g09d2
From 0b6a18bc445825ecf69f57b49b002ed5c8a13902 Mon Sep 17 00:00:00 2001
From: 0x85FB9C51 <77808164+0x85FB9C51@users.noreply.github.com>
Date: Mon, 26 Jul 2021 16:39:06 -0400
Subject: comments
---
src/fields/Doc.ts | 1 +
1 file changed, 1 insertion(+)
(limited to 'src')
diff --git a/src/fields/Doc.ts b/src/fields/Doc.ts
index bd0ba3ad7..e51eb44db 100644
--- a/src/fields/Doc.ts
+++ b/src/fields/Doc.ts
@@ -1251,6 +1251,7 @@ export namespace Doc {
if (typeof resolved === "object" && !(resolved instanceof Array)) {
output = convertObject(resolved, excludeEmptyObjects, title, appendToExisting?.targetDoc);
} else {
+ // give the proper types to the data extracted from the JSON
const result = toField(resolved, excludeEmptyObjects);
if (appendToExisting) {
(output = appendToExisting.targetDoc)[appendToExisting.fieldKey || defaultKey] = result;
--
cgit v1.2.3-70-g09d2
From b3fde759b304f6401595f4e43bb00cc6fa65c915 Mon Sep 17 00:00:00 2001
From: dinhanhtruong <70963346+dinhanhtruong@users.noreply.github.com>
Date: Thu, 29 Jul 2021 17:50:15 -0400
Subject: added message to empty tab screen
---
src/client/goldenLayout.js | 3056 ++++++++++----------
src/client/views/MainView.scss | 30 +-
.../views/collections/CollectionDockingView.scss | 23 +
3 files changed, 1574 insertions(+), 1535 deletions(-)
(limited to 'src')
diff --git a/src/client/goldenLayout.js b/src/client/goldenLayout.js
index 9cfea7f3f..7fca8d9d5 100644
--- a/src/client/goldenLayout.js
+++ b/src/client/goldenLayout.js
@@ -82,16 +82,16 @@
return target;
};
- /**
- * This is based on Paul Irish's shim, but looks quite odd in comparison. Why?
- * Because
- * a) it shouldn't affect the global requestAnimationFrame function
- * b) it shouldn't pass on the time that has passed
- *
- * @param {Function} fn
- *
- * @returns {void}
- */
+ /**
+ * This is based on Paul Irish's shim, but looks quite odd in comparison. Why?
+ * Because
+ * a) it shouldn't affect the global requestAnimationFrame function
+ * b) it shouldn't pass on the time that has passed
+ *
+ * @param {Function} fn
+ *
+ * @returns {void}
+ */
lm.utils.animFrame = function (fn) {
return (window.requestAnimationFrame ||
window.webkitRequestAnimationFrame ||
@@ -178,16 +178,16 @@
.replace('.', '');
};
- /**
- * A basic XSS filter. It is ultimately up to the
- * implementing developer to make sure their particular
- * applications and usecases are save from cross site scripting attacks
- *
- * @param {String} input
- * @param {Boolean} keepTags
- *
- * @returns {String} filtered input
- */
+ /**
+ * A basic XSS filter. It is ultimately up to the
+ * implementing developer to make sure their particular
+ * applications and usecases are save from cross site scripting attacks
+ *
+ * @param {String} input
+ * @param {Boolean} keepTags
+ *
+ * @returns {String} filtered input
+ */
lm.utils.filterXss = function (input, keepTags) {
var output = input
@@ -206,41 +206,41 @@
}
};
- /**
- * Removes html tags from a string
- *
- * @param {String} input
- *
- * @returns {String} input without tags
- */
+ /**
+ * Removes html tags from a string
+ *
+ * @param {String} input
+ *
+ * @returns {String} input without tags
+ */
lm.utils.stripTags = function (input) {
return $.trim(input.replace(/(<([^>]+)>)/ig, ''));
};
- /**
- * A generic and very fast EventEmitter
- * implementation. On top of emitting the
- * actual event it emits an
- *
- * lm.utils.EventEmitter.ALL_EVENT
- *
- * event for every event triggered. This allows
- * to hook into it and proxy events forwards
- *
- * @constructor
- */
+ /**
+ * A generic and very fast EventEmitter
+ * implementation. On top of emitting the
+ * actual event it emits an
+ *
+ * lm.utils.EventEmitter.ALL_EVENT
+ *
+ * event for every event triggered. This allows
+ * to hook into it and proxy events forwards
+ *
+ * @constructor
+ */
lm.utils.EventEmitter = function () {
this._mSubscriptions = {};
this._mSubscriptions[lm.utils.EventEmitter.ALL_EVENT] = [];
- /**
- * Listen for events
- *
- * @param {String} sEvent The name of the event to listen to
- * @param {Function} fCallback The callback to execute when the event occurs
- * @param {[Object]} oContext The value of the this pointer within the callback function
- *
- * @returns {void}
- */
+ /**
+ * Listen for events
+ *
+ * @param {String} sEvent The name of the event to listen to
+ * @param {Function} fCallback The callback to execute when the event occurs
+ * @param {[Object]} oContext The value of the this pointer within the callback function
+ *
+ * @returns {void}
+ */
this.on = function (sEvent, fCallback, oContext) {
if (!lm.utils.isFunction(fCallback)) {
throw new Error('Tried to listen to event ' + sEvent + ' with non-function callback ' + fCallback);
@@ -253,14 +253,14 @@
this._mSubscriptions[sEvent].push({ fn: fCallback, ctx: oContext });
};
- /**
- * Emit an event and notify listeners
- *
- * @param {String} sEvent The name of the event
- * @param {Mixed} various additional arguments that will be passed to the listener
- *
- * @returns {void}
- */
+ /**
+ * Emit an event and notify listeners
+ *
+ * @param {String} sEvent The name of the event
+ * @param {Mixed} various additional arguments that will be passed to the listener
+ *
+ * @returns {void}
+ */
this.emit = function (sEvent) {
var i, ctx, args;
@@ -286,15 +286,15 @@
}
};
- /**
- * Removes a listener for an event, or all listeners if no callback and context is provided.
- *
- * @param {String} sEvent The name of the event
- * @param {Function} fCallback The previously registered callback method (optional)
- * @param {Object} oContext The previously registered context (optional)
- *
- * @returns {void}
- */
+ /**
+ * Removes a listener for an event, or all listeners if no callback and context is provided.
+ *
+ * @param {String} sEvent The name of the event
+ * @param {Function} fCallback The previously registered callback method (optional)
+ * @param {Object} oContext The previously registered context (optional)
+ *
+ * @returns {void}
+ */
this.unbind = function (sEvent, fCallback, oContext) {
if (!this._mSubscriptions[sEvent]) {
throw new Error('No subscribtions to unsubscribe for event ' + sEvent);
@@ -318,28 +318,28 @@
}
};
- /**
- * Alias for unbind
- */
+ /**
+ * Alias for unbind
+ */
this.off = this.unbind;
- /**
- * Alias for emit
- */
+ /**
+ * Alias for emit
+ */
this.trigger = this.emit;
};
- /**
- * The name of the event that's triggered for every other event
- *
- * usage
- *
- * myEmitter.on( lm.utils.EventEmitter.ALL_EVENT, function( eventName, argsArray ){
- * //do stuff
- * });
- *
- * @type {String}
- */
+ /**
+ * The name of the event that's triggered for every other event
+ *
+ * usage
+ *
+ * myEmitter.on( lm.utils.EventEmitter.ALL_EVENT, function( eventName, argsArray ){
+ * //do stuff
+ * });
+ *
+ * @type {String}
+ */
lm.utils.EventEmitter.ALL_EVENT = '__all';
lm.utils.DragListener = function (eElement, nButtonCode) {
lm.utils.EventEmitter.call(this);
@@ -349,14 +349,14 @@
this._eBody = $(document.body);
this._nButtonCode = nButtonCode || 0;
- /**
- * The delay after which to start the drag in milliseconds
- */
+ /**
+ * The delay after which to start the drag in milliseconds
+ */
this._nDelay = 200;
- /**
- * The distance the mouse needs to be moved to qualify as a drag
- */
+ /**
+ * The distance the mouse needs to be moved to qualify as a drag
+ */
this._nDistance = 10;//TODO - works better with delay only
this._nX = 0;
@@ -459,16 +459,16 @@
};
}
});
- /**
- * The main class that will be exposed as GoldenLayout.
- *
- * @public
- * @constructor
- * @param {GoldenLayout config} config
- * @param {[DOM element container]} container Can be a jQuery selector string or a Dom element. Defaults to body
- *
- * @returns {VOID}
- */
+ /**
+ * The main class that will be exposed as GoldenLayout.
+ *
+ * @public
+ * @constructor
+ * @param {GoldenLayout config} config
+ * @param {[DOM element container]} container Can be a jQuery selector string or a Dom element. Defaults to body
+ *
+ * @returns {VOID}
+ */
lm.LayoutManager = function (config, container) {
if (!$ || typeof $.noConflict !== 'function') {
@@ -521,59 +521,59 @@
};
};
- /**
- * Hook that allows to access private classes
- */
+ /**
+ * Hook that allows to access private classes
+ */
lm.LayoutManager.__lm = lm;
- /**
- * Takes a GoldenLayout configuration object and
- * replaces its keys and values recursively with
- * one letter codes
- *
- * @static
- * @public
- * @param {Object} config A GoldenLayout config object
- *
- * @returns {Object} minified config
- */
+ /**
+ * Takes a GoldenLayout configuration object and
+ * replaces its keys and values recursively with
+ * one letter codes
+ *
+ * @static
+ * @public
+ * @param {Object} config A GoldenLayout config object
+ *
+ * @returns {Object} minified config
+ */
lm.LayoutManager.minifyConfig = function (config) {
return (new lm.utils.ConfigMinifier()).minifyConfig(config);
};
- /**
- * Takes a configuration Object that was previously minified
- * using minifyConfig and returns its original version
- *
- * @static
- * @public
- * @param {Object} minifiedConfig
- *
- * @returns {Object} the original configuration
- */
+ /**
+ * Takes a configuration Object that was previously minified
+ * using minifyConfig and returns its original version
+ *
+ * @static
+ * @public
+ * @param {Object} minifiedConfig
+ *
+ * @returns {Object} the original configuration
+ */
lm.LayoutManager.unminifyConfig = function (config) {
return (new lm.utils.ConfigMinifier()).unminifyConfig(config);
};
lm.utils.copy(lm.LayoutManager.prototype, {
- /**
- * Register a component with the layout manager. If a configuration node
- * of type component is reached it will look up componentName and create the
- * associated component
- *
- * {
- * type: "component",
- * componentName: "EquityNewsFeed",
- * componentState: { "feedTopic": "us-bluechips" }
- * }
- *
- * @public
- * @param {String} name
- * @param {Function} constructor
- *
- * @returns {void}
- */
+ /**
+ * Register a component with the layout manager. If a configuration node
+ * of type component is reached it will look up componentName and create the
+ * associated component
+ *
+ * {
+ * type: "component",
+ * componentName: "EquityNewsFeed",
+ * componentState: { "feedTopic": "us-bluechips" }
+ * }
+ *
+ * @public
+ * @param {String} name
+ * @param {Function} constructor
+ *
+ * @returns {void}
+ */
registerComponent: function (name, constructor) {
if (typeof constructor !== 'function') {
throw new Error('Please register a constructor function');
@@ -586,12 +586,12 @@
this._components[name] = constructor;
},
- /**
- * Creates a layout configuration object based on the the current state
- *
- * @public
- * @returns {Object} GoldenLayout configuration
- */
+ /**
+ * Creates a layout configuration object based on the the current state
+ *
+ * @public
+ * @returns {Object} GoldenLayout configuration
+ */
toConfig: function (root) {
var config, next, i;
@@ -603,18 +603,18 @@
throw new Error('Root must be a ContentItem');
}
- /*
- * settings & labels
- */
+ /*
+ * settings & labels
+ */
config = {
settings: lm.utils.copy({}, this.config.settings),
dimensions: lm.utils.copy({}, this.config.dimensions),
labels: lm.utils.copy({}, this.config.labels)
};
- /*
- * Content
- */
+ /*
+ * Content
+ */
config.content = [];
next = function (configNode, item) {
var key, i;
@@ -641,30 +641,30 @@
next(config, this.root);
}
- /*
- * Retrieve config for subwindows
- */
+ /*
+ * Retrieve config for subwindows
+ */
this._$reconcilePopoutWindows();
config.openPopouts = [];
for (i = 0; i < this.openPopouts.length; i++) {
config.openPopouts.push(this.openPopouts[i].toConfig());
}
- /*
- * Add maximised item
- */
+ /*
+ * Add maximised item
+ */
config.maximisedItemId = this._maximisedItem ? '__glMaximised' : null;
return config;
},
- /**
- * Returns a previously registered component
- *
- * @public
- * @param {String} name The name used
- *
- * @returns {Function}
- */
+ /**
+ * Returns a previously registered component
+ *
+ * @public
+ * @param {String} name The name used
+ *
+ * @returns {Function}
+ */
getComponent: function (name) {
if (this._components[name] === undefined) {
throw new lm.errors.ConfigurationError('Unknown component "' + name + '"');
@@ -673,44 +673,44 @@
return this._components[name];
},
- /**
- * Creates the actual layout. Must be called after all initial components
- * are registered. Recurses through the configuration and sets up
- * the item tree.
- *
- * If called before the document is ready it adds itself as a listener
- * to the document.ready event
- *
- * @public
- *
- * @returns {void}
- */
+ /**
+ * Creates the actual layout. Must be called after all initial components
+ * are registered. Recurses through the configuration and sets up
+ * the item tree.
+ *
+ * If called before the document is ready it adds itself as a listener
+ * to the document.ready event
+ *
+ * @public
+ *
+ * @returns {void}
+ */
init: function () {
- /**
- * Create the popout windows straight away. If popouts are blocked
- * an error is thrown on the same 'thread' rather than a timeout and can
- * be caught. This also prevents any further initilisation from taking place.
- */
+ /**
+ * Create the popout windows straight away. If popouts are blocked
+ * an error is thrown on the same 'thread' rather than a timeout and can
+ * be caught. This also prevents any further initilisation from taking place.
+ */
if (this._subWindowsCreated === false) {
this._createSubWindows();
this._subWindowsCreated = true;
}
- /**
- * If the document isn't ready yet, wait for it.
- */
+ /**
+ * If the document isn't ready yet, wait for it.
+ */
if (document.readyState === 'loading' || document.body === null) {
$(document).ready(lm.utils.fnBind(this.init, this));
return;
}
- /**
- * If this is a subwindow, wait a few milliseconds for the original
- * page's js calls to be executed, then replace the bodies content
- * with GoldenLayout
- */
+ /**
+ * If this is a subwindow, wait a few milliseconds for the original
+ * page's js calls to be executed, then replace the bodies content
+ * with GoldenLayout
+ */
if (this.isSubWindow === true && this._creationTimeoutPassed === false) {
setTimeout(lm.utils.fnBind(this.init, this), 7);
this._creationTimeoutPassed = true;
@@ -732,15 +732,15 @@
this.emit('initialised');
},
- /**
- * Updates the layout managers size
- *
- * @public
- * @param {[int]} width height in pixels
- * @param {[int]} height width in pixels
- *
- * @returns {void}
- */
+ /**
+ * Updates the layout managers size
+ *
+ * @public
+ * @param {[int]} width height in pixels
+ * @param {[int]} height width in pixels
+ *
+ * @returns {void}
+ */
updateSize: function (width, height) {
if (arguments.length === 2) {
this.width = width;
@@ -763,13 +763,13 @@
}
},
- /**
- * Destroys the LayoutManager instance itself as well as every ContentItem
- * within it. After this is called nothing should be left of the LayoutManager.
- *
- * @public
- * @returns {void}
- */
+ /**
+ * Destroys the LayoutManager instance itself as well as every ContentItem
+ * within it. After this is called nothing should be left of the LayoutManager.
+ *
+ * @public
+ * @returns {void}
+ */
destroy: function () {
if (this.isInitialised === false) {
return;
@@ -793,16 +793,16 @@
this._dragSources = [];
},
- /**
- * Recursively creates new item tree structures based on a provided
- * ItemConfiguration object
- *
- * @public
- * @param {Object} config ItemConfig
- * @param {[ContentItem]} parent The item the newly created item should be a child of
- *
- * @returns {lm.items.ContentItem}
- */
+ /**
+ * Recursively creates new item tree structures based on a provided
+ * ItemConfiguration object
+ *
+ * @public
+ * @param {Object} config ItemConfig
+ * @param {[ContentItem]} parent The item the newly created item should be a child of
+ *
+ * @returns {lm.items.ContentItem}
+ */
createContentItem: function (config, parent) {
var typeErrorMsg, contentItem;
@@ -823,9 +823,9 @@
}
- /**
- * We add an additional stack around every component that's not within a stack anyways.
- */
+ /**
+ * We add an additional stack around every component that's not within a stack anyways.
+ */
if (
// If this is a component
config.type === 'component' &&
@@ -851,17 +851,17 @@
return contentItem;
},
- /**
- * Creates a popout window with the specified content and dimensions
- *
- * @param {Object|lm.itemsAbstractContentItem} configOrContentItem
- * @param {[Object]} dimensions A map with width, height, left and top
- * @param {[String]} parentId the id of the element this item will be appended to
- * when popIn is called
- * @param {[Number]} indexInParent The position of this item within its parent element
+ /**
+ * Creates a popout window with the specified content and dimensions
+ *
+ * @param {Object|lm.itemsAbstractContentItem} configOrContentItem
+ * @param {[Object]} dimensions A map with width, height, left and top
+ * @param {[String]} parentId the id of the element this item will be appended to
+ * when popIn is called
+ * @param {[Number]} indexInParent The position of this item within its parent element
- * @returns {lm.controls.BrowserPopout}
- */
+ * @returns {lm.controls.BrowserPopout}
+ */
createPopout: function (configOrContentItem, dimensions, parentId, indexInParent) {
var config = configOrContentItem,
isItem = configOrContentItem instanceof lm.items.AbstractContentItem,
@@ -879,14 +879,14 @@
config = this.toConfig(configOrContentItem).content;
parentId = lm.utils.getUniqueId();
- /**
- * If the item is the only component within a stack or for some
- * other reason the only child of its parent the parent will be destroyed
- * when the child is removed.
- *
- * In order to support this we move up the tree until we find something
- * that will remain after the item is being popped out
- */
+ /**
+ * If the item is the only component within a stack or for some
+ * other reason the only child of its parent the parent will be destroyed
+ * when the child is removed.
+ *
+ * In order to support this we move up the tree until we find something
+ * that will remain after the item is being popped out
+ */
parent = configOrContentItem.parent;
child = configOrContentItem;
while (parent.contentItems.length === 1 && !parent.isRoot) {
@@ -946,16 +946,16 @@
return browserPopout;
},
- /**
- * Attaches DragListener to any given DOM element
- * and turns it into a way of creating new ContentItems
- * by 'dragging' the DOM element into the layout
- *
- * @param {jQuery DOM element} element
- * @param {Object|Function} itemConfig for the new item to be created, or a function which will provide it
- *
- * @returns {void}
- */
+ /**
+ * Attaches DragListener to any given DOM element
+ * and turns it into a way of creating new ContentItems
+ * by 'dragging' the DOM element into the layout
+ *
+ * @param {jQuery DOM element} element
+ * @param {Object|Function} itemConfig for the new item to be created, or a function which will provide it
+ *
+ * @returns {void}
+ */
createDragSource: function (element, itemConfig) {
this.config.settings.constrainDragToContainer = false;
var dragSource = new lm.controls.DragSource($(element), itemConfig, this);
@@ -964,17 +964,17 @@
return dragSource;
},
- /**
- * Programmatically selects an item. This deselects
- * the currently selected item, selects the specified item
- * and emits a selectionChanged event
- *
- * @param {lm.item.AbstractContentItem} item#
- * @param {[Boolean]} _$silent Wheather to notify the item of its selection
- * @event selectionChanged
- *
- * @returns {VOID}
- */
+ /**
+ * Programmatically selects an item. This deselects
+ * the currently selected item, selects the specified item
+ * and emits a selectionChanged event
+ *
+ * @param {lm.item.AbstractContentItem} item#
+ * @param {[Boolean]} _$silent Wheather to notify the item of its selection
+ * @event selectionChanged
+ *
+ * @returns {VOID}
+ */
selectItem: function (item, _$silent) {
if (this.config.settings.selectionEnabled !== true) {
@@ -998,9 +998,9 @@
this.emit('selectionChanged', item);
},
- /*************************
- * PACKAGE PRIVATE
- *************************/
+ /*************************
+ * PACKAGE PRIVATE
+ *************************/
_$maximiseItem: function (contentItem) {
if (this._maximisedItem !== null) {
this._$minimiseItem(this._maximisedItem);
@@ -1028,20 +1028,20 @@
this.emit('stateChanged');
},
- /**
- * This method is used to get around sandboxed iframe restrictions.
- * If 'allow-top-navigation' is not specified in the iframe's 'sandbox' attribute
- * (as is the case with codepens) the parent window is forbidden from calling certain
- * methods on the child, such as window.close() or setting document.location.href.
- *
- * This prevented GoldenLayout popouts from popping in in codepens. The fix is to call
- * _$closeWindow on the child window's gl instance which (after a timeout to disconnect
- * the invoking method from the close call) closes itself.
- *
- * @packagePrivate
- *
- * @returns {void}
- */
+ /**
+ * This method is used to get around sandboxed iframe restrictions.
+ * If 'allow-top-navigation' is not specified in the iframe's 'sandbox' attribute
+ * (as is the case with codepens) the parent window is forbidden from calling certain
+ * methods on the child, such as window.close() or setting document.location.href.
+ *
+ * This prevented GoldenLayout popouts from popping in in codepens. The fix is to call
+ * _$closeWindow on the child window's gl instance which (after a timeout to disconnect
+ * the invoking method from the close call) closes itself.
+ *
+ * @packagePrivate
+ *
+ * @returns {void}
+ */
_$closeWindow: function () {
window.setTimeout(function () {
window.close();
@@ -1088,13 +1088,13 @@
var i, area, allContentItems = this._getAllContentItems();
this._itemAreas = [];
- /**
- * If the last item is dragged out, highlight the entire container size to
- * allow to re-drop it. allContentItems[ 0 ] === this.root at this point
- *
- * Don't include root into the possible drop areas though otherwise since it
- * will used for every gap in the layout, e.g. splitters
- */
+ /**
+ * If the last item is dragged out, highlight the entire container size to
+ * allow to re-drop it. allContentItems[ 0 ] === this.root at this point
+ *
+ * Don't include root into the possible drop areas though otherwise since it
+ * will used for every gap in the layout, e.g. splitters
+ */
if (allContentItems.length === 1) {
this._itemAreas.push(this.root._$getArea());
return;
@@ -1124,18 +1124,18 @@
}
},
- /**
- * Takes a contentItem or a configuration and optionally a parent
- * item and returns an initialised instance of the contentItem.
- * If the contentItem is a function, it is first called
- *
- * @packagePrivate
- *
- * @param {lm.items.AbtractContentItem|Object|Function} contentItemOrConfig
- * @param {lm.items.AbtractContentItem} parent Only necessary when passing in config
- *
- * @returns {lm.items.AbtractContentItem}
- */
+ /**
+ * Takes a contentItem or a configuration and optionally a parent
+ * item and returns an initialised instance of the contentItem.
+ * If the contentItem is a function, it is first called
+ *
+ * @packagePrivate
+ *
+ * @param {lm.items.AbtractContentItem|Object|Function} contentItemOrConfig
+ * @param {lm.items.AbtractContentItem} parent Only necessary when passing in config
+ *
+ * @returns {lm.items.AbtractContentItem}
+ */
_$normalizeContentItem: function (contentItemOrConfig, parent) {
if (!contentItemOrConfig) {
throw new Error('No content item defined');
@@ -1158,15 +1158,15 @@
}
},
- /**
- * Iterates through the array of open popout windows and removes the ones
- * that are effectively closed. This is necessary due to the lack of reliably
- * listening for window.close / unload events in a cross browser compatible fashion.
- *
- * @packagePrivate
- *
- * @returns {void}
- */
+ /**
+ * Iterates through the array of open popout windows and removes the ones
+ * that are effectively closed. This is necessary due to the lack of reliably
+ * listening for window.close / unload events in a cross browser compatible fashion.
+ *
+ * @packagePrivate
+ *
+ * @returns {void}
+ */
_$reconcilePopoutWindows: function () {
var openPopouts = [], i;
@@ -1185,17 +1185,17 @@
},
- /***************************
- * PRIVATE
- ***************************/
- /**
- * Returns a flattened array of all content items,
- * regardles of level or type
- *
- * @private
- *
- * @returns {void}
- */
+ /***************************
+ * PRIVATE
+ ***************************/
+ /**
+ * Returns a flattened array of all content items,
+ * regardles of level or type
+ *
+ * @private
+ *
+ * @returns {void}
+ */
_getAllContentItems: function () {
var allContentItems = [];
@@ -1214,13 +1214,13 @@
return allContentItems;
},
- /**
- * Binds to DOM/BOM events on init
- *
- * @private
- *
- * @returns {void}
- */
+ /**
+ * Binds to DOM/BOM events on init
+ *
+ * @private
+ *
+ * @returns {void}
+ */
_bindEvents: function () {
if (this._isFullPage) {
$(window).resize(this._resizeFunction);
@@ -1228,27 +1228,27 @@
$(window).on('unload beforeunload', this._unloadFunction);
},
- /**
- * Debounces resize events
- *
- * @private
- *
- * @returns {void}
- */
+ /**
+ * Debounces resize events
+ *
+ * @private
+ *
+ * @returns {void}
+ */
_onResize: function () {
clearTimeout(this._resizeTimeoutId);
this._resizeTimeoutId = setTimeout(lm.utils.fnBind(this.updateSize, this), 100);
},
- /**
- * Extends the default config with the user specific settings and applies
- * derivations. Please note that there's a seperate method (AbstractContentItem._extendItemNode)
- * that deals with the extension of item configs
- *
- * @param {Object} config
- * @static
- * @returns {Object} config
- */
+ /**
+ * Extends the default config with the user specific settings and applies
+ * derivations. Please note that there's a seperate method (AbstractContentItem._extendItemNode)
+ * that deals with the extension of item configs
+ *
+ * @param {Object} config
+ * @static
+ * @returns {Object} config
+ */
_createConfig: function (config) {
var windowConfigKey = lm.utils.getQueryStringParam('gl-window');
@@ -1283,14 +1283,14 @@
return config;
},
- /**
- * This is executed when GoldenLayout detects that it is run
- * within a previously opened popout window.
- *
- * @private
- *
- * @returns {void}
- */
+ /**
+ * This is executed when GoldenLayout detects that it is run
+ * within a previously opened popout window.
+ *
+ * @private
+ *
+ * @returns {void}
+ */
_adjustToWindowMode: function () {
var popInButton = $('
' +
'' +
@@ -1310,26 +1310,26 @@
.css('visibility', 'visible')
.append(popInButton);
- /*
- * This seems a bit pointless, but actually causes a reflow/re-evaluation getting around
- * slickgrid's "Cannot find stylesheet." bug in chrome
- */
+ /*
+ * This seems a bit pointless, but actually causes a reflow/re-evaluation getting around
+ * slickgrid's "Cannot find stylesheet." bug in chrome
+ */
var x = document.body.offsetHeight; // jshint ignore:line
- /*
- * Expose this instance on the window object
- * to allow the opening window to interact with
- * it
- */
+ /*
+ * Expose this instance on the window object
+ * to allow the opening window to interact with
+ * it
+ */
window.__glInstance = this;
},
- /**
- * Creates Subwindows (if there are any). Throws an error
- * if popouts are blocked.
- *
- * @returns {void}
- */
+ /**
+ * Creates Subwindows (if there are any). Throws an error
+ * if popouts are blocked.
+ *
+ * @returns {void}
+ */
_createSubWindows: function () {
var i, popout;
@@ -1345,13 +1345,13 @@
}
},
- /**
- * Determines what element the layout will be created in
- *
- * @private
- *
- * @returns {void}
- */
+ /**
+ * Determines what element the layout will be created in
+ *
+ * @private
+ *
+ * @returns {void}
+ */
_setContainer: function () {
var container = $(this.container || 'body');
@@ -1377,13 +1377,13 @@
this.container = container;
},
- /**
- * Kicks of the initial, recursive creation chain
- *
- * @param {Object} config GoldenLayout Config
- *
- * @returns {void}
- */
+ /**
+ * Kicks of the initial, recursive creation chain
+ *
+ * @param {Object} config GoldenLayout Config
+ *
+ * @returns {void}
+ */
_create: function (config) {
var errorMsg;
@@ -1410,12 +1410,12 @@
}
},
- /**
- * Called when the window is closed or the user navigates away
- * from the page
- *
- * @returns {void}
- */
+ /**
+ * Called when the window is closed or the user navigates away
+ * from the page
+ *
+ * @returns {void}
+ */
_onUnload: function () {
if (this.config.settings.closePopoutsOnUnload === true) {
for (var i = 0; i < this.openPopouts.length; i++) {
@@ -1424,11 +1424,11 @@
}
},
- /**
- * Adjusts the number of columns to be lower to fit the screen and still maintain minItemWidth.
- *
- * @returns {void}
- */
+ /**
+ * Adjusts the number of columns to be lower to fit the screen and still maintain minItemWidth.
+ *
+ * @returns {void}
+ */
_adjustColumnsResponsive: function () {
// If there is no min width set, or not content items, do nothing.
@@ -1470,21 +1470,21 @@
this._updatingColumnsResponsive = false;
},
- /**
- * Determines if responsive layout should be used.
- *
- * @returns {bool} - True if responsive layout should be used; otherwise false.
- */
+ /**
+ * Determines if responsive layout should be used.
+ *
+ * @returns {bool} - True if responsive layout should be used; otherwise false.
+ */
_useResponsiveLayout: function () {
return this.config.settings && (this.config.settings.responsiveMode == 'always' || (this.config.settings.responsiveMode == 'onload' && this._firstLoad));
},
- /**
- * Adds all children of a node to another container recursively.
- * @param {object} container - Container to add child content items to.
- * @param {object} node - Node to search for content items.
- * @returns {void}
- */
+ /**
+ * Adds all children of a node to another container recursively.
+ * @param {object} container - Container to add child content items to.
+ * @param {object} node - Node to search for content items.
+ * @returns {void}
+ */
_addChildContentItemsToContainer: function (container, node) {
if (node.type === 'stack') {
node.contentItems.forEach(function (item) {
@@ -1499,10 +1499,10 @@
}
},
- /**
- * Finds all the stack containers.
- * @returns {array} - The found stack containers.
- */
+ /**
+ * Finds all the stack containers.
+ * @returns {array} - The found stack containers.
+ */
_findAllStackContainers: function () {
var stackContainers = [];
this._findAllStackContainersRecursive(stackContainers, this.root);
@@ -1510,14 +1510,14 @@
return stackContainers;
},
- /**
- * Finds all the stack containers.
- *
- * @param {array} - Set of containers to populate.
- * @param {object} - Current node to process.
- *
- * @returns {void}
- */
+ /**
+ * Finds all the stack containers.
+ *
+ * @param {array} - Set of containers to populate.
+ * @param {object} - Current node to process.
+ *
+ * @returns {void}
+ */
_findAllStackContainersRecursive: function (stackContainers, node) {
node.contentItems.forEach(lm.utils.fnBind(function (item) {
if (item.type == 'stack') {
@@ -1530,9 +1530,9 @@
}
});
- /**
- * Expose the Layoutmanager as the single entrypoint using UMD
- */
+ /**
+ * Expose the Layoutmanager as the single entrypoint using UMD
+ */
(function () {
/* global define */
if (typeof define === 'function' && define.amd) {
@@ -1583,7 +1583,7 @@
close: 'close',
maximise: 'maximise',
minimise: 'minimise',
- popout: 'open in new window',
+ popout: 'new tab',
popin: 'pop in',
tabDropdown: 'additional tabs'
}
@@ -1611,36 +1611,36 @@
lm.utils.copy(lm.container.ItemContainer.prototype, {
- /**
- * Get the inner DOM element the container's content
- * is intended to live in
- *
- * @returns {DOM element}
- */
+ /**
+ * Get the inner DOM element the container's content
+ * is intended to live in
+ *
+ * @returns {DOM element}
+ */
getElement: function () {
return this._contentElement;
},
- /**
- * Hide the container. Notifies the containers content first
- * and then hides the DOM node. If the container is already hidden
- * this should have no effect
- *
- * @returns {void}
- */
+ /**
+ * Hide the container. Notifies the containers content first
+ * and then hides the DOM node. If the container is already hidden
+ * this should have no effect
+ *
+ * @returns {void}
+ */
hide: function () {
this.emit('hide');
this.isHidden = true;
this._element.hide();
},
- /**
- * Shows a previously hidden container. Notifies the
- * containers content first and then shows the DOM element.
- * If the container is already visible this has no effect.
- *
- * @returns {void}
- */
+ /**
+ * Shows a previously hidden container. Notifies the
+ * containers content first and then shows the DOM element.
+ * If the container is already visible this has no effect.
+ *
+ * @returns {void}
+ */
show: function () {
this.emit('show');
this.isHidden = false;
@@ -1651,19 +1651,19 @@
}
},
- /**
- * Set the size from within the container. Traverses up
- * the item tree until it finds a row or column element
- * and resizes its items accordingly.
- *
- * If this container isn't a descendant of a row or column
- * it returns false
- * @todo Rework!!!
- * @param {Number} width The new width in pixel
- * @param {Number} height The new height in pixel
- *
- * @returns {Boolean} resizeSuccesful
- */
+ /**
+ * Set the size from within the container. Traverses up
+ * the item tree until it finds a row or column element
+ * and resizes its items accordingly.
+ *
+ * If this container isn't a descendant of a row or column
+ * it returns false
+ * @todo Rework!!!
+ * @param {Number} width The new width in pixel
+ * @param {Number} height The new height in pixel
+ *
+ * @returns {Boolean} resizeSuccesful
+ */
setSize: function (width, height) {
var rowOrColumn = this.parent,
rowOrColumnChild = this,
@@ -1679,9 +1679,9 @@
rowOrColumn = rowOrColumn.parent;
- /**
- * No row or column has been found
- */
+ /**
+ * No row or column has been found
+ */
if (rowOrColumn.isRoot) {
return false;
}
@@ -1707,13 +1707,13 @@
return true;
},
- /**
- * Closes the container if it is closable. Can be called by
- * both the component within at as well as the contentItem containing
- * it. Emits a close event before the container itself is closed.
- *
- * @returns {void}
- */
+ /**
+ * Closes the container if it is closable. Can be called by
+ * both the component within at as well as the contentItem containing
+ * it. Emits a close event before the container itself is closed.
+ *
+ * @returns {void}
+ */
close: function () {
if (this._config.isClosable) {
this.emit('close');
@@ -1721,55 +1721,55 @@
}
},
- /**
- * Returns the current state object
- *
- * @returns {Object} state
- */
+ /**
+ * Returns the current state object
+ *
+ * @returns {Object} state
+ */
getState: function () {
return this._config.componentState;
},
- /**
- * Merges the provided state into the current one
- *
- * @param {Object} state
- *
- * @returns {void}
- */
+ /**
+ * Merges the provided state into the current one
+ *
+ * @param {Object} state
+ *
+ * @returns {void}
+ */
extendState: function (state) {
this.setState($.extend(true, this.getState(), state));
},
- /**
- * Notifies the layout manager of a stateupdate
- *
- * @param {serialisable} state
- */
+ /**
+ * Notifies the layout manager of a stateupdate
+ *
+ * @param {serialisable} state
+ */
setState: function (state) {
this._config.componentState = state;
this.parent.emitBubblingEvent('stateChanged');
},
- /**
- * Set's the components title
- *
- * @param {String} title
- */
+ /**
+ * Set's the components title
+ *
+ * @param {String} title
+ */
setTitle: function (title) {
this.parent.setTitle(title);
},
- /**
- * Set's the containers size. Called by the container's component.
- * To set the size programmatically from within the container please
- * use the public setSize method
- *
- * @param {[Int]} width in px
- * @param {[Int]} height in px
- *
- * @returns {void}
- */
+ /**
+ * Set's the containers size. Called by the container's component.
+ * To set the size programmatically from within the container please
+ * use the public setSize method
+ *
+ * @param {[Int]} width in px
+ * @param {[Int]} height in px
+ *
+ * @returns {void}
+ */
_$setSize: function (width, height) {
if (width !== this.width || height !== this.height) {
this.width = width;
@@ -1784,22 +1784,22 @@
}
});
- /**
- * Pops a content item out into a new browser window.
- * This is achieved by
- *
- * - Creating a new configuration with the content item as root element
- * - Serializing and minifying the configuration
- * - Opening the current window's URL with the configuration as a GET parameter
- * - GoldenLayout when opened in the new window will look for the GET parameter
- * and use it instead of the provided configuration
- *
- * @param {Object} config GoldenLayout item config
- * @param {Object} dimensions A map with width, height, top and left
- * @param {String} parentId The id of the element the item will be appended to on popIn
- * @param {Number} indexInParent The position of this element within its parent
- * @param {lm.LayoutManager} layoutManager
- */
+ /**
+ * Pops a content item out into a new browser window.
+ * This is achieved by
+ *
+ * - Creating a new configuration with the content item as root element
+ * - Serializing and minifying the configuration
+ * - Opening the current window's URL with the configuration as a GET parameter
+ * - GoldenLayout when opened in the new window will look for the GET parameter
+ * and use it instead of the provided configuration
+ *
+ * @param {Object} config GoldenLayout item config
+ * @param {Object} dimensions A map with width, height, top and left
+ * @param {String} parentId The id of the element the item will be appended to on popIn
+ * @param {Number} indexInParent The position of this element within its parent
+ * @param {lm.LayoutManager} layoutManager
+ */
lm.controls.BrowserPopout = function (config, dimensions, parentId, indexInParent, layoutManager) {
lm.utils.EventEmitter.call(this);
this.isInitialised = false;
@@ -1853,10 +1853,10 @@
}
},
- /**
- * Returns the popped out item to its original position. If the original
- * parent isn't available anymore it falls back to the layout's topmost element
- */
+ /**
+ * Returns the popped out item to its original position. If the original
+ * parent isn't available anymore it falls back to the layout's topmost element
+ */
popIn: function () {
var childConfig,
parentItem,
@@ -1864,22 +1864,22 @@
if (this._parentId) {
- /*
- * The $.extend call seems a bit pointless, but it's crucial to
- * copy the config returned by this.getGlInstance().toConfig()
- * onto a new object. Internet Explorer keeps the references
- * to objects on the child window, resulting in the following error
- * once the child window is closed:
- *
- * The callee (server [not server application]) is not available and disappeared
- */
+ /*
+ * The $.extend call seems a bit pointless, but it's crucial to
+ * copy the config returned by this.getGlInstance().toConfig()
+ * onto a new object. Internet Explorer keeps the references
+ * to objects on the child window, resulting in the following error
+ * once the child window is closed:
+ *
+ * The callee (server [not server application]) is not available and disappeared
+ */
childConfig = $.extend(true, {}, this.getGlInstance().toConfig()).content[0];
parentItem = this._layoutManager.root.getItemsById(this._parentId)[0];
- /*
- * Fallback if parentItem is not available. Either add it to the topmost
- * item or make it the topmost item if the layout is empty
- */
+ /*
+ * Fallback if parentItem is not available. Either add it to the topmost
+ * item or make it the topmost item if the layout is empty
+ */
if (!parentItem) {
if (this._layoutManager.root.contentItems.length > 0) {
parentItem = this._layoutManager.root.contentItems[0];
@@ -1894,28 +1894,28 @@
this.close();
},
- /**
- * Creates the URL and window parameter
- * and opens a new window
- *
- * @private
- *
- * @returns {void}
- */
+ /**
+ * Creates the URL and window parameter
+ * and opens a new window
+ *
+ * @private
+ *
+ * @returns {void}
+ */
_createWindow: function () {
var checkReadyInterval,
url = this._createUrl(),
- /**
- * Bogus title to prevent re-usage of existing window with the
- * same title. The actual title will be set by the new window's
- * GoldenLayout instance if it detects that it is in subWindowMode
- */
+ /**
+ * Bogus title to prevent re-usage of existing window with the
+ * same title. The actual title will be set by the new window's
+ * GoldenLayout instance if it detects that it is in subWindowMode
+ */
title = Math.floor(Math.random() * 1000000).toString(36),
- /**
- * The options as used in the window.open string
- */
+ /**
+ * The options as used in the window.open string
+ */
options = this._serializeWindowOptions({
width: this._dimensions.width,
height: this._dimensions.height,
@@ -1946,12 +1946,12 @@
.on('load', lm.utils.fnBind(this._positionWindow, this))
.on('unload beforeunload', lm.utils.fnBind(this._onClose, this));
- /**
- * Polling the childwindow to find out if GoldenLayout has been initialised
- * doesn't seem optimal, but the alternatives - adding a callback to the parent
- * window or raising an event on the window object - both would introduce knowledge
- * about the parent to the child window which we'd rather avoid
- */
+ /**
+ * Polling the childwindow to find out if GoldenLayout has been initialised
+ * doesn't seem optimal, but the alternatives - adding a callback to the parent
+ * window or raising an event on the window object - both would introduce knowledge
+ * about the parent to the child window which we'd rather avoid
+ */
checkReadyInterval = setInterval(lm.utils.fnBind(function () {
if (this._popoutWindow.__glInstance && this._popoutWindow.__glInstance.isInitialised) {
this._onInitialised();
@@ -1960,13 +1960,13 @@
}, this), 10);
},
- /**
- * Serialises a map of key:values to a window options string
- *
- * @param {Object} windowOptions
- *
- * @returns {String} serialised window options
- */
+ /**
+ * Serialises a map of key:values to a window options string
+ *
+ * @param {Object} windowOptions
+ *
+ * @returns {String} serialised window options
+ */
_serializeWindowOptions: function (windowOptions) {
var windowOptionsString = [], key;
@@ -1977,12 +1977,12 @@
return windowOptionsString.join(',');
},
- /**
- * Creates the URL for the new window, including the
- * config GET parameter
- *
- * @returns {String} URL
- */
+ /**
+ * Creates the URL for the new window, including the
+ * config GET parameter
+ *
+ * @returns {String} URL
+ */
_createUrl: function () {
var config = { content: this._config },
storageKey = 'gl-window-config-' + lm.utils.getUniqueId(),
@@ -2008,57 +2008,57 @@
}
},
- /**
- * Move the newly created window roughly to
- * where the component used to be.
- *
- * @private
- *
- * @returns {void}
- */
+ /**
+ * Move the newly created window roughly to
+ * where the component used to be.
+ *
+ * @private
+ *
+ * @returns {void}
+ */
_positionWindow: function () {
this._popoutWindow.moveTo(this._dimensions.left, this._dimensions.top);
this._popoutWindow.focus();
},
- /**
- * Callback when the new window is opened and the GoldenLayout instance
- * within it is initialised
- *
- * @returns {void}
- */
+ /**
+ * Callback when the new window is opened and the GoldenLayout instance
+ * within it is initialised
+ *
+ * @returns {void}
+ */
_onInitialised: function () {
this.isInitialised = true;
this.getGlInstance().on('popIn', this.popIn, this);
this.emit('initialised');
},
- /**
- * Invoked 50ms after the window unload event
- *
- * @private
- *
- * @returns {void}
- */
+ /**
+ * Invoked 50ms after the window unload event
+ *
+ * @private
+ *
+ * @returns {void}
+ */
_onClose: function () {
setTimeout(lm.utils.fnBind(this.emit, this, ['closed']), 50);
}
});
- /**
- * This class creates a temporary container
- * for the component whilst it is being dragged
- * and handles drag events
- *
- * @constructor
- * @private
- *
- * @param {Number} x The initial x position
- * @param {Number} y The initial y position
- * @param {lm.utils.DragListener} dragListener
- * @param {lm.LayoutManager} layoutManager
- * @param {lm.item.AbstractContentItem} contentItem
- * @param {lm.item.AbstractContentItem} originalParent
- */
+ /**
+ * This class creates a temporary container
+ * for the component whilst it is being dragged
+ * and handles drag events
+ *
+ * @constructor
+ * @private
+ *
+ * @param {Number} x The initial x position
+ * @param {Number} y The initial y position
+ * @param {lm.utils.DragListener} dragListener
+ * @param {lm.LayoutManager} layoutManager
+ * @param {lm.item.AbstractContentItem} contentItem
+ * @param {lm.item.AbstractContentItem} originalParent
+ */
lm.controls.DragProxy = function (x, y, dragListener, layoutManager, contentItem, originalParent) {
lm.utils.EventEmitter.call(this);
@@ -2120,19 +2120,19 @@
lm.utils.copy(lm.controls.DragProxy.prototype, {
- /**
- * Callback on every mouseMove event during a drag. Determines if the drag is
- * still within the valid drag area and calls the layoutManager to highlight the
- * current drop area
- *
- * @param {Number} offsetX The difference from the original x position in px
- * @param {Number} offsetY The difference from the original y position in px
- * @param {jQuery DOM event} event
- *
- * @private
- *
- * @returns {void}
- */
+ /**
+ * Callback on every mouseMove event during a drag. Determines if the drag is
+ * still within the valid drag area and calls the layoutManager to highlight the
+ * current drop area
+ *
+ * @param {Number} offsetX The difference from the original x position in px
+ * @param {Number} offsetY The difference from the original y position in px
+ * @param {jQuery DOM event} event
+ *
+ * @private
+ *
+ * @returns {void}
+ */
_onDrag: function (offsetX, offsetY, event) {
event = event.originalEvent && event.originalEvent.touches ? event.originalEvent.touches[0] : event;
@@ -2148,16 +2148,16 @@
this._setDropPosition(x, y);
},
- /**
- * Sets the target position, highlighting the appropriate area
- *
- * @param {Number} x The x position in px
- * @param {Number} y The y position in px
- *
- * @private
- *
- * @returns {void}
- */
+ /**
+ * Sets the target position, highlighting the appropriate area
+ *
+ * @param {Number} x The x position in px
+ * @param {Number} y The y position in px
+ *
+ * @private
+ *
+ * @returns {void}
+ */
_setDropPosition: function (x, y) {
this.element.css({ left: x, top: y });
this._area = this._layoutManager._$getArea(x, y);
@@ -2168,43 +2168,43 @@
}
},
- /**
- * Callback when the drag has finished. Determines the drop area
- * and adds the child to it
- *
- * @private
- *
- * @returns {void}
- */
+ /**
+ * Callback when the drag has finished. Determines the drop area
+ * and adds the child to it
+ *
+ * @private
+ *
+ * @returns {void}
+ */
_onDrop: function () {
this._layoutManager.dropTargetIndicator.hide();
- /*
- * Valid drop area found
- */
+ /*
+ * Valid drop area found
+ */
if (this._area !== null) {
this._area.contentItem._$onDrop(this._contentItem, this._area);
- /**
- * No valid drop area available at present, but one has been found before.
- * Use it
- */
+ /**
+ * No valid drop area available at present, but one has been found before.
+ * Use it
+ */
} else if (this._lastValidArea !== null) {
this._lastValidArea.contentItem._$onDrop(this._contentItem, this._lastValidArea);
- /**
- * No valid drop area found during the duration of the drag. Return
- * content item to its original position if a original parent is provided.
- * (Which is not the case if the drag had been initiated by createDragSource)
- */
+ /**
+ * No valid drop area found during the duration of the drag. Return
+ * content item to its original position if a original parent is provided.
+ * (Which is not the case if the drag had been initiated by createDragSource)
+ */
} else if (this._originalParent) {
this._originalParent.addChild(this._contentItem);
- /**
- * The drag didn't ultimately end up with adding the content item to
- * any container. In order to ensure clean up happens, destroy the
- * content item.
- */
+ /**
+ * The drag didn't ultimately end up with adding the content item to
+ * any container. In order to ensure clean up happens, destroy the
+ * content item.
+ */
} else {
this._contentItem._$destroy();
}
@@ -2215,18 +2215,18 @@
this._layoutManager.emit('itemDropped', this._contentItem);
},
- /**
- * Removes the item from its original position within the tree
- *
- * @private
- *
- * @returns {void}
- */
+ /**
+ * Removes the item from its original position within the tree
+ *
+ * @private
+ *
+ * @returns {void}
+ */
_updateTree: function () {
- /**
- * parent is null if the drag had been initiated by a external drag source
- */
+ /**
+ * parent is null if the drag had been initiated by a external drag source
+ */
if (this._contentItem.parent) {
this._contentItem.parent.removeChild(this._contentItem, true);
}
@@ -2234,13 +2234,13 @@
this._contentItem._$setParent(this);
},
- /**
- * Updates the Drag Proxie's dimensions
- *
- * @private
- *
- * @returns {void}
- */
+ /**
+ * Updates the Drag Proxie's dimensions
+ *
+ * @private
+ *
+ * @returns {void}
+ */
_setDimensions: function () {
var dimensions = this._layoutManager.config.dimensions,
width = dimensions.dragProxyWidth,
@@ -2259,16 +2259,16 @@
}
});
- /**
- * Allows for any DOM item to create a component on drag
- * start tobe dragged into the Layout
- *
- * @param {jQuery element} element
- * @param {Object} itemConfig the configuration for the contentItem that will be created
- * @param {LayoutManager} layoutManager
- *
- * @constructor
- */
+ /**
+ * Allows for any DOM item to create a component on drag
+ * start tobe dragged into the Layout
+ *
+ * @param {jQuery element} element
+ * @param {Object} itemConfig the configuration for the contentItem that will be created
+ * @param {LayoutManager} layoutManager
+ *
+ * @constructor
+ */
lm.controls.DragSource = function (element, itemConfig, layoutManager) {
this._element = element;
this._itemConfig = itemConfig;
@@ -2280,11 +2280,11 @@
lm.utils.copy(lm.controls.DragSource.prototype, {
- /**
- * Called initially and after every drag
- *
- * @returns {void}
- */
+ /**
+ * Called initially and after every drag
+ *
+ * @returns {void}
+ */
_createDragListener: function () {
if (this._dragListener !== null) {
this._dragListener.destroy();
@@ -2306,14 +2306,14 @@
}
},
- /**
- * Callback for the DragListener's dragStart event
- *
- * @param {int} x the x position of the mouse on dragStart
- * @param {int} y the x position of the mouse on dragStart
- *
- * @returns {void}
- */
+ /**
+ * Callback for the DragListener's dragStart event
+ *
+ * @param {int} x the x position of the mouse on dragStart
+ * @param {int} y the x position of the mouse on dragStart
+ *
+ * @returns {void}
+ */
_onDragStart: function (x, y) {
var itemConfig = this._itemConfig;
if (lm.utils.isFunction(itemConfig)) {
@@ -2355,12 +2355,12 @@
this.element.hide();
}
});
- /**
- * This class represents a header above a Stack ContentItem.
- *
- * @param {lm.LayoutManager} layoutManager
- * @param {lm.item.AbstractContentItem} parent
- */
+ /**
+ * This class represents a header above a Stack ContentItem.
+ *
+ * @param {lm.LayoutManager} layoutManager
+ * @param {lm.item.AbstractContentItem} parent
+ */
lm.controls.Header = function (layoutManager, parent) {
lm.utils.EventEmitter.call(this);
@@ -2400,14 +2400,14 @@
lm.utils.copy(lm.controls.Header.prototype, {
- /**
- * Creates a new tab and associates it with a contentItem
- *
- * @param {lm.item.AbstractContentItem} contentItem
- * @param {Integer} index The position of the tab
- *
- * @returns {void}
- */
+ /**
+ * Creates a new tab and associates it with a contentItem
+ *
+ * @param {lm.item.AbstractContentItem} contentItem
+ * @param {Integer} index The position of the tab
+ *
+ * @returns {void}
+ */
createTab: function (contentItem, index) {
var tab, i;
@@ -2441,13 +2441,13 @@
this._updateTabSizes();
},
- /**
- * Finds a tab based on the contentItem its associated with and removes it.
- *
- * @param {lm.item.AbstractContentItem} contentItem
- *
- * @returns {void}
- */
+ /**
+ * Finds a tab based on the contentItem its associated with and removes it.
+ *
+ * @param {lm.item.AbstractContentItem} contentItem
+ *
+ * @returns {void}
+ */
removeTab: function (contentItem) {
for (var i = 0; i < this.tabs.length; i++) {
if (this.tabs[i].contentItem === contentItem) {
@@ -2460,11 +2460,11 @@
throw new Error('contentItem is not controlled by this header');
},
- /**
- * The programmatical equivalent of clicking a Tab.
- *
- * @param {lm.item.AbstractContentItem} contentItem
- */
+ /**
+ * The programmatical equivalent of clicking a Tab.
+ *
+ * @param {lm.item.AbstractContentItem} contentItem
+ */
setActiveContentItem: function (contentItem) {
var i, j, isActive, activeTab;
@@ -2478,10 +2478,10 @@
}
if (this.layoutManager.config.settings.reorderOnTabMenuClick) {
- /**
- * If the tab selected was in the dropdown, move everything down one to make way for this one to be the first.
- * This will make sure the most used tabs stay visible.
- */
+ /**
+ * If the tab selected was in the dropdown, move everything down one to make way for this one to be the first.
+ * This will make sure the most used tabs stay visible.
+ */
if (this._lastVisibleTabIndex !== -1 && this.parent.config.activeItemIndex > this._lastVisibleTabIndex) {
activeTab = this.tabs[this.parent.config.activeItemIndex];
for (j = this.parent.config.activeItemIndex; j > 0; j--) {
@@ -2496,13 +2496,13 @@
this.parent.emitBubblingEvent('stateChanged');
},
- /**
- * Programmatically operate with header position.
- *
- * @param {string} position one of ('top','left','right','bottom') to set or empty to get it.
- *
- * @returns {string} previous header position
- */
+ /**
+ * Programmatically operate with header position.
+ *
+ * @param {string} position one of ('top','left','right','bottom') to set or empty to get it.
+ *
+ * @returns {string} previous header position
+ */
position: function (position) {
var previous = this.parent._header.show;
if (previous && !this.parent._side)
@@ -2514,14 +2514,14 @@
return previous;
},
- /**
- * Programmatically set closability.
- *
- * @package private
- * @param {Boolean} isClosable Whether to enable/disable closability.
- *
- * @returns {Boolean} Whether the action was successful
- */
+ /**
+ * Programmatically set closability.
+ *
+ * @package private
+ * @param {Boolean} isClosable Whether to enable/disable closability.
+ *
+ * @returns {Boolean} Whether the action was successful
+ */
_$setClosable: function (isClosable) {
if (this.closeButton && this._isClosable()) {
this.closeButton.element[isClosable ? "show" : "hide"]();
@@ -2531,13 +2531,13 @@
return false;
},
- /**
- * Destroys the entire header
- *
- * @package private
- *
- * @returns {void}
- */
+ /**
+ * Destroys the entire header
+ *
+ * @package private
+ *
+ * @returns {void}
+ */
_$destroy: function () {
this.emit('destroy', this);
@@ -2548,20 +2548,20 @@
this.element.remove();
},
- /**
- * get settings from header
- *
- * @returns {string} when exists
- */
+ /**
+ * get settings from header
+ *
+ * @returns {string} when exists
+ */
_getHeaderSetting: function (name) {
if (name in this.parent._header)
return this.parent._header[name];
},
- /**
- * Creates the popout, maximise and close buttons in the header's top right corner
- *
- * @returns {void}
- */
+ /**
+ * Creates the popout, maximise and close buttons in the header's top right corner
+ *
+ * @returns {void}
+ */
_createControls: function () {
var closeStack,
popout,
@@ -2573,26 +2573,26 @@
tabDropdownLabel,
showTabDropdown;
- /**
- * Dropdown to show additional tabs.
- */
+ /**
+ * Dropdown to show additional tabs.
+ */
showTabDropdown = lm.utils.fnBind(this._showAdditionalTabsDropdown, this);
tabDropdownLabel = this.layoutManager.config.labels.tabDropdown;
this.tabDropdownButton = new lm.controls.HeaderButton(this, tabDropdownLabel, 'lm_tabdropdown', showTabDropdown);
this.tabDropdownButton.element.hide();
- /**
- * Popout control to launch component in new window.
- */
+ /**
+ * Popout control to launch component in new window.
+ */
if (this._getHeaderSetting('popout')) {
popout = lm.utils.fnBind(this._onPopoutClick, this);
label = this._getHeaderSetting('popout');
new lm.controls.HeaderButton(this, label, 'lm_popout', popout);
}
- /**
- * Maximise control - set the component to the full size of the layout
- */
+ /**
+ * Maximise control - set the component to the full size of the layout
+ */
if (this._getHeaderSetting('maximise')) {
maximise = lm.utils.fnBind(this.parent.toggleMaximise, this.parent);
maximiseLabel = this._getHeaderSetting('maximise');
@@ -2608,9 +2608,9 @@
});
}
- /**
- * Close button
- */
+ /**
+ * Close button
+ */
if (this._isClosable()) {
closeStack = lm.utils.fnBind(this.parent.remove, this.parent);
label = this._getHeaderSetting('close');
@@ -2618,30 +2618,30 @@
}
},
- /**
- * Shows drop down for additional tabs when there are too many to display.
- *
- * @returns {void}
- */
+ /**
+ * Shows drop down for additional tabs when there are too many to display.
+ *
+ * @returns {void}
+ */
_showAdditionalTabsDropdown: function () {
this.tabDropdownContainer.show();
},
- /**
- * Hides drop down for additional tabs when there are too many to display.
- *
- * @returns {void}
- */
+ /**
+ * Hides drop down for additional tabs when there are too many to display.
+ *
+ * @returns {void}
+ */
_hideAdditionalTabsDropdown: function (e) {
this.tabDropdownContainer.hide();
},
- /**
- * Checks whether the header is closable based on the parent config and
- * the global config.
- *
- * @returns {Boolean} Whether the header is closable.
- */
+ /**
+ * Checks whether the header is closable based on the parent config and
+ * the global config.
+ *
+ * @returns {Boolean} Whether the header is closable.
+ */
_isClosable: function () {
return this.parent.config.isClosable && this.layoutManager.config.settings.showCloseIcon;
},
@@ -2655,24 +2655,24 @@
},
- /**
- * Invoked when the header's background is clicked (not it's tabs or controls)
- *
- * @param {jQuery DOM event} event
- *
- * @returns {void}
- */
+ /**
+ * Invoked when the header's background is clicked (not it's tabs or controls)
+ *
+ * @param {jQuery DOM event} event
+ *
+ * @returns {void}
+ */
_onHeaderClick: function (event) {
if (event.target === this.element[0]) {
this.parent.select();
}
},
- /**
- * Pushes the tabs to the tab dropdown if the available space is not sufficient
- *
- * @returns {void}
- */
+ /**
+ * Pushes the tabs to the tab dropdown if the available space is not sufficient
+ *
+ * @returns {void}
+ */
_updateTabSizes: function (showTabMenu) {
if (this.tabs.length === 0) {
return;
@@ -2835,14 +2835,14 @@
}
});
- /**
- * Represents an individual tab within a Stack's header
- *
- * @param {lm.controls.Header} header
- * @param {lm.items.AbstractContentItem} contentItem
- *
- * @constructor
- */
+ /**
+ * Represents an individual tab within a Stack's header
+ *
+ * @param {lm.controls.Header} header
+ * @param {lm.items.AbstractContentItem} contentItem
+ *
+ * @constructor
+ */
lm.controls.Tab = function (header, contentItem) {
this.header = header;
this.contentItem = contentItem;
@@ -2888,37 +2888,37 @@
}
};
- /**
- * The tab's html template
- *
- * @type {String}
- */
+ /**
+ * The tab's html template
+ *
+ * @type {String}
+ */
lm.controls.Tab._template = '
' +
'' +
'
';
lm.utils.copy(lm.controls.Tab.prototype, {
- /**
- * Sets the tab's title to the provided string and sets
- * its title attribute to a pure text representation (without
- * html tags) of the same string.
- *
- * @public
- * @param {String} title can contain html
- */
+ /**
+ * Sets the tab's title to the provided string and sets
+ * its title attribute to a pure text representation (without
+ * html tags) of the same string.
+ *
+ * @public
+ * @param {String} title can contain html
+ */
setTitle: function (title) {
this.element.attr('title', lm.utils.stripTags(title));
this.titleElement.html(title);
},
- /**
- * Sets this tab's active state. To programmatically
- * switch tabs, use header.setActiveContentItem( item ) instead.
- *
- * @public
- * @param {Boolean} isActive
- */
+ /**
+ * Sets this tab's active state. To programmatically
+ * switch tabs, use header.setActiveContentItem( item ) instead.
+ *
+ * @public
+ * @param {Boolean} isActive
+ */
setActive: function (isActive) {
if (isActive === this.isActive) {
return;
@@ -2932,12 +2932,12 @@
}
},
- /**
- * Destroys the tab
- *
- * @private
- * @returns {void}
- */
+ /**
+ * Destroys the tab
+ *
+ * @private
+ * @returns {void}
+ */
_$destroy: function () {
this._layoutManager.emit('tabDestroyed', this);
this.element.off('mousedown touchstart', this._onTabClickFn);
@@ -2950,15 +2950,15 @@
this.element.remove();
},
- /**
- * Callback for the DragListener
- *
- * @param {Number} x The tabs absolute x position
- * @param {Number} y The tabs absolute y position
- *
- * @private
- * @returns {void}
- */
+ /**
+ * Callback for the DragListener
+ *
+ * @param {Number} x The tabs absolute x position
+ * @param {Number} y The tabs absolute y position
+ *
+ * @private
+ * @returns {void}
+ */
_onDragStart: function (x, y) {
if (this.contentItem.parent.isMaximised === true) {
this.contentItem.parent.toggleMaximise();
@@ -2973,14 +2973,14 @@
);
},
- /**
- * Callback when the tab is clicked
- *
- * @param {jQuery DOM event} event
- *
- * @private
- * @returns {void}
- */
+ /**
+ * Callback when the tab is clicked
+ *
+ * @param {jQuery DOM event} event
+ *
+ * @private
+ * @returns {void}
+ */
_onTabClick: function (event) {
// left mouse button or tap
if (event.button === 0 || event.type === 'touchstart') {
@@ -2995,30 +2995,30 @@
}
},
- /**
- * Callback when the tab's close button is
- * clicked
- *
- * @param {jQuery DOM event} event
- *
- * @private
- * @returns {void}
- */
+ /**
+ * Callback when the tab's close button is
+ * clicked
+ *
+ * @param {jQuery DOM event} event
+ *
+ * @private
+ * @returns {void}
+ */
_onCloseClick: function (event) {
event.stopPropagation();
this.header.parent.removeChild(this.contentItem);
},
- /**
- * Callback to capture tab close button mousedown
- * to prevent tab from activating.
- *
- * @param (jQuery DOM event) event
- *
- * @private
- * @returns {void}
- */
+ /**
+ * Callback to capture tab close button mousedown
+ * to prevent tab from activating.
+ *
+ * @param (jQuery DOM event) event
+ *
+ * @private
+ * @returns {void}
+ */
_onCloseMousedown: function (event) {
event.stopPropagation();
}
@@ -3040,9 +3040,9 @@
},
transitionElements: function (fromElement, toElement) {
- /**
- * TODO - This is not quite as cool as expected. Review.
- */
+ /**
+ * TODO - This is not quite as cool as expected. Review.
+ */
return;
this._toElement = toElement;
this._animationStartTime = lm.utils.now();
@@ -3096,27 +3096,27 @@
lm.errors.ConfigurationError.prototype = new Error();
- /**
- * This is the baseclass that all content items inherit from.
- * Most methods provide a subset of what the sub-classes do.
- *
- * It also provides a number of functions for tree traversal
- *
- * @param {lm.LayoutManager} layoutManager
- * @param {item node configuration} config
- * @param {lm.item} parent
- *
- * @event stateChanged
- * @event beforeItemDestroyed
- * @event itemDestroyed
- * @event itemCreated
- * @event componentCreated
- * @event rowCreated
- * @event columnCreated
- * @event stackCreated
- *
- * @constructor
- */
+ /**
+ * This is the baseclass that all content items inherit from.
+ * Most methods provide a subset of what the sub-classes do.
+ *
+ * It also provides a number of functions for tree traversal
+ *
+ * @param {lm.LayoutManager} layoutManager
+ * @param {item node configuration} config
+ * @param {lm.item} parent
+ *
+ * @event stateChanged
+ * @event beforeItemDestroyed
+ * @event itemDestroyed
+ * @event itemCreated
+ * @event componentCreated
+ * @event rowCreated
+ * @event columnCreated
+ * @event stackCreated
+ *
+ * @constructor
+ */
lm.items.AbstractContentItem = function (layoutManager, config, parent) {
lm.utils.EventEmitter.call(this);
@@ -3146,26 +3146,26 @@
lm.utils.copy(lm.items.AbstractContentItem.prototype, {
- /**
- * Set the size of the component and its children, called recursively
- *
- * @abstract
- * @returns void
- */
+ /**
+ * Set the size of the component and its children, called recursively
+ *
+ * @abstract
+ * @returns void
+ */
setSize: function () {
throw new Error('Abstract Method');
},
- /**
- * Calls a method recursively downwards on the tree
- *
- * @param {String} functionName the name of the function to be called
- * @param {[Array]}functionArguments optional arguments that are passed to every function
- * @param {[bool]} bottomUp Call methods from bottom to top, defaults to false
- * @param {[bool]} skipSelf Don't invoke the method on the class that calls it, defaults to false
- *
- * @returns {void}
- */
+ /**
+ * Calls a method recursively downwards on the tree
+ *
+ * @param {String} functionName the name of the function to be called
+ * @param {[Array]}functionArguments optional arguments that are passed to every function
+ * @param {[bool]} bottomUp Call methods from bottom to top, defaults to false
+ * @param {[bool]} skipSelf Don't invoke the method on the class that calls it, defaults to false
+ *
+ * @returns {void}
+ */
callDownwards: function (functionName, functionArguments, bottomUp, skipSelf) {
var i;
@@ -3180,53 +3180,53 @@
}
},
- /**
- * Removes a child node (and its children) from the tree
- *
- * @param {lm.items.ContentItem} contentItem
- *
- * @returns {void}
- */
+ /**
+ * Removes a child node (and its children) from the tree
+ *
+ * @param {lm.items.ContentItem} contentItem
+ *
+ * @returns {void}
+ */
removeChild: function (contentItem, keepChild) {
- /*
- * Get the position of the item that's to be removed within all content items this node contains
- */
+ /*
+ * Get the position of the item that's to be removed within all content items this node contains
+ */
var index = lm.utils.indexOf(contentItem, this.contentItems);
- /*
- * Make sure the content item to be removed is actually a child of this item
- */
+ /*
+ * Make sure the content item to be removed is actually a child of this item
+ */
if (index === -1) {
throw new Error('Can\'t remove child item. Unknown content item');
}
- /**
- * Call ._$destroy on the content item. This also calls ._$destroy on all its children
- */
+ /**
+ * Call ._$destroy on the content item. This also calls ._$destroy on all its children
+ */
if (keepChild !== true) {
this.contentItems[index]._$destroy();
}
- /**
- * Remove the content item from this nodes array of children
- */
+ /**
+ * Remove the content item from this nodes array of children
+ */
this.contentItems.splice(index, 1);
- /**
- * Remove the item from the configuration
- */
+ /**
+ * Remove the item from the configuration
+ */
this.config.content.splice(index, 1);
- /**
- * If this node still contains other content items, adjust their size
- */
+ /**
+ * If this node still contains other content items, adjust their size
+ */
if (this.contentItems.length > 0) {
this.callDownwards('setSize');
- /**
- * If this was the last content item, remove this node as well
- */
+ /**
+ * If this was the last content item, remove this node as well
+ */
} else if (!(this instanceof lm.items.Root) && this.config.isClosable === true) {
const stack = this;
const rowOrCol = stack.parent;
@@ -3244,14 +3244,14 @@
}
},
- /**
- * Sets up the tree structure for the newly added child
- * The responsibility for the actual DOM manipulations lies
- * with the concrete item
- *
- * @param {lm.items.AbstractContentItem} contentItem
- * @param {[Int]} index If omitted item will be appended
- */
+ /**
+ * Sets up the tree structure for the newly added child
+ * The responsibility for the actual DOM manipulations lies
+ * with the concrete item
+ *
+ * @param {lm.items.AbstractContentItem} contentItem
+ * @param {[Int]} index If omitted item will be appended
+ */
addChild: function (contentItem, index) {
if (index === undefined) {
index = this.contentItems.length;
@@ -3271,15 +3271,15 @@
}
},
- /**
- * Replaces oldChild with newChild. This used to use jQuery.replaceWith... which for
- * some reason removes all event listeners, so isn't really an option.
- *
- * @param {lm.item.AbstractContentItem} oldChild
- * @param {lm.item.AbstractContentItem} newChild
- *
- * @returns {void}
- */
+ /**
+ * Replaces oldChild with newChild. This used to use jQuery.replaceWith... which for
+ * some reason removes all event listeners, so isn't really an option.
+ *
+ * @param {lm.item.AbstractContentItem} oldChild
+ * @param {lm.item.AbstractContentItem} newChild
+ *
+ * @returns {void}
+ */
replaceChild: function (oldChild, newChild, _$destroyOldChild) {
newChild = this.layoutManager._$normalizeContentItem(newChild);
@@ -3293,23 +3293,23 @@
parentNode.replaceChild(newChild.element[0], oldChild.element[0]);
- /*
- * Optionally destroy the old content item
- */
+ /*
+ * Optionally destroy the old content item
+ */
if (_$destroyOldChild === true) {
oldChild.parent = null;
oldChild._$destroy();
}
- /*
- * Wire the new contentItem into the tree
- */
+ /*
+ * Wire the new contentItem into the tree
+ */
this.contentItems[index] = newChild;
newChild.parent = this;
- /*
- * Update tab reference
- */
+ /*
+ * Update tab reference
+ */
if (this.isStack) {
this.header.tabs[index].contentItem = newChild;
}
@@ -3322,33 +3322,33 @@
this.callDownwards('setSize');
},
- /**
- * Convenience method.
- * Shorthand for this.parent.removeChild( this )
- *
- * @returns {void}
- */
+ /**
+ * Convenience method.
+ * Shorthand for this.parent.removeChild( this )
+ *
+ * @returns {void}
+ */
remove: function () {
this.parent.removeChild(this);
},
- /**
- * Removes the component from the layout and creates a new
- * browser window with the component and its children inside
- *
- * @returns {lm.controls.BrowserPopout}
- */
+ /**
+ * Removes the component from the layout and creates a new
+ * browser window with the component and its children inside
+ *
+ * @returns {lm.controls.BrowserPopout}
+ */
popout: function () {
var browserPopout = this.layoutManager.createPopout(this);
this.emitBubblingEvent('stateChanged');
return browserPopout;
},
- /**
- * Maximises the Item or minimises it if it is already maximised
- *
- * @returns {void}
- */
+ /**
+ * Maximises the Item or minimises it if it is already maximised
+ *
+ * @returns {void}
+ */
toggleMaximise: function (e) {
e && e.preventDefault();
if (this.isMaximised === true) {
@@ -3361,11 +3361,11 @@
this.emitBubblingEvent('stateChanged');
},
- /**
- * Selects the item if it is not already selected
- *
- * @returns {void}
- */
+ /**
+ * Selects the item if it is not already selected
+ *
+ * @returns {void}
+ */
select: function () {
if (this.layoutManager.selectedItem !== this) {
this.layoutManager.selectItem(this, true);
@@ -3373,11 +3373,11 @@
}
},
- /**
- * De-selects the item if it is selected
- *
- * @returns {void}
- */
+ /**
+ * De-selects the item if it is selected
+ *
+ * @returns {void}
+ */
deselect: function () {
if (this.layoutManager.selectedItem === this) {
this.layoutManager.selectedItem = null;
@@ -3385,28 +3385,28 @@
}
},
- /**
- * Set this component's title
- *
- * @public
- * @param {String} title
- *
- * @returns {void}
- */
+ /**
+ * Set this component's title
+ *
+ * @public
+ * @param {String} title
+ *
+ * @returns {void}
+ */
setTitle: function (title) {
this.config.title = title;
this.emit('titleChanged', title);
this.emit('stateChanged');
},
- /**
- * Checks whether a provided id is present
- *
- * @public
- * @param {String} id
- *
- * @returns {Boolean} isPresent
- */
+ /**
+ * Checks whether a provided id is present
+ *
+ * @public
+ * @param {String} id
+ *
+ * @returns {Boolean} isPresent
+ */
hasId: function (id) {
if (!this.config.id) {
return false;
@@ -3417,15 +3417,15 @@
}
},
- /**
- * Adds an id. Adds it as a string if the component doesn't
- * have an id yet or creates/uses an array
- *
- * @public
- * @param {String} id
- *
- * @returns {void}
- */
+ /**
+ * Adds an id. Adds it as a string if the component doesn't
+ * have an id yet or creates/uses an array
+ *
+ * @public
+ * @param {String} id
+ *
+ * @returns {void}
+ */
addId: function (id) {
if (this.hasId(id)) {
return;
@@ -3440,15 +3440,15 @@
}
},
- /**
- * Removes an existing id. Throws an error
- * if the id is not present
- *
- * @public
- * @param {String} id
- *
- * @returns {void}
- */
+ /**
+ * Removes an existing id. Throws an error
+ * if the id is not present
+ *
+ * @public
+ * @param {String} id
+ *
+ * @returns {void}
+ */
removeId: function (id) {
if (!this.hasId(id)) {
throw new Error('Id not found');
@@ -3462,9 +3462,9 @@
}
},
- /****************************************
- * SELECTOR
- ****************************************/
+ /****************************************
+ * SELECTOR
+ ****************************************/
getItemsByFilter: function (filter) {
var result = [],
next = function (contentItem) {
@@ -3508,9 +3508,9 @@
return instances;
},
- /****************************************
- * PACKAGE PRIVATE
- ****************************************/
+ /****************************************
+ * PACKAGE PRIVATE
+ ****************************************/
_$getItemsByProperty: function (key, value) {
return this.getItemsByFilter(function (item) {
return item[key] === value;
@@ -3555,11 +3555,11 @@
}
},
- /**
- * Destroys this item ands its children
- *
- * @returns {void}
- */
+ /**
+ * Destroys this item ands its children
+ *
+ * @returns {void}
+ */
_$destroy: function () {
this.emitBubblingEvent('beforeItemDestroyed');
this.callDownwards('_$destroy', [], true, true);
@@ -3567,17 +3567,17 @@
this.emitBubblingEvent('itemDestroyed');
},
- /**
- * Returns the area the component currently occupies in the format
- *
- * {
- * x1: int
- * xy: int
- * y1: int
- * y2: int
- * contentItem: contentItem
- * }
- */
+ /**
+ * Returns the area the component currently occupies in the format
+ *
+ * {
+ * x1: int
+ * xy: int
+ * y1: int
+ * y2: int
+ * contentItem: contentItem
+ * }
+ */
_$getArea: function (element) {
element = element || this.element;
@@ -3595,17 +3595,17 @@
};
},
- /**
- * The tree of content items is created in two steps: First all content items are instantiated,
- * then init is called recursively from top to bottem. This is the basic init function,
- * it can be used, extended or overwritten by the content items
- *
- * Its behaviour depends on the content item
- *
- * @package private
- *
- * @returns {void}
- */
+ /**
+ * The tree of content items is created in two steps: First all content items are instantiated,
+ * then init is called recursively from top to bottem. This is the basic init function,
+ * it can be used, extended or overwritten by the content items
+ *
+ * Its behaviour depends on the content item
+ *
+ * @package private
+ *
+ * @returns {void}
+ */
_$init: function () {
var i;
this.setSize();
@@ -3619,26 +3619,26 @@
this.emitBubblingEvent(this.type + 'Created');
},
- /**
- * Emit an event that bubbles up the item tree.
- *
- * @param {String} name The name of the event
- *
- * @returns {void}
- */
+ /**
+ * Emit an event that bubbles up the item tree.
+ *
+ * @param {String} name The name of the event
+ *
+ * @returns {void}
+ */
emitBubblingEvent: function (name) {
var event = new lm.utils.BubblingEvent(name, this);
this.emit(name, event);
},
- /**
- * Private method, creates all content items for this node at initialisation time
- * PLEASE NOTE, please see addChild for adding contentItems add runtime
- * @private
- * @param {configuration item node} config
- *
- * @returns {void}
- */
+ /**
+ * Private method, creates all content items for this node at initialisation time
+ * PLEASE NOTE, please see addChild for adding contentItems add runtime
+ * @private
+ * @param {configuration item node} config
+ *
+ * @returns {void}
+ */
_createContentItems: function (config) {
var oContentItem, i;
@@ -3652,13 +3652,13 @@
}
},
- /**
- * Extends an item configuration node with default settings
- * @private
- * @param {configuration item node} config
- *
- * @returns {configuration item node} extended config
- */
+ /**
+ * Extends an item configuration node with default settings
+ * @private
+ * @param {configuration item node} config
+ *
+ * @returns {configuration item node} extended config
+ */
_extendItemNode: function (config) {
for (var key in lm.config.itemDefaultConfig) {
@@ -3670,26 +3670,26 @@
return config;
},
- /**
- * Called for every event on the item tree. Decides whether the event is a bubbling
- * event and propagates it to its parent
- *
- * @param {String} name the name of the event
- * @param {lm.utils.BubblingEvent} event
- *
- * @returns {void}
- */
+ /**
+ * Called for every event on the item tree. Decides whether the event is a bubbling
+ * event and propagates it to its parent
+ *
+ * @param {String} name the name of the event
+ * @param {lm.utils.BubblingEvent} event
+ *
+ * @returns {void}
+ */
_propagateEvent: function (name, event) {
if (event instanceof lm.utils.BubblingEvent &&
event.isPropagationStopped === false &&
this.isInitialised === true) {
- /**
- * In some cases (e.g. if an element is created from a DragSource) it
- * doesn't have a parent and is not below root. If that's the case
- * propagate the bubbling event from the top level of the substree directly
- * to the layoutManager
- */
+ /**
+ * In some cases (e.g. if an element is created from a DragSource) it
+ * doesn't have a parent and is not below root. If that's the case
+ * propagate the bubbling event from the top level of the substree directly
+ * to the layoutManager
+ */
if (this.isRoot === false && this.parent) {
this.parent.emit.apply(this.parent, Array.prototype.slice.call(arguments, 0));
} else {
@@ -3698,16 +3698,16 @@
}
},
- /**
- * All raw events bubble up to the root element. Some events that
- * are propagated to - and emitted by - the layoutManager however are
- * only string-based, batched and sanitized to make them more usable
- *
- * @param {String} name the name of the event
- *
- * @private
- * @returns {void}
- */
+ /**
+ * All raw events bubble up to the root element. Some events that
+ * are propagated to - and emitted by - the layoutManager however are
+ * only string-based, batched and sanitized to make them more usable
+ *
+ * @param {String} name the name of the event
+ *
+ * @private
+ * @returns {void}
+ */
_scheduleEventPropagationToLayoutManager: function (name, event) {
if (lm.utils.indexOf(name, this._throttledEvents) === -1) {
this.layoutManager.emit(name, event.origin);
@@ -3720,25 +3720,25 @@
},
- /**
- * Callback for events scheduled by _scheduleEventPropagationToLayoutManager
- *
- * @param {String} name the name of the event
- *
- * @private
- * @returns {void}
- */
+ /**
+ * Callback for events scheduled by _scheduleEventPropagationToLayoutManager
+ *
+ * @param {String} name the name of the event
+ *
+ * @private
+ * @returns {void}
+ */
_propagateEventToLayoutManager: function (name, event) {
this._pendingEventPropagations[name] = false;
this.layoutManager.emit(name, event);
}
});
- /**
- * @param {[type]} layoutManager [description]
- * @param {[type]} config [description]
- * @param {[type]} parent [description]
- */
+ /**
+ * @param {[type]} layoutManager [description]
+ * @param {[type]} config [description]
+ * @param {[type]} parent [description]
+ */
lm.items.Component = function (layoutManager, config, parent) {
lm.items.AbstractContentItem.call(this, layoutManager, config, parent);
@@ -3798,11 +3798,11 @@
lm.items.AbstractContentItem.prototype._$destroy.call(this);
},
- /**
- * Dragging onto a component directly is not an option
- *
- * @returns null
- */
+ /**
+ * Dragging onto a component directly is not an option
+ *
+ * @returns null
+ */
_$getArea: function () {
return null;
}
@@ -3841,9 +3841,9 @@
this.element.width(width);
this.element.height(height);
- /*
- * Root can be empty
- */
+ /*
+ * Root can be empty
+ */
if (this.contentItems[0]) {
this.contentItems[0].element.width(width);
this.contentItems[0].element.height(height);
@@ -3917,18 +3917,18 @@
lm.utils.copy(lm.items.RowOrColumn.prototype, {
- /**
- * Add a new contentItem to the Row or Column
- *
- * @param {lm.item.AbstractContentItem} contentItem
- * @param {[int]} index The position of the new item within the Row or Column.
- * If no index is provided the item will be added to the end
- * @param {[bool]} _$suspendResize If true the items won't be resized. This will leave the item in
- * an inconsistent state and is only intended to be used if multiple
- * children need to be added in one go and resize is called afterwards
- *
- * @returns {void}
- */
+ /**
+ * Add a new contentItem to the Row or Column
+ *
+ * @param {lm.item.AbstractContentItem} contentItem
+ * @param {[int]} index The position of the new item within the Row or Column.
+ * If no index is provided the item will be added to the end
+ * @param {[bool]} _$suspendResize If true the items won't be resized. This will leave the item in
+ * an inconsistent state and is only intended to be used if multiple
+ * children need to be added in one go and resize is called afterwards
+ *
+ * @returns {void}
+ */
addChild: function (contentItem, index, _$suspendResize) {
var newItemSize, itemSize, i, splitterElement;
@@ -3986,14 +3986,14 @@
},
- /**
- * Removes a child of this element
- *
- * @param {lm.items.AbstractContentItem} contentItem
- * @param {boolean} keepChild If true the child will be removed, but not destroyed
- *
- * @returns {void}
- */
+ /**
+ * Removes a child of this element
+ *
+ * @param {lm.items.AbstractContentItem} contentItem
+ * @param {boolean} keepChild If true the child will be removed, but not destroyed
+ *
+ * @returns {void}
+ */
removeChild: function (contentItem, keepChild) {
var removedItemSize = contentItem.config[this._dimension],
index = lm.utils.indexOf(contentItem, this.contentItems),
@@ -4005,10 +4005,10 @@
throw new Error('Can\'t remove child. ContentItem is not child of this Row or Column');
}
- /**
- * Remove the splitter before the item or after if the item happens
- * to be the first in the row/column
- */
+ /**
+ * Remove the splitter before the item or after if the item happens
+ * to be the first in the row/column
+ */
if (this._splitter[splitterIndex]) {
this._splitter[splitterIndex]._$destroy();
this._splitter.splice(splitterIndex, 1);
@@ -4019,9 +4019,9 @@
if (this.contentItems[i].config.fixed)
fixedItemSize += this.contentItems[i].config[this._dimension];
}
- /**
- * Allocate the space that the removed item occupied to the remaining items
- */
+ /**
+ * Allocate the space that the removed item occupied to the remaining items
+ */
for (i = 0; i < this.contentItems.length; i++) {
if (this.contentItems[i].config.fixed)
;
@@ -4044,14 +4044,14 @@
}
},
- /**
- * Replaces a child of this Row or Column with another contentItem
- *
- * @param {lm.items.AbstractContentItem} oldChild
- * @param {lm.items.AbstractContentItem} newChild
- *
- * @returns {void}
- */
+ /**
+ * Replaces a child of this Row or Column with another contentItem
+ *
+ * @param {lm.items.AbstractContentItem} oldChild
+ * @param {lm.items.AbstractContentItem} newChild
+ *
+ * @returns {void}
+ */
replaceChild: function (oldChild, newChild) {
var size = oldChild.config[this._dimension];
lm.items.AbstractContentItem.prototype.replaceChild.call(this, oldChild, newChild);
@@ -4060,11 +4060,11 @@
this.emitBubblingEvent('stateChanged');
},
- /**
- * Called whenever the dimensions of this item or one of its parents change
- *
- * @returns {void}
- */
+ /**
+ * Called whenever the dimensions of this item or one of its parents change
+ *
+ * @returns {void}
+ */
setSize: function () {
if (this.contentItems.length > 0) {
this._calculateRelativeSizes();
@@ -4074,15 +4074,15 @@
this.emit('resize');
},
- /**
- * Invoked recursively by the layout manager. AbstractContentItem.init appends
- * the contentItem's DOM elements to the container, RowOrColumn init adds splitters
- * in between them
- *
- * @package private
- * @override AbstractContentItem._$init
- * @returns {void}
- */
+ /**
+ * Invoked recursively by the layout manager. AbstractContentItem.init appends
+ * the contentItem's DOM elements to the container, RowOrColumn init adds splitters
+ * in between them
+ *
+ * @package private
+ * @override AbstractContentItem._$init
+ * @returns {void}
+ */
_$init: function () {
if (this.isInitialised === true) return;
@@ -4095,15 +4095,15 @@
}
},
- /**
- * Turns the relative sizes calculated by _calculateRelativeSizes into
- * absolute pixel values and applies them to the children's DOM elements
- *
- * Assigns additional pixels to counteract Math.floor
- *
- * @private
- * @returns {void}
- */
+ /**
+ * Turns the relative sizes calculated by _calculateRelativeSizes into
+ * absolute pixel values and applies them to the children's DOM elements
+ *
+ * Assigns additional pixels to counteract Math.floor
+ *
+ * @private
+ * @returns {void}
+ */
_setAbsoluteSizes: function () {
var i,
sizeData = this._calculateAbsoluteSizes();
@@ -4123,10 +4123,10 @@
}
},
- /**
- * Calculates the absolute sizes of all of the children of this Item.
- * @returns {object} - Set with absolute sizes and additional pixels.
- */
+ /**
+ * Calculates the absolute sizes of all of the children of this Item.
+ * @returns {object} - Set with absolute sizes and additional pixels.
+ */
_calculateAbsoluteSizes: function () {
var i,
totalSplitterSize = (this.contentItems.length - 1) * this._splitterSize,
@@ -4164,27 +4164,27 @@
};
},
- /**
- * Calculates the relative sizes of all children of this Item. The logic
- * is as follows:
- *
- * - Add up the total size of all items that have a configured size
- *
- * - If the total == 100 (check for floating point errors)
- * Excellent, job done
- *
- * - If the total is > 100,
- * set the size of items without set dimensions to 1/3 and add this to the total
- * set the size off all items so that the total is hundred relative to their original size
- *
- * - If the total is < 100
- * If there are items without set dimensions, distribute the remainder to 100 evenly between them
- * If there are no items without set dimensions, increase all items sizes relative to
- * their original size so that they add up to 100
- *
- * @private
- * @returns {void}
- */
+ /**
+ * Calculates the relative sizes of all children of this Item. The logic
+ * is as follows:
+ *
+ * - Add up the total size of all items that have a configured size
+ *
+ * - If the total == 100 (check for floating point errors)
+ * Excellent, job done
+ *
+ * - If the total is > 100,
+ * set the size of items without set dimensions to 1/3 and add this to the total
+ * set the size off all items so that the total is hundred relative to their original size
+ *
+ * - If the total is < 100
+ * If there are items without set dimensions, distribute the remainder to 100 evenly between them
+ * If there are no items without set dimensions, increase all items sizes relative to
+ * their original size so that they add up to 100
+ *
+ * @private
+ * @returns {void}
+ */
_calculateRelativeSizes: function () {
var i,
@@ -4200,17 +4200,17 @@
}
}
- /**
- * Everything adds up to hundred, all good :-)
- */
+ /**
+ * Everything adds up to hundred, all good :-)
+ */
if (Math.round(total) === 100) {
this._respectMinItemWidth();
return;
}
- /**
- * Allocate the remaining size to the items without a set dimension
- */
+ /**
+ * Allocate the remaining size to the items without a set dimension
+ */
if (Math.round(total) < 100 && itemsWithoutSetDimension.length > 0) {
for (i = 0; i < itemsWithoutSetDimension.length; i++) {
itemsWithoutSetDimension[i].config[dimension] = (100 - total) / itemsWithoutSetDimension.length;
@@ -4219,12 +4219,12 @@
return;
}
- /**
- * If the total is > 100, but there are also items without a set dimension left, assing 50
- * as their dimension and add it to the total
- *
- * This will be reset in the next step
- */
+ /**
+ * If the total is > 100, but there are also items without a set dimension left, assing 50
+ * as their dimension and add it to the total
+ *
+ * This will be reset in the next step
+ */
if (Math.round(total) > 100) {
for (i = 0; i < itemsWithoutSetDimension.length; i++) {
itemsWithoutSetDimension[i].config[dimension] = 50;
@@ -4232,9 +4232,9 @@
}
}
- /**
- * Set every items size relative to 100 relative to its size to total
- */
+ /**
+ * Set every items size relative to 100 relative to its size to total
+ */
for (i = 0; i < this.contentItems.length; i++) {
this.contentItems[i].config[dimension] = (this.contentItems[i].config[dimension] / total) * 100;
}
@@ -4242,10 +4242,10 @@
this._respectMinItemWidth();
},
- /**
- * Adjusts the column widths to respect the dimensions minItemWidth if set.
- * @returns {}
- */
+ /**
+ * Adjusts the column widths to respect the dimensions minItemWidth if set.
+ * @returns {}
+ */
_respectMinItemWidth: function () {
var minItemWidth = this.layoutManager.config.dimensions ? (this.layoutManager.config.dimensions.minItemWidth || 0) : 0,
sizeData = null,
@@ -4266,9 +4266,9 @@
sizeData = this._calculateAbsoluteSizes();
- /**
- * Figure out how much we are under the min item size total and how much room we have to use.
- */
+ /**
+ * Figure out how much we are under the min item size total and how much room we have to use.
+ */
for (var i = 0; i < this.contentItems.length; i++) {
contentItem = this.contentItems[i];
@@ -4288,16 +4288,16 @@
allEntries.push(entry);
}
- /**
- * If there is nothing under min, or there is not enough over to make up the difference, do nothing.
- */
+ /**
+ * If there is nothing under min, or there is not enough over to make up the difference, do nothing.
+ */
if (totalUnderMin === 0 || totalUnderMin > totalOverMin) {
return;
}
- /**
- * Evenly reduce all columns that are over the min item width to make up the difference.
- */
+ /**
+ * Evenly reduce all columns that are over the min item width to make up the difference.
+ */
reducePercent = totalUnderMin / totalOverMin;
remainingWidth = totalUnderMin;
for (i = 0; i < entriesOverMin.length; i++) {
@@ -4307,31 +4307,31 @@
entry.width -= reducedWidth;
}
- /**
- * Take anything remaining from the last item.
- */
+ /**
+ * Take anything remaining from the last item.
+ */
if (remainingWidth !== 0) {
allEntries[allEntries.length - 1].width -= remainingWidth;
}
- /**
- * Set every items size relative to 100 relative to its size to total
- */
+ /**
+ * Set every items size relative to 100 relative to its size to total
+ */
for (i = 0; i < this.contentItems.length; i++) {
this.contentItems[i].config.width = (allEntries[i].width / sizeData.totalWidth) * 100;
}
},
- /**
- * Instantiates a new lm.controls.Splitter, binds events to it and adds
- * it to the array of splitters at the position specified as the index argument
- *
- * What it doesn't do though is append the splitter to the DOM
- *
- * @param {Int} index The position of the splitter
- *
- * @returns {lm.controls.Splitter}
- */
+ /**
+ * Instantiates a new lm.controls.Splitter, binds events to it and adds
+ * it to the array of splitters at the position specified as the index argument
+ *
+ * What it doesn't do though is append the splitter to the DOM
+ *
+ * @param {Int} index The position of the splitter
+ *
+ * @returns {lm.controls.Splitter}
+ */
_createSplitter: function (index) {
var splitter;
splitter = new lm.controls.Splitter(this._isColumn, this._splitterSize, this._splitterGrabSize);
@@ -4342,16 +4342,16 @@
return splitter;
},
- /**
- * Locates the instance of lm.controls.Splitter in the array of
- * registered splitters and returns a map containing the contentItem
- * before and after the splitters, both of which are affected if the
- * splitter is moved
- *
- * @param {lm.controls.Splitter} splitter
- *
- * @returns {Object} A map of contentItems that the splitter affects
- */
+ /**
+ * Locates the instance of lm.controls.Splitter in the array of
+ * registered splitters and returns a map containing the contentItem
+ * before and after the splitters, both of which are affected if the
+ * splitter is moved
+ *
+ * @param {lm.controls.Splitter} splitter
+ *
+ * @returns {Object} A map of contentItems that the splitter affects
+ */
_getItemsForSplitter: function (splitter) {
var index = lm.utils.indexOf(splitter, this._splitter);
@@ -4361,11 +4361,11 @@
};
},
- /**
- * Gets the minimum dimensions for the given item configuration array
- * @param item
- * @private
- */
+ /**
+ * Gets the minimum dimensions for the given item configuration array
+ * @param item
+ * @private
+ */
_getMinimumDimensions: function (arr) {
var minWidth = 0, minHeight = 0;
@@ -4377,14 +4377,14 @@
return { horizontal: minWidth, vertical: minHeight };
},
- /**
- * Invoked when a splitter's dragListener fires dragStart. Calculates the splitters
- * movement area once (so that it doesn't need calculating on every mousemove event)
- *
- * @param {lm.controls.Splitter} splitter
- *
- * @returns {void}
- */
+ /**
+ * Invoked when a splitter's dragListener fires dragStart. Calculates the splitters
+ * movement area once (so that it doesn't need calculating on every mousemove event)
+ *
+ * @param {lm.controls.Splitter} splitter
+ *
+ * @returns {void}
+ */
_onSplitterDragStart: function (splitter) {
var items = this._getItemsForSplitter(splitter),
minSize = this.layoutManager.config.dimensions[this._isColumn ? 'minItemHeight' : 'minItemWidth'];
@@ -4400,16 +4400,16 @@
this._splitterMaxPosition = items.after.element[this._dimension]() - (afterMinSize || minSize);
},
- /**
- * Invoked when a splitter's DragListener fires drag. Updates the splitters DOM position,
- * but not the sizes of the elements the splitter controls in order to minimize resize events
- *
- * @param {lm.controls.Splitter} splitter
- * @param {Int} offsetX Relative pixel values to the splitters original position. Can be negative
- * @param {Int} offsetY Relative pixel values to the splitters original position. Can be negative
- *
- * @returns {void}
- */
+ /**
+ * Invoked when a splitter's DragListener fires drag. Updates the splitters DOM position,
+ * but not the sizes of the elements the splitter controls in order to minimize resize events
+ *
+ * @param {lm.controls.Splitter} splitter
+ * @param {Int} offsetX Relative pixel values to the splitters original position. Can be negative
+ * @param {Int} offsetY Relative pixel values to the splitters original position. Can be negative
+ *
+ * @returns {void}
+ */
_onSplitterDrag: function (splitter, offsetX, offsetY) {
var offset = this._isColumn ? offsetY : offsetX;
@@ -4419,15 +4419,15 @@
}
},
- /**
- * Invoked when a splitter's DragListener fires dragStop. Resets the splitters DOM position,
- * and applies the new sizes to the elements before and after the splitter and their children
- * on the next animation frame
- *
- * @param {lm.controls.Splitter} splitter
- *
- * @returns {void}
- */
+ /**
+ * Invoked when a splitter's DragListener fires dragStop. Resets the splitters DOM position,
+ * and applies the new sizes to the elements before and after the splitter and their children
+ * on the next animation frame
+ *
+ * @param {lm.controls.Splitter} splitter
+ *
+ * @returns {void}
+ */
_onSplitterDragStop: function (splitter) {
var items = this._getItemsForSplitter(splitter),
@@ -4451,7 +4451,7 @@
lm.items.Stack = function (layoutManager, config, parent) {
lm.items.AbstractContentItem.call(this, layoutManager, config, parent);
- this.element = $('');
+ this.element = $('
Click to create a new tab
');
this._activeContentItem = null;
var cfg = layoutManager.config;
this._header = { // defaults' reconstruction from old configuration style
@@ -4575,13 +4575,13 @@
this.emitBubblingEvent('stateChanged');
},
- /**
- * Validates that the stack is still closable or not. If a stack is able
- * to close, but has a non closable component added to it, the stack is no
- * longer closable until all components are closable.
- *
- * @returns {void}
- */
+ /**
+ * Validates that the stack is still closable or not. If a stack is able
+ * to close, but has a non closable component added to it, the stack is no
+ * longer closable until all components are closable.
+ *
+ * @returns {void}
+ */
_$validateClosability: function () {
var contentItem,
isClosable,
@@ -4607,51 +4607,51 @@
},
- /**
- * Ok, this one is going to be the tricky one: The user has dropped {contentItem} onto this stack.
- *
- * It was dropped on either the stacks header or the top, right, bottom or left bit of the content area
- * (which one of those is stored in this._dropSegment). Now, if the user has dropped on the header the case
- * is relatively clear: We add the item to the existing stack... job done (might be good to have
- * tab reordering at some point, but lets not sweat it right now)
- *
- * If the item was dropped on the content part things are a bit more complicated. If it was dropped on either the
- * top or bottom region we need to create a new column and place the items accordingly.
- * Unless, of course if the stack is already within a column... in which case we want
- * to add the newly created item to the existing column...
- * either prepend or append it, depending on wether its top or bottom.
- *
- * Same thing for rows and left / right drop segments... so in total there are 9 things that can potentially happen
- * (left, top, right, bottom) * is child of the right parent (row, column) + header drop
- *
- * @param {lm.item} contentItem
- *
- * @returns {void}
- */
+ /**
+ * Ok, this one is going to be the tricky one: The user has dropped {contentItem} onto this stack.
+ *
+ * It was dropped on either the stacks header or the top, right, bottom or left bit of the content area
+ * (which one of those is stored in this._dropSegment). Now, if the user has dropped on the header the case
+ * is relatively clear: We add the item to the existing stack... job done (might be good to have
+ * tab reordering at some point, but lets not sweat it right now)
+ *
+ * If the item was dropped on the content part things are a bit more complicated. If it was dropped on either the
+ * top or bottom region we need to create a new column and place the items accordingly.
+ * Unless, of course if the stack is already within a column... in which case we want
+ * to add the newly created item to the existing column...
+ * either prepend or append it, depending on wether its top or bottom.
+ *
+ * Same thing for rows and left / right drop segments... so in total there are 9 things that can potentially happen
+ * (left, top, right, bottom) * is child of the right parent (row, column) + header drop
+ *
+ * @param {lm.item} contentItem
+ *
+ * @returns {void}
+ */
_$onDrop: function (contentItem) {
- /*
- * The item was dropped on the header area. Just add it as a child of this stack and
- * get the hell out of this logic
- */
+ /*
+ * The item was dropped on the header area. Just add it as a child of this stack and
+ * get the hell out of this logic
+ */
if (this._dropSegment === 'header') {
this._resetHeaderDropZone();
this.addChild(contentItem, this._dropIndex);
return;
}
- /*
- * The stack is empty. Let's just add the element.
- */
+ /*
+ * The stack is empty. Let's just add the element.
+ */
if (this._dropSegment === 'body') {
this.addChild(contentItem);
return;
}
- /*
- * The item was dropped on the top-, left-, bottom- or right- part of the content. Let's
- * aggregate some conditions to make the if statements later on more readable
- */
+ /*
+ * The item was dropped on the top-, left-, bottom- or right- part of the content. Let's
+ * aggregate some conditions to make the if statements later on more readable
+ */
var isVertical = this._dropSegment === 'top' || this._dropSegment === 'bottom',
isHorizontal = this._dropSegment === 'left' || this._dropSegment === 'right',
insertBefore = this._dropSegment === 'top' || this._dropSegment === 'left',
@@ -4662,9 +4662,9 @@
stack,
rowOrColumn;
- /*
- * The content item can be either a component or a stack. If it is a component, wrap it into a stack
- */
+ /*
+ * The content item can be either a component or a stack. If it is a component, wrap it into a stack
+ */
if (contentItem.isComponent) {
stack = this.layoutManager.createContentItem({
type: 'stack',
@@ -4675,20 +4675,20 @@
contentItem = stack;
}
- /*
- * If the item is dropped on top or bottom of a column or left and right of a row, it's already
- * layd out in the correct way. Just add it as a child
- */
+ /*
+ * If the item is dropped on top or bottom of a column or left and right of a row, it's already
+ * layd out in the correct way. Just add it as a child
+ */
if (hasCorrectParent) {
index = lm.utils.indexOf(this, this.parent.contentItems);
this.parent.addChild(contentItem, insertBefore ? index : index + 1, true);
this.config[dimension] *= 0.5;
contentItem.config[dimension] = this.config[dimension];
this.parent.callDownwards('setSize');
- /*
- * This handles items that are dropped on top or bottom of a row or left / right of a column. We need
- * to create the appropriate contentItem for them to live in
- */
+ /*
+ * This handles items that are dropped on top or bottom of a row or left / right of a column. We need
+ * to create the appropriate contentItem for them to live in
+ */
} else {
type = isVertical ? 'column' : 'row';
rowOrColumn = this.layoutManager.createContentItem({ type: type }, this);
@@ -4703,15 +4703,15 @@
}
},
- /**
- * If the user hovers above the header part of the stack, indicate drop positions for tabs.
- * otherwise indicate which segment of the body the dragged item would be dropped on
- *
- * @param {Int} x Absolute Screen X
- * @param {Int} y Absolute Screen Y
- *
- * @returns {void}
- */
+ /**
+ * If the user hovers above the header part of the stack, indicate drop positions for tabs.
+ * otherwise indicate which segment of the body the dragged item would be dropped on
+ *
+ * @param {Int} x Absolute Screen X
+ * @param {Int} y Absolute Screen Y
+ *
+ * @returns {void}
+ */
_$highlightDropZone: function (x, y) {
var segment, area;
@@ -4761,17 +4761,17 @@
}
};
- /**
- * If this Stack is a parent to rows, columns or other stacks only its
- * header is a valid dropzone.
- */
+ /**
+ * If this Stack is a parent to rows, columns or other stacks only its
+ * header is a valid dropzone.
+ */
if (this._activeContentItem && this._activeContentItem.isComponent === false) {
return headerArea;
}
- /**
- * Highlight the entire body if the stack is empty
- */
+ /**
+ * Highlight the entire body if the stack is empty
+ */
if (this.contentItems.length === 0) {
this._contentAreaDimensions.body = {
@@ -4971,13 +4971,13 @@
lm.utils.BubblingEvent.prototype.stopPropagation = function () {
this.isPropagationStopped = true;
};
- /**
- * Minifies and unminifies configs by replacing frequent keys
- * and values with one letter substitutes. Config options must
- * retain array position/index, add new options at the end.
- *
- * @constructor
- */
+ /**
+ * Minifies and unminifies configs by replacing frequent keys
+ * and values with one letter substitutes. Config options must
+ * retain array position/index, add new options at the end.
+ *
+ * @constructor
+ */
lm.utils.ConfigMinifier = function () {
this._keys = [
'settings',
@@ -5031,160 +5031,160 @@
'close',
'maximise',
'minimise',
- 'open in new window'
+ 'new tab'
];
};
lm.utils.copy(lm.utils.ConfigMinifier.prototype, {
- /**
- * Takes a GoldenLayout configuration object and
- * replaces its keys and values recursively with
- * one letter counterparts
- *
- * @param {Object} config A GoldenLayout config object
- *
- * @returns {Object} minified config
- */
+ /**
+ * Takes a GoldenLayout configuration object and
+ * replaces its keys and values recursively with
+ * one letter counterparts
+ *
+ * @param {Object} config A GoldenLayout config object
+ *
+ * @returns {Object} minified config
+ */
minifyConfig: function (config) {
var min = {};
this._nextLevel(config, min, '_min');
return min;
},
- /**
- * Takes a configuration Object that was previously minified
- * using minifyConfig and returns its original version
- *
- * @param {Object} minifiedConfig
- *
- * @returns {Object} the original configuration
- */
+ /**
+ * Takes a configuration Object that was previously minified
+ * using minifyConfig and returns its original version
+ *
+ * @param {Object} minifiedConfig
+ *
+ * @returns {Object} the original configuration
+ */
unminifyConfig: function (minifiedConfig) {
var orig = {};
this._nextLevel(minifiedConfig, orig, '_max');
return orig;
},
- /**
- * Recursive function, called for every level of the config structure
- *
- * @param {Array|Object} orig
- * @param {Array|Object} min
- * @param {String} translationFn
- *
- * @returns {void}
- */
+ /**
+ * Recursive function, called for every level of the config structure
+ *
+ * @param {Array|Object} orig
+ * @param {Array|Object} min
+ * @param {String} translationFn
+ *
+ * @returns {void}
+ */
_nextLevel: function (from, to, translationFn) {
var key, minKey;
for (key in from) {
- /**
- * For in returns array indices as keys, so let's cast them to numbers
- */
+ /**
+ * For in returns array indices as keys, so let's cast them to numbers
+ */
if (from instanceof Array) key = parseInt(key, 10);
- /**
- * In case something has extended Object prototypes
- */
+ /**
+ * In case something has extended Object prototypes
+ */
if (!from.hasOwnProperty(key)) continue;
- /**
- * Translate the key to a one letter substitute
- */
+ /**
+ * Translate the key to a one letter substitute
+ */
minKey = this[translationFn](key, this._keys);
- /**
- * For Arrays and Objects, create a new Array/Object
- * on the minified object and recurse into it
- */
+ /**
+ * For Arrays and Objects, create a new Array/Object
+ * on the minified object and recurse into it
+ */
if (typeof from[key] === 'object') {
to[minKey] = from[key] instanceof Array ? [] : {};
this._nextLevel(from[key], to[minKey], translationFn);
- /**
- * For primitive values (Strings, Numbers, Boolean etc.)
- * minify the value
- */
+ /**
+ * For primitive values (Strings, Numbers, Boolean etc.)
+ * minify the value
+ */
} else {
to[minKey] = this[translationFn](from[key], this._values);
}
}
},
- /**
- * Minifies value based on a dictionary
- *
- * @param {String|Boolean} value
- * @param {Array} dictionary
- *
- * @returns {String} The minified version
- */
+ /**
+ * Minifies value based on a dictionary
+ *
+ * @param {String|Boolean} value
+ * @param {Array} dictionary
+ *
+ * @returns {String} The minified version
+ */
_min: function (value, dictionary) {
- /**
- * If a value actually is a single character, prefix it
- * with ___ to avoid mistaking it for a minification code
- */
+ /**
+ * If a value actually is a single character, prefix it
+ * with ___ to avoid mistaking it for a minification code
+ */
if (typeof value === 'string' && value.length === 1) {
return '___' + value;
}
var index = lm.utils.indexOf(value, dictionary);
- /**
- * value not found in the dictionary, return it unmodified
- */
+ /**
+ * value not found in the dictionary, return it unmodified
+ */
if (index === -1) {
return value;
- /**
- * value found in dictionary, return its base36 counterpart
- */
+ /**
+ * value found in dictionary, return its base36 counterpart
+ */
} else {
return index.toString(36);
}
},
_max: function (value, dictionary) {
- /**
- * value is a single character. Assume that it's a translation
- * and return the original value from the dictionary
- */
+ /**
+ * value is a single character. Assume that it's a translation
+ * and return the original value from the dictionary
+ */
if (typeof value === 'string' && value.length === 1) {
return dictionary[parseInt(value, 36)];
}
- /**
- * value originally was a single character and was prefixed with ___
- * to avoid mistaking it for a translation. Remove the prefix
- * and return the original character
- */
+ /**
+ * value originally was a single character and was prefixed with ___
+ * to avoid mistaking it for a translation. Remove the prefix
+ * and return the original character
+ */
if (typeof value === 'string' && value.substr(0, 3) === '___') {
return value[3];
}
- /**
- * value was not minified
- */
+ /**
+ * value was not minified
+ */
return value;
}
});
- /**
- * An EventEmitter singleton that propagates events
- * across multiple windows. This is a little bit trickier since
- * windows are allowed to open childWindows in their own right
- *
- * This means that we deal with a tree of windows. Hence the rules for event propagation are:
- *
- * - Propagate events from this layout to both parents and children
- * - Propagate events from parent to this and children
- * - Propagate events from children to the other children (but not the emitting one) and the parent
- *
- * @constructor
- *
- * @param {lm.LayoutManager} layoutManager
- */
+ /**
+ * An EventEmitter singleton that propagates events
+ * across multiple windows. This is a little bit trickier since
+ * windows are allowed to open childWindows in their own right
+ *
+ * This means that we deal with a tree of windows. Hence the rules for event propagation are:
+ *
+ * - Propagate events from this layout to both parents and children
+ * - Propagate events from parent to this and children
+ * - Propagate events from children to the other children (but not the emitting one) and the parent
+ *
+ * @constructor
+ *
+ * @param {lm.LayoutManager} layoutManager
+ */
lm.utils.EventHub = function (layoutManager) {
lm.utils.EventEmitter.call(this);
this._layoutManager = layoutManager;
@@ -5195,15 +5195,15 @@
$(window).on('gl_child_event', this._boundOnEventFromChild);
};
- /**
- * Called on every event emitted on this eventHub, regardles of origin.
- *
- * @private
- *
- * @param {Mixed}
- *
- * @returns {void}
- */
+ /**
+ * Called on every event emitted on this eventHub, regardles of origin.
+ *
+ * @private
+ *
+ * @param {Mixed}
+ *
+ * @returns {void}
+ */
lm.utils.EventHub.prototype._onEventFromThis = function () {
var args = Array.prototype.slice.call(arguments);
@@ -5217,40 +5217,40 @@
this._childEventSource = null;
};
- /**
- * Called by the parent layout.
- *
- * @param {Array} args Event name + arguments
- *
- * @returns {void}
- */
+ /**
+ * Called by the parent layout.
+ *
+ * @param {Array} args Event name + arguments
+ *
+ * @returns {void}
+ */
lm.utils.EventHub.prototype._$onEventFromParent = function (args) {
this._dontPropagateToParent = args[0];
this.emit.apply(this, args);
};
- /**
- * Callback for child events raised on the window
- *
- * @param {DOMEvent} event
- * @private
- *
- * @returns {void}
- */
+ /**
+ * Callback for child events raised on the window
+ *
+ * @param {DOMEvent} event
+ * @private
+ *
+ * @returns {void}
+ */
lm.utils.EventHub.prototype._onEventFromChild = function (event) {
this._childEventSource = event.originalEvent.__gl;
this.emit.apply(this, event.originalEvent.__glArgs);
};
- /**
- * Propagates the event to the parent by emitting
- * it on the parent's DOM window
- *
- * @param {Array} args Event name + arguments
- * @private
- *
- * @returns {void}
- */
+ /**
+ * Propagates the event to the parent by emitting
+ * it on the parent's DOM window
+ *
+ * @param {Array} args Event name + arguments
+ * @private
+ *
+ * @returns {void}
+ */
lm.utils.EventHub.prototype._propagateToParent = function (args) {
var event,
eventName = 'gl_child_event';
@@ -5274,14 +5274,14 @@
}
};
- /**
- * Propagate events to children
- *
- * @param {Array} args Event name + arguments
- * @private
- *
- * @returns {void}
- */
+ /**
+ * Propagate events to children
+ *
+ * @param {Array} args Event name + arguments
+ * @private
+ *
+ * @returns {void}
+ */
lm.utils.EventHub.prototype._propagateToChildren = function (args) {
var childGl, i;
@@ -5295,25 +5295,25 @@
};
- /**
- * Destroys the EventHub
- *
- * @public
- * @returns {void}
- */
+ /**
+ * Destroys the EventHub
+ *
+ * @public
+ * @returns {void}
+ */
lm.utils.EventHub.prototype.destroy = function () {
$(window).off('gl_child_event', this._boundOnEventFromChild);
};
- /**
- * A specialised GoldenLayout component that binds GoldenLayout container
- * lifecycle events to react components
- *
- * @constructor
- *
- * @param {lm.container.ItemContainer} container
- * @param {Object} state state is not required for react components
- */
+ /**
+ * A specialised GoldenLayout component that binds GoldenLayout container
+ * lifecycle events to react components
+ *
+ * @constructor
+ *
+ * @param {lm.container.ItemContainer} container
+ * @param {Object} state state is not required for react components
+ */
lm.utils.ReactComponentHandler = function (container, state) {
this._reactComponent = null;
this._originalComponentWillUpdate = null;
@@ -5326,15 +5326,15 @@
lm.utils.copy(lm.utils.ReactComponentHandler.prototype, {
- /**
- * Creates the react class and component and hydrates it with
- * the initial state - if one is present
- *
- * By default, react's getInitialState will be used
- *
- * @private
- * @returns {void}
- */
+ /**
+ * Creates the react class and component and hydrates it with
+ * the initial state - if one is present
+ *
+ * By default, react's getInitialState will be used
+ *
+ * @private
+ * @returns {void}
+ */
_render: function () {
this._reactComponent = ReactDOM.render(this._getReactComponent(), this._container.getElement()[0]);
this._originalComponentWillUpdate = this._reactComponent.componentWillUpdate || function () {
@@ -5345,36 +5345,36 @@
}
},
- /**
- * Removes the component from the DOM and thus invokes React's unmount lifecycle
- *
- * @private
- * @returns {void}
- */
+ /**
+ * Removes the component from the DOM and thus invokes React's unmount lifecycle
+ *
+ * @private
+ * @returns {void}
+ */
_destroy: function () {
ReactDOM.unmountComponentAtNode(this._container.getElement()[0]);
this._container.off('open', this._render, this);
this._container.off('destroy', this._destroy, this);
},
- /**
- * Hooks into React's state management and applies the componentstate
- * to GoldenLayout
- *
- * @private
- * @returns {void}
- */
+ /**
+ * Hooks into React's state management and applies the componentstate
+ * to GoldenLayout
+ *
+ * @private
+ * @returns {void}
+ */
_onUpdate: function (nextProps, nextState) {
this._container.setState(nextState);
this._originalComponentWillUpdate.call(this._reactComponent, nextProps, nextState);
},
- /**
- * Retrieves the react class from GoldenLayout's registry
- *
- * @private
- * @returns {React.Class}
- */
+ /**
+ * Retrieves the react class from GoldenLayout's registry
+ *
+ * @private
+ * @returns {React.Class}
+ */
_getReactClass: function () {
var componentName = this._container._config.component;
var reactClass;
@@ -5393,12 +5393,12 @@
return reactClass;
},
- /**
- * Copies and extends the properties array and returns the React element
- *
- * @private
- * @returns {React.Element}
- */
+ /**
+ * Copies and extends the properties array and returns the React element
+ *
+ * @private
+ * @returns {React.Element}
+ */
_getReactComponent: function () {
var defaultProps = {
glEventHub: this._container.layoutManager.eventHub,
diff --git a/src/client/views/MainView.scss b/src/client/views/MainView.scss
index 07ca0257c..08bcd55ae 100644
--- a/src/client/views/MainView.scss
+++ b/src/client/views/MainView.scss
@@ -63,6 +63,10 @@
.mainView-container {
color: $dark-gray;
+ .lm_goldenlayout {
+ background: $medium-gray;
+ }
+
.lm_title {
background: $light-gray;
color: $dark-gray;
@@ -153,7 +157,8 @@
cursor: auto;
}
-.mainView-innerContent, .mainView-innerContent-dark {
+.mainView-innerContent,
+.mainView-innerContent-dark {
display: contents;
flex-direction: row;
position: relative;
@@ -175,44 +180,52 @@
position: absolute;
z-index: 2;
background-color: $medium-gray;
+
.editable-title {
background-color: $light-gray;
}
}
}
+
.mainView-libraryHandle {
background-color: $light-gray;
}
-.mainView-innerContent-dark
-{
+
+.mainView-innerContent-dark {
.propertiesView {
background-color: #252525;
+
input {
background-color: $medium-gray;
}
- .propertiesView-sharingTable
- {
+
+ .propertiesView-sharingTable {
background-color: $medium-gray;
}
+
.editable-title {
background-color: $medium-gray;
}
+
.propertiesView-field {
background-color: $medium-gray;
}
}
+
.mainView-propertiesDragger,
.mainView-libraryHandle {
background: #353535;
}
}
+
.mainView-container-dark {
.contextMenu-cont {
background: $medium-gray;
color: $white;
+
input::placeholder {
- color:$white;
+ color: $white;
}
}
}
@@ -432,6 +445,7 @@
right: unset !important;
left: 0 !important;
}
+
.lm_close_tab {
padding: 0;
width: 15px !important;
@@ -443,7 +457,9 @@
right: unset !important;
left: 0 !important;
}
-.lm_tab, .lm_tab_active {
+
+.lm_tab,
+.lm_tab_active {
display: flex !important;
padding-right: 0 !important;
}
\ No newline at end of file
diff --git a/src/client/views/collections/CollectionDockingView.scss b/src/client/views/collections/CollectionDockingView.scss
index a054f0ae1..d1b8b2df0 100644
--- a/src/client/views/collections/CollectionDockingView.scss
+++ b/src/client/views/collections/CollectionDockingView.scss
@@ -55,6 +55,29 @@
display: inline;
}
+.empty-tabs-message {
+ position: absolute;
+ width: 100%;
+ z-index: 1;
+ top: 50%;
+ z-index: 1;
+ text-align: center;
+ font-size: 18;
+ color: $dark-gray;
+
+ img {
+ position: relative;
+ top: -1px;
+ margin: 0 5px;
+ }
+}
+
+.lm_header,
+.lm_items {
+ z-index: 2;
+ position: relative;
+}
+
.collectiondockingview-container {
width: 100%;
height: 100%;
--
cgit v1.2.3-70-g09d2
From 02336134cff5f5789380bf5950864f4b95583cf6 Mon Sep 17 00:00:00 2001
From: 0x85FB9C51 <77808164+0x85FB9C51@users.noreply.github.com>
Date: Mon, 16 Aug 2021 16:09:13 -0400
Subject: commented column code
---
.../collectionSchema/CollectionSchemaMovableColumn.tsx | 18 ++++++++++++++++++
1 file changed, 18 insertions(+)
(limited to 'src')
diff --git a/src/client/views/collections/collectionSchema/CollectionSchemaMovableColumn.tsx b/src/client/views/collections/collectionSchema/CollectionSchemaMovableColumn.tsx
index 456c38c68..2df95ffd8 100644
--- a/src/client/views/collections/collectionSchema/CollectionSchemaMovableColumn.tsx
+++ b/src/client/views/collections/collectionSchema/CollectionSchemaMovableColumn.tsx
@@ -21,27 +21,38 @@ export interface MovableColumnProps {
ScreenToLocalTransform: () => Transform;
}
export class MovableColumn extends React.Component {
+ // The header of the column
private _header?: React.RefObject = React.createRef();
+ // The container of the function that is responsible for moving the column over to a new plac
private _colDropDisposer?: DragManager.DragDropDisposer;
+ // initial column position
private _startDragPosition: { x: number, y: number } = { x: 0, y: 0 };
+ // sensitivity to being dragged, in pixels
private _sensitivity: number = 16;
+ // Column reference ID
private _dragRef: React.RefObject = React.createRef();
onPointerEnter = (e: React.PointerEvent): void => {
+ // if the column is left-clicked and it is being dragged
if (e.buttons === 1 && SnappingManager.GetIsDragging()) {
this._header!.current!.className = "collectionSchema-col-wrapper";
document.addEventListener("pointermove", this.onDragMove, true);
}
}
+
onPointerLeave = (e: React.PointerEvent): void => {
this._header!.current!.className = "collectionSchema-col-wrapper";
document.removeEventListener("pointermove", this.onDragMove, true);
!e.buttons && document.removeEventListener("pointermove", this.onPointerMove);
}
+
onDragMove = (e: PointerEvent): void => {
+ // only take into account the horizonal direction when a column is dragged
const x = this.props.ScreenToLocalTransform().transformPoint(e.clientX, e.clientY);
const rect = this._header!.current!.getBoundingClientRect();
+ // Now store the point at the top center of the column when it was in its original position
const bounds = this.props.ScreenToLocalTransform().transformPoint(rect.left + ((rect.right - rect.left) / 2), rect.top);
+ // to be compared with its new horizontal position
const before = x[0] < bounds[0];
this._header!.current!.className = "collectionSchema-col-wrapper";
if (before) this._header!.current!.className += " col-before";
@@ -58,11 +69,15 @@ export class MovableColumn extends React.Component {
colDrop = (e: Event, de: DragManager.DropEvent) => {
document.removeEventListener("pointermove", this.onDragMove, true);
+ // we only care about whether the column is shifted to the side
const x = this.props.ScreenToLocalTransform().transformPoint(de.x, de.y);
+ // get the dimensions of the smallest rectangle that bounds the header
const rect = this._header!.current!.getBoundingClientRect();
const bounds = this.props.ScreenToLocalTransform().transformPoint(rect.left + ((rect.right - rect.left) / 2), rect.top);
+ // get whether the column was dragged before or after where it is now
const before = x[0] < bounds[0];
const colDragData = de.complete.columnDragData;
+ // if there is colDragData, which happen when the drag is complete, reorder the columns according to the established variables
if (colDragData) {
e.stopPropagation();
this.props.reorderColumns(colDragData.colKey, this.props.columnValue, before, this.props.allColumns);
@@ -85,8 +100,10 @@ export class MovableColumn extends React.Component {
document.removeEventListener("pointermove", onRowMove);
document.removeEventListener('pointerup', onRowUp);
};
+ // if the left mouse button is the one being held
if (e.buttons === 1) {
const [dx, dy] = this.props.ScreenToLocalTransform().transformDirection(e.clientX - this._startDragPosition.x, e.clientY - this._startDragPosition.y);
+ // If the movemnt of the drag exceeds the sensitivity value
if (Math.abs(dx) + Math.abs(dy) > this._sensitivity) {
document.removeEventListener("pointermove", this.onPointerMove);
e.stopPropagation();
@@ -105,6 +122,7 @@ export class MovableColumn extends React.Component {
onPointerDown = (e: React.PointerEvent, ref: React.RefObject) => {
this._dragRef = ref;
const [dx, dy] = this.props.ScreenToLocalTransform().transformDirection(e.clientX, e.clientY);
+ // If the cell thing dragged is not being edited
if (!(e.target as any)?.tagName.includes("INPUT")) {
this._startDragPosition = { x: dx, y: dy };
document.addEventListener("pointermove", this.onPointerMove);
--
cgit v1.2.3-70-g09d2
From 9031708067ee16d7b7e6b2689f45ee54ea5f1e4a Mon Sep 17 00:00:00 2001
From: dinhanhtruong <70963346+dinhanhtruong@users.noreply.github.com>
Date: Tue, 17 Aug 2021 14:14:26 -0400
Subject: Added empty tabs message
todo: create buttons for recent tabs when all tabs in a dashboard are closed
---
src/client/documents/Documents.ts | 2 +-
src/client/goldenLayout.js | 8 +++++++-
src/client/views/MainView.tsx | 1 +
3 files changed, 9 insertions(+), 2 deletions(-)
(limited to 'src')
diff --git a/src/client/documents/Documents.ts b/src/client/documents/Documents.ts
index 48886aa3b..47e0377df 100644
--- a/src/client/documents/Documents.ts
+++ b/src/client/documents/Documents.ts
@@ -269,7 +269,7 @@ export class DocumentOptions {
linearViewIsExpanded?: boolean; // is linear view expanded
useLinkSmallAnchor?: boolean; // whether links to this document should use a miniature linkAnchorBox
border?: string; //for searchbox
- hoverBackgroundColor?: string; // background color of a label when hovered
+ hoverBackgroundColor?: string; // background color of a label when hovered
}
export namespace Docs {
diff --git a/src/client/goldenLayout.js b/src/client/goldenLayout.js
index db94cce3d..896237e1d 100644
--- a/src/client/goldenLayout.js
+++ b/src/client/goldenLayout.js
@@ -2355,6 +2355,7 @@
this.element.hide();
}
});
+
/**
* This class represents a header above a Stack ContentItem.
*
@@ -2362,6 +2363,7 @@
* @param {lm.item.AbstractContentItem} parent
*/
lm.controls.Header = function (layoutManager, parent) {
+
lm.utils.EventEmitter.call(this);
this.layoutManager = layoutManager;
@@ -4449,7 +4451,11 @@
lm.items.Stack = function (layoutManager, config, parent) {
lm.items.AbstractContentItem.call(this, layoutManager, config, parent);
- this.element = $('
Click to create a new tab
');
+ this.element = $(
+ '
'
+ + '
Click to create a new tab
'
+ + '
'
+ );
this._activeContentItem = null;
var cfg = layoutManager.config;
this._header = { // defaults' reconstruction from old configuration style
diff --git a/src/client/views/MainView.tsx b/src/client/views/MainView.tsx
index b0b8d7f41..ba8f2a4c8 100644
--- a/src/client/views/MainView.tsx
+++ b/src/client/views/MainView.tsx
@@ -448,6 +448,7 @@ export class MainView extends React.Component {
this.changeFollowBehavior("openExternal")}>
--
cgit v1.2.3-70-g09d2
From c5e96c72fcf149b9bcfe5f7f7a9c714de1d5fd9a Mon Sep 17 00:00:00 2001
From: 0x85FB9C51 <77808164+0x85FB9C51@users.noreply.github.com>
Date: Wed, 25 Aug 2021 16:58:57 -0400
Subject: added comment, fixed path issue
---
.../collectionSchema/CollectionSchemaCells.tsx | 239 +++++++++++----------
.../collectionSchema/CollectionSchemaHeaders.tsx | 2 +-
2 files changed, 126 insertions(+), 115 deletions(-)
(limited to 'src')
diff --git a/src/client/views/collections/collectionSchema/CollectionSchemaCells.tsx b/src/client/views/collections/collectionSchema/CollectionSchemaCells.tsx
index f7dfaaeb4..c8638dd12 100644
--- a/src/client/views/collections/collectionSchema/CollectionSchemaCells.tsx
+++ b/src/client/views/collections/collectionSchema/CollectionSchemaCells.tsx
@@ -26,7 +26,7 @@ import { SnappingManager } from "../../../util/SnappingManager";
import { undoBatch } from "../../../util/UndoManager";
import '../../../views/DocumentDecorations.scss';
import { EditableView } from "../../EditableView";
-import { MAX_ROW_HEIGHT } from '../../globalCssVariables.scss';
+import { MAX_ROW_HEIGHT } from '../../../../client/views/globalCssVariables.scss';
import { DocumentIconContainer } from "../../nodes/DocumentIcon";
import { OverlayView } from "../../OverlayView";
import "./CollectionSchemaView.scss";
@@ -38,27 +38,35 @@ export interface CellProps {
row: number;
col: number;
rowProps: CellInfo;
+ // currently unused
CollectionView: Opt;
+ // currently unused
ContainingCollection: Opt;
Document: Doc;
+ // column name
fieldKey: string;
+ // currently unused
renderDepth: number;
+ // called when a button is pressed on the node itself
addDocTab: (document: Doc, where: string) => boolean;
pinToPres: (document: Doc) => void;
moveDocument?: (document: Doc | Doc[], targetCollection: Doc | undefined,
addDocument: (document: Doc | Doc[]) => boolean) => boolean;
isFocused: boolean;
changeFocusedCellByIndex: (row: number, col: number) => void;
+ // set whether the cell is in the isEditing mode
setIsEditing: (isEditing: boolean) => void;
isEditable: boolean;
setPreviewDoc: (doc: Doc) => void;
setComputed: (script: string, doc: Doc, field: string, row: number, col: number) => boolean;
getField: (row: number, col?: number) => void;
+ // currnetly unused
showDoc: (doc: Doc | undefined, dataDoc?: any, screenX?: number, screenY?: number) => void;
}
@observer
export class CollectionSchemaCell extends React.Component {
+ // return a field key that is corrected for whether it COMMENT
public static resolvedFieldKey(column: string, rowDoc: Doc) {
const fieldKey = column;
if (fieldKey.startsWith("*")) {
@@ -72,7 +80,9 @@ export class CollectionSchemaCell extends React.Component {
@observable protected _isEditing: boolean = false;
protected _focusRef = React.createRef();
protected _rowDoc = this.props.rowProps.original;
+ // Gets the serialized data in proto form of the base proto that this document's proto inherits from
protected _rowDataDoc = Doc.GetProto(this.props.rowProps.original);
+ // methods for dragging and dropping
protected _dropDisposer?: DragManager.DragDropDisposer;
@observable contents: string = "";
@@ -81,6 +91,7 @@ export class CollectionSchemaCell extends React.Component {
@action
onKeyDown = (e: KeyboardEvent): void => {
+ // If a cell is editable and clicked, hitting enter shoudl allow the user to edit it
if (this.props.isFocused && this.props.isEditable && e.keyCode === KeyCodes.ENTER) {
document.removeEventListener("keydown", this.onKeyDown);
this._isEditing = true;
@@ -90,7 +101,11 @@ export class CollectionSchemaCell extends React.Component {
@action
isEditingCallback = (isEditing: boolean): void => {
+ // a general method that takes a boolean that determines whether the cell should be in
+ // is-editing mode
+ // remove the event listener if it's there
document.removeEventListener("keydown", this.onKeyDown);
+ // it's not already in is-editing mode, re-add the event listener
isEditing && document.addEventListener("keydown", this.onKeyDown);
this._isEditing = isEditing;
this.props.setIsEditing(isEditing);
@@ -99,12 +114,16 @@ export class CollectionSchemaCell extends React.Component {
@action
onPointerDown = async (e: React.PointerEvent): Promise => {
+ // pan to the cell
this.onItemDown(e);
+ // focus on it
this.props.changeFocusedCellByIndex(this.props.row, this.props.col);
this.props.setPreviewDoc(this.props.rowProps.original);
+ // console.log("click cell");
let url: string;
if (url = StrCast(this.props.rowProps.row.href)) {
+ // opens up the the doc in a new window, blurring the old one
try {
new URL(url);
const temp = window.open(url)!;
@@ -119,18 +138,25 @@ export class CollectionSchemaCell extends React.Component {
@undoBatch
applyToDoc = (doc: Doc, row: number, col: number, run: (args?: { [name: string]: any }) => any) => {
+ // apply a specified change to the cell
const res = run({ this: doc, $r: row, $c: col, $: (r: number = 0, c: number = 0) => this.props.getField(r + row, c + col) });
if (!res.success) return false;
+ // change what is rendered to this new changed cell content
doc[this.renderFieldKey] = res.result;
return true;
+ // return whether the change was successful
}
private drop = (e: Event, de: DragManager.DropEvent) => {
+ // if the drag has data at its completion
if (de.complete.docDragData) {
+ // if only one doc was dragged
if (de.complete.docDragData.draggedDocuments.length === 1) {
+ // update the renderFieldKey
this._rowDataDoc[this.renderFieldKey] = de.complete.docDragData.draggedDocuments[0];
}
else {
+ // create schema document reflecting the new column arrangement
const coll = Docs.Create.SchemaDocument([new SchemaHeaderField("title", "#f1efeb")], de.complete.docDragData.draggedDocuments, {});
this._rowDataDoc[this.renderFieldKey] = coll;
}
@@ -139,7 +165,9 @@ export class CollectionSchemaCell extends React.Component {
}
protected dropRef = (ele: HTMLElement | null) => {
+ // if the drop disposer is not undefined, run its function
this._dropDisposer?.();
+ // if ele is not null, give ele a non-undefined drop disposer
ele && (this._dropDisposer = DragManager.MakeDropTarget(ele, this.drop.bind(this)));
}
@@ -163,33 +191,46 @@ export class CollectionSchemaCell extends React.Component {
return {contents ? contents?.valueOf() : "undefined"};
}
- @computed get renderFieldKey() { return CollectionSchemaCell.resolvedFieldKey(this.props.rowProps.column.id!, this.props.rowProps.original); }
+ @computed get renderFieldKey() {
+ // gets the resolved field key of this cell
+ return CollectionSchemaCell.resolvedFieldKey(this.props.rowProps.column.id!, this.props.rowProps.original);
+ }
+
onItemDown = async (e: React.PointerEvent) => {
+ // if the document is a document used to change UI for search results in schema view
if (this.props.Document._searchDoc) {
const aliasdoc = await SearchUtil.GetAliasesOfDocument(this._rowDataDoc);
const targetContext = aliasdoc.length <= 0 ? undefined : Cast(aliasdoc[0].context, Doc, null);
+ // Jump to the this document
DocumentManager.Instance.jumpToDocument(this._rowDoc, false, emptyFunction, targetContext,
undefined, undefined, undefined, () => this.props.setPreviewDoc(this._rowDoc));
}
}
+
renderCellWithType(type: string | undefined) {
const dragRef: React.RefObject = React.createRef();
+ // the column
const fieldKey = this.renderFieldKey;
+ // the exact cell
const field = this._rowDoc[fieldKey];
const onPointerEnter = (e: React.PointerEvent): void => {
+ // e.buttons === 1 means the left moue pointer is down
if (e.buttons === 1 && SnappingManager.GetIsDragging() && (type === "document" || type === undefined)) {
dragRef.current!.className = "collectionSchemaView-cellContainer doc-drag-over";
}
};
const onPointerLeave = (e: React.PointerEvent): void => {
+ // change the class name to indicate that the cell is no longer being dragged
dragRef.current!.className = "collectionSchemaView-cellContainer";
};
let contents = Field.toString(field as Field);
+ // display 2 hyphens instead of a blank box for empty cells
contents = contents === "" ? "--" : contents;
+ // classname reflects the tatus of the cell
let className = "collectionSchemaView-cellWrapper";
if (this._isEditing) className += " editing";
if (this.props.isFocused && this.props.isEditable) className += " focused";
@@ -197,72 +238,27 @@ export class CollectionSchemaCell extends React.Component {
const positions = [];
if (StrCast(this.props.Document._searchString).toLowerCase() !== "") {
+ // term is ...promise pending... if the field is a Promise, otherwise it is the cell's contents
let term = (field instanceof Promise) ? "...promise pending..." : contents.toLowerCase();
const search = StrCast(this.props.Document._searchString).toLowerCase();
let start = term.indexOf(search);
let tally = 0;
+ // if search is found in term
if (start !== -1) {
positions.push(start);
}
+ // if search is found in term, continue finding all instances of search in term
while (start < contents?.length && start !== -1) {
term = term.slice(start + search.length + 1);
tally += start + search.length + 1;
start = term.indexOf(search);
positions.push(tally + start);
}
+ // remove the last position
if (positions.length > 1) {
positions.pop();
}
}
-
- // handles input procedures for string cells
- let stringInput = (value: string, retVal: boolean): void => {
- let valueSansQuotes = value;
- if (this._isEditing) {
- const vsqLength = valueSansQuotes.length;
- // get rid of outer quotes
- valueSansQuotes = valueSansQuotes.substring(value.startsWith("\"") ? 1 : 0,
- valueSansQuotes.charAt(vsqLength - 1) == "\"" ? vsqLength - 1 : vsqLength);
- }
- let inputAsString = '"';
- // escape any quotes in the string
- for (const i of valueSansQuotes) {
- if (i == '"') {
- inputAsString += '\\"';
- } else {
- inputAsString += i;
- }
- }
- // add a closing quote
- inputAsString += '"';
- //two options here: we can strip off outer quotes or we can figure out what's going on with the script
- const script = CompileScript(inputAsString, { requiredType: type, typecheck: false, editable: true, addReturn: true, params: { this: Doc.name, $r: "number", $c: "number", $: "any" } });
- const changeMade = inputAsString.length !== value.length || inputAsString.length - 2 !== value.length
- script.compiled && (retVal = this.applyToDoc(changeMade ? this._rowDoc : this._rowDataDoc, this.props.row, this.props.col, script.run));
- }
-
- // handles input procedure for number cells
- let numberInput = (value: string, retVal: boolean): void => {
- const inputscript = value.substring(value.startsWith("=") ? 1 : 0);
- // if commas are not stripped, the parser only considers the numbers after the last comma
- let inputSansCommas = "";
- for (let s of inputscript) {
- if (!(s == ",")) {
- inputSansCommas += s;
- }
- }
- const script = CompileScript(inputSansCommas, { requiredType: type, typecheck: false, editable: true, addReturn: true, params: { this: Doc.name, $r: "number", $c: "number", $: "any" } });
- const changeMade = value.length !== value.length || value.length - 2 !== value.length
- script.compiled && (retVal = this.applyToDoc(changeMade ? this._rowDoc : this._rowDataDoc, this.props.row, this.props.col, script.run));
- }
-
- // handles input procedure for boolean cells
- let boolInput = (value: string, retVal: boolean): void => {
- const script = CompileScript(value, { requiredType: type, typecheck: false, editable: true, addReturn: true, params: { this: Doc.name, $r: "number", $c: "number", $: "any" } });
- const changeMade = value.length !== value.length || value.length - 2 !== value.length
- script.compiled && (retVal = this.applyToDoc(changeMade ? this._rowDoc : this._rowDataDoc, this.props.row, this.props.col, script.run));
- }
-
const placeholder = type === "number" ? "0" : contents === "" ? "--" : "undefined";
return (
{
} else {
// check if the input is a number
let inputIsNum = true;
- for (let s of value) {
- if (isNaN(parseInt(s)) && !(s == ".") && !(s == ",")) {
+ for (const s of value) {
+ if (isNaN(parseInt(s)) && !(s === ".") && !(s === ",")) {
inputIsNum = false;
}
}
-
- let contentsAreNum = true;
- for (let s of contents) {
- if (isNaN(parseInt(s)) && !(s == ".") && !(s == ",")) {
- contentsAreNum = false;
- }
- }
// check if the input is a boolean
- let inputIsBool: boolean = value == "false" || value == "true";
- let contentsAreBool: boolean = contents == "false" || contents == "true";
-
- if (type == undefined) {
- // what to do in the case
- if (!inputIsNum && !inputIsBool && !value.startsWith("=")) {
- // if it's not a number, it's a string, and should be processed as such
- // strips the string of quotes when it is edited to prevent quotes form being added to the text automatically
- // after each edit
- stringInput(value, retVal);
- // handle numbers and expressions
- } else if (inputIsNum || value.startsWith("=")) {
- numberInput(value, retVal);
- // handle booleans
- } else if (inputIsBool) {
- boolInput(value, retVal);
+ const inputIsBool: boolean = value === "false" || value === "true";
+ // what to do in the case
+ if (!inputIsNum && !inputIsBool && !value.startsWith("=")) {
+ // if it's not a number, it's a string, and should be processed as such
+ // strips the string of quotes when it is edited to prevent quotes form being added to the text automatically
+ // after each edit
+ let valueSansQuotes = value;
+ if (this._isEditing) {
+ const vsqLength = valueSansQuotes.length;
+ // get rid of outer quotes
+ valueSansQuotes = valueSansQuotes.substring(value.startsWith("\"") ? 1 : 0,
+ valueSansQuotes.charAt(vsqLength - 1) === "\"" ? vsqLength - 1 : vsqLength);
}
- // if the cell type is a string
- } else if (type == "string") {
- stringInput(value, retVal);
- // if the cell type is a number
- } else if (type == "number") {
- if (inputIsNum) {
- numberInput(value, retVal);
- } else if (!contentsAreNum) {
- stringInput("", retVal);
+ let inputAsString = '"';
+ // escape any quotes in the string
+ for (const i of valueSansQuotes) {
+ if (i === '"') {
+ inputAsString += '\\"';
+ } else {
+ inputAsString += i;
+ }
}
- // if the cell type is a boolean
- } else if (type == "boolean") {
- if (inputIsBool) {
- boolInput(value, retVal);
- } else if (!contentsAreBool) {
- stringInput("", retVal);
+ // add a closing quote
+ inputAsString += '"';
+ //two options here: we can strip off outer quotes or we can figure out what's going on with the script
+ const script = CompileScript(inputAsString, { requiredType: type, typecheck: false, editable: true, addReturn: true, params: { this: Doc.name, $r: "number", $c: "number", $: "any" } });
+ const changeMade = inputAsString.length !== value.length || inputAsString.length - 2 !== value.length;
+ // change it if a change is made, otherwise, just compile using the old cell conetnts
+ script.compiled && (retVal = this.applyToDoc(changeMade ? this._rowDoc : this._rowDataDoc, this.props.row, this.props.col, script.run));
+ // handle numbers and expressions
+ } else if (inputIsNum || value.startsWith("=")) {
+ //TODO: make accept numbers
+ const inputscript = value.substring(value.startsWith("=") ? 1 : 0);
+ // if commas are not stripped, the parser only considers the numbers after the last comma
+ let inputSansCommas = "";
+ for (const s of inputscript) {
+ if (!(s === ",")) {
+ inputSansCommas += s;
+ }
}
+ const script = CompileScript(inputSansCommas, { requiredType: type, typecheck: false, editable: true, addReturn: true, params: { this: Doc.name, $r: "number", $c: "number", $: "any" } });
+ const changeMade = value.length !== value.length || value.length - 2 !== value.length;
+ script.compiled && (retVal = this.applyToDoc(changeMade ? this._rowDoc : this._rowDataDoc, this.props.row, this.props.col, script.run));
+ // handle booleans
+ } else if (inputIsBool) {
+ const script = CompileScript(value, { requiredType: type, typecheck: false, editable: true, addReturn: true, params: { this: Doc.name, $r: "number", $c: "number", $: "any" } });
+ const changeMade = value.length !== value.length || value.length - 2 !== value.length;
+ script.compiled && (retVal = this.applyToDoc(changeMade ? this._rowDoc : this._rowDataDoc, this.props.row, this.props.col, script.run));
}
}
if (retVal) {
@@ -351,6 +354,7 @@ export class CollectionSchemaCell extends React.Component {
return retVal;
})}
OnFillDown={async (value: string) => {
+ // computes all of the value preceded by :=
const script = CompileScript(value, { requiredType: type, typecheck: false, editable: true, addReturn: true, params: { this: Doc.name, $r: "number", $c: "number", $: "any" } });
script.compiled && DocListCast(this.props.Document[this.props.fieldKey]).
forEach((doc, i) => value.startsWith(":=") ?
@@ -381,7 +385,10 @@ export class CollectionSchemaStringCell extends CollectionSchemaCell { render()
@observer
export class CollectionSchemaDateCell extends CollectionSchemaCell {
- @computed get _date(): Opt { return this._rowDoc[this.renderFieldKey] instanceof DateField ? DateCast(this._rowDoc[this.renderFieldKey]) : undefined; }
+ @computed get _date(): Opt {
+ // if the cell is a date field, cast then contents to a date. Otherrwwise, make the contents undefined.
+ return this._rowDoc[this.renderFieldKey] instanceof DateField ? DateCast(this._rowDoc[this.renderFieldKey]) : undefined;
+ }
@action
handleChange = (date: any) => {
@@ -394,16 +401,13 @@ export class CollectionSchemaDateCell extends CollectionSchemaCell {
//}
}
- // If the cell is not clicked on, render the date normally. Otherwise, render a date picker.
render() {
- return !this.props.isFocused ? {this._date ? Field.toString(this._date as Field) : "--"} :
-
+ return !this.props.isFocused ? {this._date ? Field.toString(this._date as Field) : "--"} :
+ this.handleChange(date)}
+ onChange={date => this.handleChange(date)}
+ />;
}
}
@@ -423,8 +427,9 @@ export class CollectionSchemaDocCell extends CollectionSchemaCell {
typecheck: true,
transformer: DocumentIconContainer.getTransformer()
});
-
+ // compile the script
const results = script.compiled && script.run();
+ // if the script was compiled and run
if (results && results.success) {
this._rowDoc[this.renderFieldKey] = results.result;
return true;
@@ -442,6 +447,7 @@ export class CollectionSchemaDocCell extends CollectionSchemaCell {
@action
isEditingCallback = (isEditing: boolean): void => {
+ // the isEditingCallback from a general CollectionSchemaCell
document.removeEventListener("keydown", this.onKeyDown);
isEditing && document.addEventListener("keydown", this.onKeyDown);
this._isEditing = isEditing;
@@ -450,6 +456,7 @@ export class CollectionSchemaDocCell extends CollectionSchemaCell {
}
render() {
+ // if there's a doc, render it
return !this._doc ? this.renderCellWithType("document") :
Cast(doc[Doc.LayoutFieldKey(doc)], ImageField, null)?.url).filter(url => url).map(url => this.choosePath(url)); // access the primary layout data of the alternate documents
const paths = field ? [this.choosePath(field.url), ...altpaths] : altpaths;
+ // If there is a path, follow it; otherwise, follow a link to a default image icon
const url = paths.length ? paths : [Utils.CorsProxy("http://www.cs.brown.edu/~bcz/noImage.png")];
- const aspect = Doc.NativeAspect(this._rowDoc);
- let width = Math.min(75, this.props.rowProps.width);
- const height = Math.min(75, width / aspect);
- width = height * aspect;
+ const aspect = Doc.NativeAspect(this._rowDoc); // aspect ratio
+ let width = Math.min(75, this.props.rowProps.width); // get a with that is no smaller than 75px
+ const height = Math.min(75, width / aspect); // get a height either proportional to that or 75 px
+ width = height * aspect; // increase the width of the image if necessary to maintain proportionality
const reference = React.createRef();
return
@@ -523,13 +531,13 @@ export class CollectionSchemaListCell extends CollectionSchemaCell {
@computed get _field() { return this._rowDoc[this.renderFieldKey]; }
@computed get _optionsList() { return this._field as List; }
- @observable private _opened = false;
+ @observable private _opened = false; // whether the list is opened
@observable private _text = "select an item";
- @observable private _selectedNum = 0;
+ @observable private _selectedNum = 0; // the index of the list item selected
@action
onSetValue = (value: string) => {
- // change if its a document
+ // change if it's a document
this._optionsList[this._selectedNum] = this._text = value;
(this._field as List).splice(this._selectedNum, 1, value);
@@ -537,6 +545,7 @@ export class CollectionSchemaListCell extends CollectionSchemaCell {
@action
onSelected = (element: string, index: number) => {
+ // if an item is selected, the private variables should update to reflect this
this._text = element;
this._selectedNum = index;
}
@@ -550,6 +559,7 @@ export class CollectionSchemaListCell extends CollectionSchemaCell {
const link = false;
const reference = React.createRef();
+ // if the list is not opened, don't display it; otherwise, do.
if (this._optionsList?.length) {
const options = !this._opened ? (null) :
@@ -617,6 +627,7 @@ export class CollectionSchemaCheckboxCell extends CollectionSchemaCell {
@observer
export class CollectionSchemaButtons extends CollectionSchemaCell {
+ // the navigation buttons for schema view when it is used for search.
render() {
return !this.props.Document._searchDoc || ![DocumentType.PDF, DocumentType.RTF].includes(StrCast(this._rowDoc.type) as DocumentType) ? <>> :
@@ -628,4 +639,4 @@ export class CollectionSchemaButtons extends CollectionSchemaCell {
;
}
-}
\ No newline at end of file
+}
diff --git a/src/client/views/collections/collectionSchema/CollectionSchemaHeaders.tsx b/src/client/views/collections/collectionSchema/CollectionSchemaHeaders.tsx
index b2115b22e..2da9409f2 100644
--- a/src/client/views/collections/collectionSchema/CollectionSchemaHeaders.tsx
+++ b/src/client/views/collections/collectionSchema/CollectionSchemaHeaders.tsx
@@ -25,6 +25,7 @@ export interface AddColumnHeaderProps {
@observer
export class CollectionSchemaAddColumnHeader extends React.Component {
+ // the button that allows the user to add a column
render() {
return (
@@ -32,7 +33,6 @@ export class CollectionSchemaAddColumnHeader extends React.Component
Date: Wed, 6 Oct 2021 18:09:54 -0400
Subject: presBox type fix
---
src/client/views/nodes/trails/PresBox.tsx | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
(limited to 'src')
diff --git a/src/client/views/nodes/trails/PresBox.tsx b/src/client/views/nodes/trails/PresBox.tsx
index 8e61a224c..8a3df09e3 100644
--- a/src/client/views/nodes/trails/PresBox.tsx
+++ b/src/client/views/nodes/trails/PresBox.tsx
@@ -1143,10 +1143,10 @@ export class PresBox extends ViewBoxBaseComponent
@computed get transitionDropdown() {
const activeItem: Doc = this.activeItem;
const targetDoc: Doc = this.targetDoc;
- const type = targetDoc.type;
const isPresCollection: boolean = (targetDoc === this.layoutDoc.presCollection);
const isPinWithView: boolean = BoolCast(activeItem.presPinView);
if (activeItem && targetDoc) {
+ const type = targetDoc.type;
const transitionSpeed = activeItem.presTransition ? NumCast(activeItem.presTransition) / 1000 : 0.5;
let duration = activeItem.presDuration ? NumCast(activeItem.presDuration) / 1000 : 2;
if (activeItem.type === DocumentType.AUDIO) duration = NumCast(activeItem.duration);
--
cgit v1.2.3-70-g09d2
From a46d659229120cdb139f716b1a48ec6b887807bb Mon Sep 17 00:00:00 2001
From: bobzel
Date: Wed, 6 Oct 2021 19:40:40 -0400
Subject: fixed lightbox view to shrinkwrap collections when opened, but not
force fit contents to allow users to navigate. fixed comparison box to show
context of maker'/annotation documents. fixed ink pointer events to honor
pointerEvents prop (eg when embedded in a comparisonBox that turns them off).
---
src/client/views/InkingStroke.tsx | 2 +-
src/client/views/LightboxView.tsx | 4 ++--
.../collectionFreeForm/CollectionFreeFormView.tsx | 2 +-
.../collections/collectionSchema/CollectionSchemaCells.tsx | 1 -
src/client/views/nodes/ComparisonBox.tsx | 12 +++++++++---
5 files changed, 13 insertions(+), 8 deletions(-)
(limited to 'src')
diff --git a/src/client/views/InkingStroke.tsx b/src/client/views/InkingStroke.tsx
index d05a4a6e4..752db1413 100644
--- a/src/client/views/InkingStroke.tsx
+++ b/src/client/views/InkingStroke.tsx
@@ -209,7 +209,7 @@ export class InkingStroke extends ViewBoxBaseComponent {
LightboxView.SetLightboxDoc(undefined);
}
}} >
-
+
{
DataDoc={undefined}
LayoutTemplate={LightboxView.LightboxDocTemplate}
addDocument={undefined}
- fitContentsToDoc={this.fitToBox}
+ // fitContentsToDoc={this.fitToBox} // bcz: why do we want this? when we initially open a colletion, we shrinkwrap it which allows for user navigation. if we later encounter a collection, it's not clear to me that we want to make it either shrinkwrap or fitContents...
isDocumentActive={returnFalse}
isContentActive={returnTrue}
addDocTab={this.addDocTab}
diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
index b2db1168d..7dcd63b80 100644
--- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
+++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
@@ -1036,7 +1036,7 @@ export class CollectionFreeFormView extends CollectionSubView;
diff --git a/src/client/views/collections/collectionSchema/CollectionSchemaCells.tsx b/src/client/views/collections/collectionSchema/CollectionSchemaCells.tsx
index ed196349e..0274cc49c 100644
--- a/src/client/views/collections/collectionSchema/CollectionSchemaCells.tsx
+++ b/src/client/views/collections/collectionSchema/CollectionSchemaCells.tsx
@@ -103,7 +103,6 @@ export class CollectionSchemaCell extends React.Component {
this.props.changeFocusedCellByIndex(this.props.row, this.props.col);
this.props.setPreviewDoc(this.props.rowProps.original);
- console.log("click cell");
let url: string;
if (url = StrCast(this.props.rowProps.row.href)) {
try {
diff --git a/src/client/views/nodes/ComparisonBox.tsx b/src/client/views/nodes/ComparisonBox.tsx
index f23c68409..b1aada158 100644
--- a/src/client/views/nodes/ComparisonBox.tsx
+++ b/src/client/views/nodes/ComparisonBox.tsx
@@ -89,14 +89,20 @@ export class ComparisonBox extends ViewBoxAnnotatableComponent {
var whichDoc = Cast(this.dataDoc[which], Doc, null);
- if (whichDoc?.type === DocumentType.MARKER) whichDoc = Cast(whichDoc.annotationOn, Doc, null);
+ //if (whichDoc?.type === DocumentType.MARKER)
+ const targetDoc = Cast(whichDoc.annotationOn, Doc, null) ?? whichDoc;
return whichDoc ? <>
- {
+ whichDoc !== targetDoc && r?.focus(targetDoc);
+ }}
+ {...OmitKeys(this.props, ["NativeWidth", "NativeHeight"]).omit}
isContentActive={returnFalse}
isDocumentActive={returnFalse}
styleProvider={this.docStyleProvider}
- Document={whichDoc}
+ Document={targetDoc}
DataDoc={undefined}
+ hideLinkButton={true}
pointerEvents={"none"} />
{clearButton(which)}
> : // placeholder image if doc is missing
--
cgit v1.2.3-70-g09d2
From 8691e25e2f65e5041e147d37374c77947298a4b5 Mon Sep 17 00:00:00 2001
From: geireann
Date: Wed, 6 Oct 2021 20:02:24 -0400
Subject: added zoom
---
src/client/util/DocumentManager.ts | 5 +++--
src/client/views/nodes/trails/PresBox.tsx | 37 ++++++++++++++++++++++++++++++-
2 files changed, 39 insertions(+), 3 deletions(-)
(limited to 'src')
diff --git a/src/client/util/DocumentManager.ts b/src/client/util/DocumentManager.ts
index b66befb08..66b6a1e44 100644
--- a/src/client/util/DocumentManager.ts
+++ b/src/client/util/DocumentManager.ts
@@ -161,7 +161,8 @@ export class DocumentManager {
originatingDoc: Opt = undefined, // doc that initiated the display of the target odoc
finished?: () => void,
originalTarget?: Doc,
- noSelect?: boolean
+ noSelect?: boolean,
+ presZoom?: number
): Promise => {
originalTarget = originalTarget ?? targetDoc;
const getFirstDocView = LightboxView.LightboxDoc ? DocumentManager.Instance.getLightboxDocumentView : DocumentManager.Instance.getFirstDocumentView;
@@ -194,7 +195,7 @@ export class DocumentManager {
if (focusView) {
!noSelect && Doc.linkFollowHighlight(focusView.rootDoc); //TODO:glr make this a setting in PresBox
focusView.focus(targetDoc, {
- originalTarget, willZoom, afterFocus: (didFocus: boolean) =>
+ originalTarget, willZoom, scale: presZoom, afterFocus: (didFocus: boolean) =>
new Promise(res => {
focusAndFinish(didFocus);
res();
diff --git a/src/client/views/nodes/trails/PresBox.tsx b/src/client/views/nodes/trails/PresBox.tsx
index 8a3df09e3..2a153f256 100644
--- a/src/client/views/nodes/trails/PresBox.tsx
+++ b/src/client/views/nodes/trails/PresBox.tsx
@@ -404,7 +404,7 @@ export class PresBox extends ViewBoxBaseComponent
} else if ((curDoc.presMovement === PresMovement.Zoom || curDoc.presMovement === PresMovement.Jump) && targetDoc) {
LightboxView.SetLightboxDoc(undefined);
//awaiting jump so that new scale can be found, since jumping is async
- await DocumentManager.Instance.jumpToDocument(targetDoc, true, openInTab, srcContext, undefined, undefined, undefined, includesDoc || tab ? undefined : resetSelection, undefined, true); // documents open in new tab instead of on right
+ await DocumentManager.Instance.jumpToDocument(targetDoc, true, openInTab, srcContext, undefined, undefined, undefined, includesDoc || tab ? undefined : resetSelection, undefined, true, NumCast(curDoc.presZoom)); // documents open in new tab instead of on right
}
// After navigating to the document, if it is added as a presPinView then it will
// adjust the pan and scale to that of the pinView when it was added.
@@ -1026,6 +1026,15 @@ export class PresBox extends ViewBoxBaseComponent
Array.from(this._selectedArray.keys()).forEach((doc) => doc.presTransition = timeInMS);
}
+ // Converts seconds to ms and updates presTransition
+ setZoom = (number: String, change?: number) => {
+ let scale = Number(number) / 100;
+ if (change) scale += change;
+ if (scale < 0.01) scale = 0.01;
+ if (scale > 1.5) scale = 1.5;
+ Array.from(this._selectedArray.keys()).forEach((doc) => doc.presZoom = scale);
+ }
+
// Converts seconds to ms and updates presDuration
setDurationTime = (number: String, change?: number) => {
let timeInMS = Number(number) * 1000;
@@ -1148,6 +1157,7 @@ export class PresBox extends ViewBoxBaseComponent
if (activeItem && targetDoc) {
const type = targetDoc.type;
const transitionSpeed = activeItem.presTransition ? NumCast(activeItem.presTransition) / 1000 : 0.5;
+ const zoom = activeItem.presZoom ? NumCast(activeItem.presZoom) * 100 : 75;
let duration = activeItem.presDuration ? NumCast(activeItem.presDuration) / 1000 : 2;
if (activeItem.type === DocumentType.AUDIO) duration = NumCast(activeItem.duration);
const effect = targetDoc.presEffect ? targetDoc.presEffect : 'None';
@@ -1172,6 +1182,31 @@ export class PresBox extends ViewBoxBaseComponent