Function Repository Resource:

FrontEndObjectQ

Source Notebook

Determine if an expression is a valid front end object

Contributed by: Richard Hennigan (Wolfram Research)

ResourceFunction["FrontEndObjectQ"][expr]

gives True if expr is a valid front end object and gives False otherwise.

ResourceFunction["FrontEndObjectQ"][expr,t]

requires expr to be a valid front end object of type t.

Details and Options

Some possible front end objects are:
NotebookObject[]a currently open notebook
CellObject[]a cell in an open notebook
BoxObject[]a particular box in a cell
$FrontEndan object representing global settings for the front end
In ResourceFunction["FrontEndObjectQ"][expr,t], the value for t can be:
NotebookObjectchecks if expr is a valid NotebookObject
CellObjectchecks if expr is a valid CellObject
BoxObjectchecks if expr is a valid BoxObject
pattchecks if expr matches the given pattern and is a valid front end object
"type"checks if expr is a valid front end object of the named type
{t1,,tn}checks if expr is a valid front end object and has type matching one of the ti
Some possible values for "type" are:
"Notebook" or "NotebookObject"NotebookObject
"Cell" or "CellObject"CellObject
"Box" or "BoxObject"BoxObject
ResourceFunction["FrontEndObjectQ"][expr] is effectively equivalent to ResourceFunction["FrontEndObjectQ"][expr,_].

Examples

Basic Examples (3) 

A NotebookObject that corresponds to a currently open notebook is a valid front end object:

In[1]:=
nb = CreateDocument[{x + y, 1/x + 1/y}]
Out[1]=
In[2]:=
ResourceFunction["FrontEndObjectQ"][nb]
Out[2]=

If the notebook is closed, it's no longer valid:

In[3]:=
NotebookClose[nb]
In[4]:=
ResourceFunction["FrontEndObjectQ"][nb]
Out[4]=

Test if a CellObject is valid:

In[5]:=
cell = ResourceFunction["PrintAsCellObject"][
  ResourceFunction["BirdSay"]["neat"]]
Out[5]=
In[6]:=
ResourceFunction["FrontEndObjectQ"][cell]
Out[6]=

If the cell is deleted, it's no longer valid:

In[7]:=
NotebookDelete[cell]
In[8]:=
ResourceFunction["FrontEndObjectQ"][cell]
Out[8]=

FrontEndObjectQ also works with BoxObject:

In[9]:=
{Dynamic[box1 = EvaluationBox[]], Dynamic[box2 = EvaluationBox[]]}
Out[9]=
In[10]:=
ResourceFunction["FrontEndObjectQ"] /@ {box1, box2}
Out[10]=

Delete one of the boxes:

In[11]:=
NotebookDelete[box2]

Now only one of the boxes is valid:

In[12]:=
ResourceFunction["FrontEndObjectQ"] /@ {box1, box2}
Out[12]=

Scope (3) 

Test for a valid cell object:

In[13]:=
ResourceFunction["FrontEndObjectQ"][EvaluationCell[], CellObject]
Out[13]=
In[14]:=
ResourceFunction["FrontEndObjectQ"][EvaluationNotebook[], CellObject]
Out[14]=

Accept only cells and boxes:

