diff --git a/README.md b/README.md
index 8c2fa53..93b60a2 100644
--- a/README.md
+++ b/README.md
@@ -20,6 +20,8 @@ published Wednesday, September 7th, 2016.
## Methods
[`aboutJSLibs`](#aboutJSLibs) - Return the loaded versions of Dojo and React.
+[`addClasses`](#addClasses) - Add specified CSS classes to one or more DOM nodes.
+[`addToHead`](#addToHead) - Inject inline CSS or JS into the `
` section of the figure's HTML.
[`fontColor`](#fontColor) - Modify font color.
[`fontWeight`](#fontWeight) - Modify font weight.
[`getChildNodeIDs`](#getChildNodeIDs) - Get all children DOM nodes of a specified node.
@@ -59,14 +61,59 @@ ans =
react_js: '0.14.7'
```
+-----------------
+
+
+#### *mlapptools*.**addClasses**(*hUIElement*, *cssClasses*)
+
+##### Description
+
+Adds the specified CSS class (if `char` vector) or classes (if `cell` array of `char` vectors) to a UI element.
+
+##### Examples
+
+Using the demo GUI generated by `./Demo/DOMdemoGUI.m`
+
+```MATLAB
+% Create a figure:
+hFig = DOMdemoGUI;
+
+% Get a handle to the webwindow and the TextArea:
+[hWin, widgetID] = mlapptools.getWebElements(hFig.TextArea);
+
+% Define inline CSS animation and add it to the figure HTML:
+cssText = ['""'];
+mlapptools.addToHead(hWin, cssText);
+
+% Activate animation on control:
+mlapptools.setStyle(hWin, '-webkit-animation', 'mymove 5s infinite', widgetID);
+```
+
+Another example is available in the blog post "[Customizing web-GUI uipanel](https://undocumentedmatlab.com/blog/customizing-web-gui-uipanel)" by Khris Griffis.
+
+-----------------
+
+
+#### *mlapptools*.**addToHead**(*hWin*, *cssText*)
+
+##### Description
+
+A method for adding inline CSS to the HTML `` section.
+See also: [`stringify.m`](https://github.com/Khlick/matlabUiHacks/blob/master/utils/stringify.m).
+
+##### Examples
+See example for [`addClasses`](#addClasses).
+
-----------------
-#### *mlapptools*.**fontColor**(*uiElement*, *newcolor*)
+#### *mlapptools*.**fontColor**(*hUIElement*, *color*)
##### Description
-Set the font color of the specified UI element, `'uiElement'`, to the input color, `newcolor`. `newcolor` can be a
+Set the font color of the specified UI element, `'hUIElement'`, to the input color, `color`. `color` can be a
predefined color string or a string containing a valid CSS color method call.
Valid color specifications are:
@@ -96,11 +143,11 @@ mlapptools.fontColor(myGUI.TextArea, 'rgb(255,165,0)');
-----------------
-#### *mlapptools*.**fontWeight**(*uiElement*, *weight*)
+#### *mlapptools*.**fontWeight**(*hUIElement*, *weight*)
##### Description
-Set the font weight of the specified UI element, `uiElement`, to the input weight string or integer, `weight`.
+Set the font weight of the specified UI element, `hUIElement`, to the input weight string or integer, `weight`.
For this setting to have an effect, the font being used must have built-in faces that match the specified weight.
Valid font weight property values are:
@@ -129,7 +176,7 @@ mlapptools.fontWeight(myGUI.TextArea, 600);
-----------------
-#### *mlapptools*.**getChildNodeIDs**(*hWebWindow*,*widgetID*)
+#### *mlapptools*.**getChildNodeIDs**(*hWin*,*widgetID*)
##### Description
@@ -138,13 +185,13 @@ A method for getting all children nodes (commonly `
) of a specified node.
- % Returns a vector WidgetID.
- queryStr = sprintf(['var W = dojo.query("[%s = ''%s'']").map(',...
- 'function(node){return node.childNodes;})[0];'],ID_obj.ID_attr, ID_obj.ID_val);
- % The [0] above is required because an Array of Arrays is returned.
- [~] = win.executeJS(queryStr);
- % Try to establish an ID:
- childIDs = mlapptools.establishIdentities(win);
- % "Clear" the temporary JS variable
- win.executeJS('W = undefined');
- end % getChildNodeIDs
-
- function [fullHTML] = getHTML(hFigOrWin)
- % A method for dumping the HTML code of a uifigure.
- % Intended for R2017b (and onward?) where the CEF url cannot be simply opened in
- % an external browser.
- % Mostly irrelevant for UIFigures as of the introduction of mlapptools.unlockUIFig(...),
- % but can be useful for other non-uifigure webwindows.
- %% Obtain webwindow handle:
- if isa(hFigOrWin,'matlab.ui.Figure')
- win = mlapptools.getWebWindow(hFigOrWin);
- indepWW = false;
- else
- win = hFigOrWin; % rename the handle
- %% Attempt to determine if this is an "independent" webwindow:
- hF = mlapptools.figFromWebwindow(win);
- if isempty(hF)
- indepWW = true;
- else
- indepWW = false;
- end
- end
- %% Get HTML according to webwindow type:
- if indepWW
- [~,hWB] = web(win.URL, '-new');
- fullHTML = hWB.getHtmlText();
- close(hWB);
- %% TODO: Try to fix css paths:
- % See: https://stackoverflow.com/q/50944935/
- %{
- % Get all elements:
- win.executeJS('dojo.query("link")')
- % Convert relative paths to absolute:
-
- % Replace paths in HTML:
-
- %}
- else
- % Get the outer html:
- fullHTML = win.executeJS('document.documentElement.outerHTML');
- % Replace some strings for conversion to work well:
- fullHTML = strrep(fullHTML,'%','%%');
- fullHTML = strrep(fullHTML,'><','>\n<');
- % Append the DOCTYPE header and remove quotes:
- fullHTML = sprintf(['\n' fullHTML(2:end-1)]);
- %% Optional things to do with the output:
- % Display as web page:
- %{
- web(['text://' fullHTML]);
- %}
- % Save as file:
- %{
- fid = fopen('uifig_raw.html','w');
- fprintf(fid,'%s',fullHTML);
- fclose(fid);
- %}
- end
- end % getHTML
-
- function [parentID] = getParentNodeID(win,ID_obj)
- % A method for getting the parent node (commonly
) of a specified node.
- % Returns a scalar WidgetID.
- queryStr = sprintf(['var W = dojo.query("[%s = ''%s'']").map(',...
- 'function(node){return node.parentNode;});'],ID_obj.ID_attr, ID_obj.ID_val);
- [~] = win.executeJS(queryStr);
- % Try to establish an ID:
- parentID = mlapptools.establishIdentities(win);
- % "Clear" the temporary JS variable
- win.executeJS('W = undefined');
- end % getParentNodeID
-
- function [win, widgetID] = getWebElements(uiElement)
- % A method for obtaining the webwindow handle and the widget ID corresponding
- % to the provided uifigure control.
- % Get a handle to the webwindow
- win = mlapptools.getWebWindow(uiElement);
- mlapptools.waitTillWebwindowLoaded(win);
-
- % Find which element of the DOM we want to edit
- switch uiElement.Type
- case 'uitreenode'
- p = uiElement.Parent;
- if ~isa(p,'matlab.ui.container.Tree')
- p.expand(); % The row must be visible to apply changes
- end
- warnState = mlapptools.toggleWarnings('off');
- widgetID = WidgetID('data-test-id', char(struct(uiElement).NodeId));
- warning(warnState); % Restore warning state
- case {'uipanel', 'figure', 'uitabgroup', 'uitab', ...
- 'uiswitch', 'uitoggleswitch', 'uirockerswitch'}
- widgetID = WidgetID('data-tag', mlapptools.getDataTag(uiElement));
- otherwise % default:
- widgetID = mlapptools.getWidgetID(win, mlapptools.getDataTag(uiElement));
- end
- end % getWebElements
+ % MLAPPTOOLS is a collection of static methods for customizing the
+ % R2016a-introduced web-based uifigure windows and associated UI elements
+ % through DOM manipulations.
+ %
+ % MLAPPTOOLS' public methods:
+ %
+ % aboutJSLibs - Return version information about certain JS libraries.
+ % addClasses - Add specified CSS classes to one or more DOM nodes.
+ % addToHead - Inject inline CSS/JS into the section of the figure's HTML.
+ % fontColor - Modify font color.
+ % fontWeight - Modify font weight.
+ % getHTML - Return the full HTML code of a uifigure.
+ % getWebElements - Extract a webwindow handle and a widget ID from a uifigure control handle.
+ % getWebWindow - Extract a webwindow handle from a uifigure handle.
+ % getWidgetInfo - Gather information about a specific dijit widget.
+ % getWidgetList - Gather information about all dijit widget in a specified uifigure.
+ % setStyle - Modify a specified style property.
+ % setTimeout - Override the default timeout for dojo commands, for a specific uifigure.
+ % textAlign - Modify text alignment.
+ % unlockUIFig - Allow the uifigure to be opened using an external browser.
+ % waitForFigureReady - A blocking method that only returns after the uifigure is fully loaded.
+ %
+ % See README.md for detailed documentation and examples.
+
+ properties (Access = private, Constant = true)
+ QUERY_TIMEOUT = 5; % Dojo query timeout period, seconds
+ TAG_TIMEOUT = 'QUERY_TIMEOUT';
+ DEF_ID_ATTRIBUTE = 'id';
+ end
+
+ methods (Access = public, Static = true)
+
+ function [jsLibVersions] = aboutJSLibs()
+ % A method for getting version info about some JS libararies visible to MATLAB.
+ % This includes the Dojo Toolkit and ReactJS.
+
+ % Test if a *valid* webwindow already exists:
+ % (Written for compatibility with older releases)
+ exWW = matlab.internal.webwindowmanager.instance.findAllWebwindows();
+ validWinID = find(~cellfun(@isempty,strfind({exWW.URL}.','uifigure')),...
+ 1, 'first'); %#ok
+ if isempty(validWinID)
+ f = uifigure; drawnow; tmpWindowCreated = true;
+ winID = numel(exWW) + 1;
+ else
+ tmpWindowCreated = false;
+ winID = validWinID;
+ end
+
+ dojoVersion = matlab.internal.webwindowmanager.instance ...
+ .windowList(winID).executeJS('dojo.version');
+
+ reactVersion = matlab.internal.webwindowmanager.instance ...
+ .windowList(winID).executeJS(...
+ 'require("react/react.min").version;');
+
+ if tmpWindowCreated
+ delete(f);
+ end
+
+ % If MATLAB is sufficiently new, convert the JSON to a struct:
+ if str2double(subsref(ver('matlab'), substruct('.','Version'))) >= 9.1 %R2016b
+ dv = jsondecode(dojoVersion);
+ dojoVersion = char(strrep(join(string(struct2cell(dv)),'.'),'..','.'));
+ reactVersion = jsondecode(reactVersion);
+ else
+ dojoVersion = strsplit(dojoVersion,{':',',','"','}','{'});
+ dojoVersion = char(strjoin(dojoVersion([3,5,7,10]),'.'));
+ reactVersion = reactVersion(2:end-1);
+ end
+ jsLibVersions = struct('dojo', dojoVersion, 'react_js', reactVersion);
+ end % aboutJSLibs
+
+ function addClasses(hUIElement, cssClasses)
+ % A method for adding CSS classes to DOM nodes.
+
+ % Ensure we end up with a space-delimited list of classes:
+ if ~ischar(cssClasses) && numel(cssClasses) > 1
+ classList = strjoin(cssClasses, ' ');
+ else
+ classList = cssClasses;
+ end
+
+ if ~isscalar(hUIElement)
+ arrayfun(@(x)mlapptools.addClasses(x, cssClasses), hUIElement);
+ else
+ [hWin, widgetID] = mlapptools.getWebElements(hUIElement);
+ % Construct a dojo.js statement:
+ classSetStr = sprintf(...
+ 'dojo.addClass(dojo.query("[%s = ''%s'']")[0], "%s")',...
+ widgetID.ID_attr, widgetID.ID_val, classList);
- function [win] = getWebWindow(hUIObj)
- warnState = mlapptools.toggleWarnings('off');
- % Make sure we got a valid handle
- % Check to make sure we're addressing the parent figure window,
- % catches the case where the parent is a UIPanel or similar
- hUIFig = ancestor(hUIObj, 'figure');
-
- mlapptools.waitTillFigureLoaded(hUIFig);
- % Since the above checks if a Controller exists, the below should work.
-
- hController = struct(struct(hUIFig).Controller);
- % Check for Controller version:
- switch subsref(ver('matlab'), substruct('.','Version'))
- case {'9.0','9.1'} % R2016a or R2016b
- win = hController.Container.CEF;
- otherwise % R2017a onward
- win = struct(hController.PlatformHost).CEF;
- end
+ % Add the class(es) to the DOM node:
+ hWin.executeJS(classSetStr);
+ end
+
+ end % addClasses
+
+ function addToHead(hWin, nodeText)
+ % A method for adding nodes (" or "".'],[]);
+ elseif ~isempty(regexpi(nodeText,'http(s)?://'))
+ warning(['Remote files are not supported at this time.',...
+ ' Please provide a "stringified" input instead.'...
+ '\nInput can be "" or "".'],[]);
+ end
+
+ % Inject the nodeText:
+ hWin.executeJS(['document.head.innerHTML += ', nodeText]);
+ end % addToHead
+
+ function fontColor(hUIElement, color)
+ % A method for manipulating text color.
+ color = mlapptools.validateCSScolor(color);
+
+ [hWin, widgetID] = mlapptools.getWebElements(hUIElement);
+
+ mlapptools.setStyle(hWin, 'color', color, widgetID);
+ end % fontColor
+
+ function fontWeight(hUIElement, weight)
+ % A method for manipulating font weight, which controls how thick or
+ % thin characters in text should be displayed.
+ weight = mlapptools.validateFontWeight(weight);
+
+ [hWin, widgetID] = mlapptools.getWebElements(hUIElement);
+
+ mlapptools.setStyle(hWin, 'font-weight', weight, widgetID);
+ end % fontWeight
+
+ function [childIDs] = getChildNodeIDs(hWin, widgetID)
+ % A method for getting all children nodes (commonly
) of a specified node.
+ % Returns a vector WidgetID.
+ queryStr = sprintf([...
+ 'var W = dojo.query("[%s = ''%s'']").map(',...
+ 'function(node){return node.childNodes;})[0];'],...
+ widgetID.ID_attr, widgetID.ID_val);
+ % The [0] above is required because an Array of Arrays is returned.
+ [~] = hWin.executeJS(queryStr);
+ % Try to establish an ID:
+ childIDs = mlapptools.establishIdentities(hWin);
+ % "Clear" the temporary JS variable
+ hWin.executeJS('W = undefined');
+ end % getChildNodeIDs
+
+ function [fullHTML] = getHTML(hFigOrWin)
+ % A method for dumping the HTML code of a uifigure.
+ % Intended for R2017b (and onward?) where the CEF url cannot be simply opened in
+ % an external browser.
+ % Mostly irrelevant for UIFigures as of the introduction of mlapptools.unlockUIFig(...),
+ % but can be useful for other non-uifigure webwindows.
+ %% Obtain webwindow handle:
+ if isa(hFigOrWin,'matlab.ui.Figure')
+ hWin = mlapptools.getWebWindow(hFigOrWin);
+ indepWW = false;
+ else
+ hWin = hFigOrWin; % rename the handle
+ %% Attempt to determine if this is an "independent" webwindow:
+ hF = mlapptools.figFromWebwindow(hWin);
+ if isempty(hF)
+ indepWW = true;
+ else
+ indepWW = false;
+ end
+ end
+ %% Get HTML according to webwindow type:
+ if indepWW
+ [~,hWB] = web(hWin.URL, '-new');
+ fullHTML = hWB.getHtmlText();
+ close(hWB);
+ %% TODO: Try to fix css paths:
+ % See: https://stackoverflow.com/q/50944935/
+ %{
+ % Get all elements:
+ hWin.executeJS('dojo.query("link")')
+ % Convert relative paths to absolute:
- warning(warnState); % Restore warning state
-
- end % getWebWindow
-
- function [nfo] = getWidgetInfo(win, widgetID, verboseFlag)
- % A method for gathering information about a specific dijit widget, if its
- % HTML div id is known.
- if ~strcmp(widgetID.ID_attr,'widgetid')
- warning('getWidgetInfo:InappropriateIDAttribute',...
- 'This method requires widgets identified by a ''widgetid'' attribute.');
- nfo = struct([]);
- return
- end
- %% Handling required positional inputs:
- assert(nargin >= 2,'mlapptools:getWidgetInfo:insufficientInputs',...
- 'getWidgetInfo must be called with at least 2 inputs.');
- %% Handling optional inputs:
- if nargin < 3 || isempty(verboseFlag)
- verboseFlag = false;
- end
- %% Querying dijit
- win.executeJS(['var W; require(["dijit/registry"], '...
- 'function(registry){W = registry.byId("' widgetID.ID_val '");}); W = [W];']);
- % Decoding
- try
- nfo = mlapptools.decodeDijitRegistryResult(win,verboseFlag);
- catch ME
- switch ME.identifier
- case 'mlapptools:decodeDijitRegistryResult:noSuchWidget'
- warning(ME.identifier, '%s', ME.message);
- otherwise
- warning('mlapptools:getWidgetInfo:unknownDecodingError',...
- 'Decoding failed for an unexpected reason: %s', ME.message);
- end
- nfo = [];
- end
- % "Clear" the temporary JS variable
- win.executeJS('W = undefined');
- end % getWidgetInfo
-
- function varargout = getWidgetList(hUIFig, verboseFlag)
- % A method for listing all dijit widgets in a uifigure.
- warnState = mlapptools.toggleWarnings('off');
- %% Handle missing inputs:
- if nargin < 1 || isempty(hUIFig) || ~mlapptools.isUIFigure(hUIFig)
- throw(MException('mlapptools:getWidgetList:noHandleProvided',...
- 'Please provide a valid UIFigure handle as a first input.'));
+ % Replace paths in HTML:
+
+ %}
+ else
+ % Get the outer html:
+ fullHTML = hWin.executeJS('document.documentElement.outerHTML');
+ % Replace some strings for conversion to work well:
+ fullHTML = strrep(fullHTML,'%','%%');
+ fullHTML = strrep(fullHTML,'><','>\n<');
+ % Append the DOCTYPE header and remove quotes:
+ fullHTML = sprintf(['\n' fullHTML(2:end-1)]);
+ %% Optional things to do with the output:
+ % Display as web page:
+ %{
+ web(['text://' fullHTML]);
+ %}
+ % Save as file:
+ %{
+ fid = fopen('uifig_raw.html','w');
+ fprintf(fid,'%s',fullHTML);
+ fclose(fid);
+ %}
+ end
+ end % getHTML
+
+ function [parentID] = getParentNodeID(hWin, widgetID)
+ % A method for getting the parent node (commonly
) of a specified node.
+ % Returns a scalar WidgetID.
+ queryStr = sprintf(['var W = dojo.query("[%s = ''%s'']").map(',...
+ 'function(node){return node.parentNode;});'],widgetID.ID_attr, widgetID.ID_val);
+ [~] = hWin.executeJS(queryStr);
+ % Try to establish an ID:
+ parentID = mlapptools.establishIdentities(hWin);
+ % "Clear" the temporary JS variable
+ hWin.executeJS('W = undefined');
+ end % getParentNodeID
+
+ function [widgetIDs] = getTableCellID(hUITable, r, c)
+ % This method returns one or more ID objects, corresponding to specific cells in a
+ % uitable, as defined by the cells' row and column indices.
+ %% Constants:
+ TABLE_CLASS_NAME = 'matlab.ui.control.Table';
+ CELL_ID_PREFIX = {'variableeditor_views_editors_UITableEditor_'};
+ %% Input tests:
+ assert( isa(hUITable, TABLE_CLASS_NAME) && ishandle(hUITable),...
+ 'Invalid uitable handle!');
+ nR = numel(r); nC = numel(c);
+ assert( nR == nC, 'The number of elements in r and c must be the same!');
+ sz = size(hUITable.Data);
+ assert( all(r <= sz(1)), 'One or more requested rows are out-of-bounds!');
+ assert( all(c <= sz(2)), 'One or more requested columns are out-of-bounds!');
+ %% Computing the offset
+ % If there's more than one uitable in the figure, IDs are assigned
+ % consecutively. For example, in the case of a 3x3 and 4x4 arrays,
+ % where the smaller table was created first, IDs are assigned as follows:
+ %
+ % [ 0 1 2 [ 9 10 11 12
+ % 3 4 5 13 14 15 16
+ % 6 7 8] 17 18 19 20
+ % 21 22 23 24]
+ %
+ % ... which is why if we want to change the 2nd table we need to offset the
+ % IDs by the total amount of elements in all preceding arrays, which is 9.
+ %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+ % Get siblings (flipping to negate that newer children appear first)
+ hC = flip(hUITable.Parent.Children);
+ % Find which of them is a table:
+ hC = hC( arrayfun(@(x)isa(x, TABLE_CLASS_NAME), hC) );
+ % Find the position of the current table in the list, and count the elements of
+ % all preceding tables:
+ offset = sum(arrayfun(@(x)numel(x.Data), hC(1:find(hC == hUITable)-1)));
+ % Compute indices, r and c are reversed due to row-major ordering of the IDs
+ idx = sub2ind(sz, c, r) + offset - 1; % -1 because JS IDs are 0-based
+ idc = strcat(CELL_ID_PREFIX, num2str(idx(:)));
+ % Preallocation:
+ widgetIDs(nR,1) = WidgetID;
+ % Get the window handle so we could execute some JS commands:
+ hWin = mlapptools.getWebWindow(hUITable);
+ % ID array population:
+ for indI = 1:numel(idx)
+ jsCommand = sprintf('dojo.byId(%s).childNodes[0].id', idc{indI});
+ textFieldID = hWin.executeJS(jsCommand);
+ widgetIDs(indI) = WidgetID(mlapptools.DEF_ID_ATTRIBUTE, textFieldID(2:end-1) );
+ end
+ end % getTableCellID
+
+ function [hWin, widgetID] = getWebElements(hUIElement)
+ % A method for obtaining the webwindow handle and the widget ID corresponding
+ % to the provided ui control (aka web component).
+
+ % Get a handle to the webwindow
+ hWin = mlapptools.getWebWindow(hUIElement);
+ mlapptools.waitTillWebwindowLoaded( hWin, ...
+ ancestor(hUIElement, 'matlab.ui.Figure') );
+
+ % Find which element of the DOM we want to edit
+ switch hUIElement.Type
+ case 'uitreenode'
+ p = hUIElement.Parent;
+ if ~isa(p,'matlab.ui.container.Tree')
+ p.expand(); % The row must be visible to apply changes
end
+ warnState = mlapptools.toggleWarnings('off');
+ widgetID = WidgetID('data-test-id', char(struct(hUIElement).NodeId));
warning(warnState); % Restore warning state
- if nargin < 2 || isempty(verboseFlag)
- verboseFlag = false;
- end
- %% Process uifigure:
- win = mlapptools.getWebWindow(hUIFig);
- % Extract widgets from dijit registry:
- win.executeJS(['var W; require(["dijit/registry"], '...
- ' function(registry){W = registry.toArray();});']);
- widgets = mlapptools.decodeDijitRegistryResult(win, verboseFlag);
- % "Clear" the temporary JS variable
- win.executeJS('W = undefined');
- %% Assign outputs:
- varargout{1} = widgets;
- if nargout == 2
- % Convert to a single table:
- varargout{2} = struct2table(mlapptools.unifyStructs(widgets));
- end % getWidgetList
- end
-
- function varargout = setStyle(varargin)
- % A method providing an interface for modifying style attributes of uicontrols.
- %
- % WARNING: Due to the large amount of available style attributes and
- % corresponding settings, input checking is not performed. As this
- % might lead to unexpected results or errors - USE AT YOUR OWN RISK!
+ case {'uipanel', 'figure', 'uitabgroup', 'uitab', ...
+ 'uiswitch', 'uitoggleswitch', 'uirockerswitch'}
+ widgetID = WidgetID('data-tag', mlapptools.getDataTag(uiElement));
+ case 'uitable'
+ TAB_PREFIX = "mgg_";
+ % Notes:
+ % 1) uitables are inconsistent with other elements, their id always starts with
+ % "mgg_". So we list all widgets and select the "table-suspects" among them.
+ % 2) It's probably more useful to style the individual cells rather than the
+ % table itself. See: getTableCellID
+ % 3) The listing is not necessary, as it is possible to search for nodes
+ % having a property that starts with a certain string: E[foo^="bar"]
+ %{
+ web(['http://dojotoolkit.org/reference-guide/1.10/dojo/query.html',...
+ '#additional-selectors-supported-by-lite-engine'], '-browser');
+ %}
+ [~,tmp] = mlapptools.getWidgetList( ancestor(hUIElement,'figure') );
+ widgetID = arrayfun(@(x)WidgetID(mlapptools.DEF_ID_ATTRIBUTE, x), ...
+ string(tmp.id(contains(tmp.id, TAB_PREFIX))));
+ case 'axes'
+ switch subsref(ver('matlab'), substruct('.','Version'))
+ case {'9.6'} % R2019a
+ descendType = 'img';
+ otherwise % R2016a-R2018b
+ descendType = 'canvas';
+ % This canvas has a context of type "webgl".
+ % See also: https://developer.mozilla.org/en-US/docs/Web/API/WebGL_API
+ warning(['UIAxes object detected. Returning the innermost