In[15]:=
Dynamic[{cell = EvaluationCell[], box = EvaluationBox[], notebook = EvaluationNotebook[]}]
Out[15]=
In[16]:=
Select[{cell, box, notebook}, ResourceFunction["FrontEndObjectQ"][#, {CellObject, BoxObject}] &]
Out[16]=

Use a named type:

In[17]:=
Select[{cell, box, notebook}, ResourceFunction["FrontEndObjectQ"][#, "Box"] &]
Out[17]=

Use a pattern:

In[18]:=
Select[{cell, box, notebook}, ResourceFunction[
   "FrontEndObjectQ"][#, _CellObject | _NotebookObject] &]
Out[18]=

When a front end is available, $FrontEnd corresponds to a valid front end object:

In[19]:=
ResourceFunction["FrontEndObjectQ"][$FrontEnd]
Out[19]=

When evaluated in a standalone kernel, $FrontEnd does not correspond to a valid front end object:

In[20]:=
ResourceFunction["LocalEvaluate"][
 ResourceFunction["FrontEndObjectQ"][$FrontEnd]]
Out[20]=

Properties and Relations (5) 

The full form of a valid cell object is CellObject[id], where id is an integer that corresponds to a serial number that is unique to that cell for the front end session:

In[21]:=
thisCell = EvaluationCell[]
Out[21]=
In[22]:=
FullForm[thisCell]
Out[22]=
In[23]:=
ResourceFunction["FrontEndObjectQ"][thisCell]
Out[23]=

Not all expressions of the form CellObject[id] are valid front end objects:

In[24]:=
invalidCell = CellObject[123456]
Out[24]=
In[25]:=
FullForm[invalidCell]
Out[25]=
In[26]:=
ResourceFunction["FrontEndObjectQ"][invalidCell]
Out[26]=

The full form of a valid box object is BoxObject[id], where id is an integer that corresponds to a serial number that is unique to that box structure for the front end session:

In[27]:=
Dynamic[thisBox = EvaluationBox[]]
Out[27]=
In[28]:=
FullForm[thisBox]
Out[28]=
In[29]:=
ResourceFunction["FrontEndObjectQ"][thisBox]
Out[29]=

Not all expressions of the form BoxObject[id] are valid front end objects:

In[30]:=
invalidBox = BoxObject[123456]
Out[30]=
In[31]:=
FullForm[invalidBox]
Out[31]=
In[32]:=
ResourceFunction["FrontEndObjectQ"][invalidBox]
Out[32]=

$FrontEndSession and $DefaultFrontEnd are symbols that represent particular front end states and are valid front end objects:

In[33]:=
ResourceFunction["FrontEndObjectQ"][$DefaultFrontEnd]
Out[33]=
In[34]:=
ResourceFunction["FrontEndObjectQ"][$FrontEndSession]
Out[34]=
In[35]:=
Head /@ {$DefaultFrontEnd, $FrontEndSession}
Out[35]=

These have options just like many other front end objects:

In[36]:=
SetOptions[$FrontEndSession, Background -> RandomColor[]]
In[37]:=
SetOptions[$FrontEndSession, Options[$DefaultFrontEnd, Background]]

Possible Issues (5) 

If a cell is overwritten with another cell, it will be represented by a new CellObject:

In[38]:=
cell = ResourceFunction["PrintAsCellObject"][
   Dynamic[current = EvaluationCell[]]];
In[39]:=
cell === current
Out[39]=

Overwrite the cell with an identical copy:

In[40]:=
SelectionMove[cell, All, Cell]
NotebookWrite[InputNotebook[], NotebookRead[cell]]

The new cell has replaced the old one:

In[41]:=
cell === current
Out[41]=
In[42]:=
ResourceFunction["FrontEndObjectQ"] /@ {cell, current}
Out[42]=

Check the serial numbers:

In[43]:=
First /@ {cell, current}
Out[43]=

To preserve cell objects, overwrite the contents of cells instead of the cells themselves:

In[44]:=
cell2 = ResourceFunction["PrintAsCellObject"][
   Dynamic[current2 = EvaluationCell[]]];
In[45]:=
SelectionMove[cell2, All, CellContents]
NotebookWrite[InputNotebook[], NotebookRead[cell2]]
In[46]:=
cell2 === current2
Out[46]=
In[47]:=
ResourceFunction["FrontEndObjectQ"] /@ {cell2, current2}
Out[47]=

Neat Examples (7) 

Get a random BoxObject:

In[48]:=
Rasterize[Dynamic[max = First[EvaluationBox[]]]]
Out[48]=
In[49]:=
While[! ResourceFunction["FrontEndObjectQ"][
    box = BoxObject[RandomInteger[max]]]];
box
Out[40]=

View the box contents:

In[50]:=
Framed[RawBoxes[NotebookRead[box]]]
Out[50]=

Find the enclosing cell:

In[51]:=
cell = NestWhile[ParentCell, box, ResourceFunction["FrontEndObjectQ"],
   1, Infinity, -1]
Out[51]=

View the cell contents:

In[52]:=
Framed[RawBoxes[NotebookRead[cell]]]
Out[52]=

Get the notebook that contains the cell:

In[53]:=
notebook = Notebooks[cell]
Out[53]=

Get the front end that owns the notebook:

In[54]:=
frontend = First[notebook]
Out[54]=

These are all valid front end objects:

In[55]:=
ResourceFunction["FrontEndObjectQ"] /@ {box, cell, notebook, frontend}
Out[55]=

Version History

  • 1.0.0 – 01 June 2020

Related Resources

License Information