In the Flux {Architecture.md}, almost every user action
+is translated into an Action object and fired globally. Stores in the app observe
+these actions and perform business logic. This loose coupling means that your
+packages can observe actions and perform additional logic, or fire actions which
+the rest of the app will handle.
+
In Reflux, each {Action} is an independent object that acts as an event emitter.
+You can listen to an Action, or invoke it as a function to fire it.
+
Action Scopes
+
N1 is a multi-window application. The scope of an Action dictates
+how it propogates between windows.
+
+
Global: These actions can be listened to from any window and fired from any
+window. The action is sent from the originating window to all other windows via
+IPC, so they should be used with care. Firing this action from anywhere will
+cause all listeners in all windows to fire.
+
Main Window: You can fire these actions in any window. They'll be sent
+to the main window and triggered there.
+
Window: These actions only trigger listeners in the window they're fired in.
If you're using Reflux to create your own Store, you can use the listenTo
+convenience method to listen for an Action. If you're creating your own class
+that is not a Store, you can still use the listen method provided by Reflux:
The Attribute class represents a single model attribute, like 'account_id'.
+Subclasses of {Attribute} like {AttributeDateTime} know how to covert between
+the JSON representation of that type and the javascript representation.
+The Attribute class also exposes convenience methods for generating {Matcher} objects.
+
+
+
+
+
+
+
+
+
+
Instance Methods
+
+ equal()
+
+
+
+
+
+
+
+
Returns
+
+
+
Return Values
+
+
Returns a {Matcher} for objects `=` to the provided value.
+
+
+ in()
+
+
+
+
+
+
+
+Returns
+
+
+
Return Values
+
+
Returns a {Matcher} for objects `=` to the provided value.
+
+
+ not()
+
+
+
+
+
+
+
+Returns
+
+
+
Return Values
+
+
Returns a {Matcher} for objects `!=` to the provided value.
+
+
+ descending()
+
+
+
+
+
+
+
+Returns
+
+
+
Return Values
+
+
Returns a descending {SortOrder} for this attribute.
+
+
+ ascending()
+
+
+
+
+
+
+
+Returns
+
+
+
Return Values
+
+
Returns an ascending {SortOrder} for this attribute.
Collection attributes provide basic support for one-to-many relationships.
+For example, Threads in N1 have a collection of Labels or Folders.
+
When Collection attributes are marked as queryable, the DatabaseStore
+automatically creates a join table and maintains it as you create, save,
+and delete models. When you call persistModel, entries are added to the
+join table associating the ID of the model with the IDs of models in the collection.
+
Collection attributes have an additional clause builder, contains:
Joined Data attributes allow you to store certain attributes of an
+object in a separate table in the database. We use this attribute
+type for Message bodies. Storing message bodies, which can be very
+large, in a separate table allows us to make queries on message
+metadata extremely fast, and inflate Message objects without their
+bodies to build the thread list.
+
When building a query on a model with a JoinedData attribute, you need
+to call include to explicitly load the joined data attribute.
+The query builder will automatically perform a LEFT OUTER JOIN with
+the secondary table to retrieve the attribute:
+
DatabaseStore.find(Message, '123').then (message) ->
+ // message.body isundefined
+
+DatabaseStore.find(Message, '123').include(Message.attributes.body).then (message) ->
+ // message.body is defined
+
+
When you call persistModel, JoinedData attributes are automatically
+written to the secondary table.
Runs the given command by spawning a new child process.
+
+
+
Parameters
+
+
+
Argument
+
Description
+
+
+
+ options
+
+
+
+ An {Object} with the following keys:
+
+
+
+
+
+ onWillThrowError(callback)
+
+
+
+
Will call your callback when an error will be raised by the process.
+Usually this is due to the command not being available or not on the PATH.
+You can call `handle()` on the object passed to your callback to indicate
+that you have handled this error.
Create a new task to apply labels to a message or thread.
+
Takes an options object of the form:
+
+
folder: The {Folder} or {Folder} IDs to move to
+
threads: An array of {Thread}s or {Thread} IDs
+
threads: An array of {Message}s or {Message} IDs
+
undoData: Since changing the folder is a destructive action,
+undo tasks need to store the configuration of what folders messages
+were in. When creating an undo task, we fill this parameter with
+that configuration
ChangeMailTask aims to be fast and efficient. It does not write changes to
+the database or make API requests for models that are unmodified by
+ChangeMailTask::changesToModel
+
ChangeMailTask stores the previous values of all models it changes into
+this._restoreValues and handles undo/redo. When undoing, it restores previous
+values and calls ChangeMailTask::requestBodyForModel to make undo API
+requests. It does not call ChangeMailTask::changesToModel.
+
+
+
+
+
+
+
+
+
+
Instance Methods
+
+ changesToModel(model)
+
+
+
+
Override this method and return an object with key-value pairs
+representing changed values. For example, if (your task sets unread:)
+false, return {unread: false}.
+
+
+
Parameters
+
+
+
Argument
+
Description
+
+
+
+ model
+
+
+
+ an individual {Thread} or {Message}
+
+
+
+
+
Returns
+
+
+
Return Values
+
+
Returns an object whos key-value pairs represent the desired changed
+object.
+
+
+ requestBodyForModel(model)
+
+
+
+
Override this method and return an object that will be the
+request body used for saving changes to `model`.
+
+
+Parameters
+
+
+
Argument
+
Description
+
+
+
+ model
+
+
+
+ an individual {Thread} or {Message}
+
+
+
+
+
Returns
+
+
+
Return Values
+
+
Returns an object that will be passed as the `body` to the actual API
+`request` object
+
+
+ processNestedMessages()
+
+
+
+
Override to indicate whether actions need to be taken for all
+messages of each thread.
+
+Generally, you cannot provide both messages and threads at the same
+time. However, ChangeMailTask runs for provided threads first and then
+messages. Override and return true, and you will receive
+`changesToModel` for messages in changed threads, and any changes you
+make will be written to the database and undone during undo.
+
+Note that API requests are only made for threads if (threads are)
+present.
+
+
+
+
+ categoriesToAdd()
+
+
+
+
+
+
+
+Returns
+
+
+
Return Values
+
+
Returns categories that this task will add to the set of threads
+Must be overriden
+
+
+ categoriesToRemove()
+
+
+
+
+
+
+
+Returns
+
+
+
Return Values
+
+
Returns categories that this task will remove the set of threads
+Must be overriden
The ComponentRegistry maintains an index of React components registered
+by Nylas packages. Components can use {InjectedComponent} and {InjectedComponentSet}
+to dynamically render components registered with the ComponentRegistry.
+
+
+
+
+
+
+
+
+
+
Instance Methods
+
+ register(componentoptions)
+
+
+
+
Register a new component with the Component Registry.
+Typically, packages call this method from their main `activate` method
+to extend the Nylas user interface, and call the corresponding `unregister`
+method in `deactivate`.
+
+This method is chainable.
+
+
+
Parameters
+
+
+
Argument
+
Description
+
+
+
+ component
+
+
+
+ {Object} A React Component with a `displayName`
+
+
+
+
+ options
+
+
+
+ {Object}: Note that for advanced use cases, you can also pass (`modes`, `roles`, `locations`) with arrays instead of single values.
+
+
+
+
+
+ findComponentByName(name)
+
+
+
+
Retrieve the registry entry for a given name.
+
+
+
Parameters
+
+
+
Argument
+
Description
+
+
+
+ name
+
+
+
+ The {String} name of the registered component to retrieve.
+
+
+
+
+
Returns
+
+
+
Return Values
+
+
Returns a {React.Component}
+
+
+ findComponentsMatching(descriptor)
+
+
+
+
Retrieve all of the registry entries matching a given descriptor.
+
+```coffee
+ ComponentRegistry.findComponentsMatching({
+ role: 'Composer:ActionButton'
+ })
+
+ ComponentRegistry.findComponentsMatching({
+ location: WorkspaceStore.Location.RootSidebar.Toolbar
+ })
+```
+
+
+Parameters
+
+
+
Argument
+
Description
+
+
+
+ descriptor
+
+
+
+ An {Object} that specifies set of components using the available keys below. Note that for advanced use cases, you can also pass (`modes`, `roles`, `locations`) with arrays instead of single values.
+
To create ComposerExtensions that enhance the composer experience,
+you should create objects that implement the interface defined at
+{ComposerExtension}.
+
{ComposerExtension} extends {ContenteditableExtension}, so you can also
+implement the methods defined there to further enhance the composer
+experience.
+
To register your extension with the ExtensionRegistry, call
+{ExtensionRegistry::Composer::register}. When your package is being
+unloaded, you must call the corresponding
+{ExtensionRegistry::Composer::unregister} to unhook your extension.
Your ComposerExtension should be stateless. The user may have multiple
+drafts open at any time, and the methods of your ComposerExtension may be
+called for different drafts at any time. You should not expect that the
+session you receive in applyTransformsToDraft is for the same
+draft you previously received in warningsForSending, etc.
+
The ComposerExtension API does not currently expose any asynchronous or
+{Promise}-based APIs, except for applyTransformsToDraft and unapplyTransformsToDraft,
+which can optionally return a promsie. This will likely change in the future.
+If you have a use-case for a ComposerExtension that is not possible with the current
+API, please let us know.
Allows the addition of new types of send actions such as "Send
+Later"
+
+Return an array of objects that adhere to the following spec. If the draft data
+indicates that your action should not be available, then return null.
+
+
+
Parameters
+
+
+
Argument
+
Description
+
+
+
+ title
+
+
+
+ A short, single string that is displayed to users when describing your component. It is used in the hover title text of your option in the dropdown menu. It is also used in the "Default Send Behavior" dropdown setting. If your string is selected, then the `core.sending.defaultSendType` will be set to your string and your option will appear as the default.
+
+
+
+
+ performSendAction
+
+
+
+ Callback for when your option is clicked as the primary action. The function will be passed `{draft}` as its only argument. It does not need to return anything. It may be asynchronous and likely queue Tasks.
+
+
+
+
+ isEnabled
+
+
+
+ Callback to determine if this send action should be rendered for the given draft. Takes a draft: A fully populated {Message} object that is about to be sent.
+
+
+
+
+ iconUrl
+
+
+
+ A custom icon to be placed in the Send button. SendAction extensions have the form "Send + {ICON}"
+
+
+
+
+
+ warningsForSending(draft)
+
+
+
+
Inspect the draft, and return any warnings that need to be
+displayed before the draft is sent. Warnings should be string phrases,
+such as "without an attachment" that fit into a message of the form:
+"Send #{phase1} and #{phase2}?"
+
+
+
Parameters
+
+
+
Argument
+
Description
+
+
+
+ draft
+
+
+
+ A fully populated {Message} object that is about to be sent.
+
+
+
+
+
Returns
+
+
+
Return Values
+
+
Returns a list of warning strings, or an empty array if no warnings need
+to be displayed.
+
+
+ prepareNewDraft()
+
+
+
+
Override prepareNewDraft to modify a brand new draft before it
+is displayed in a composer. This is one of the only places in the
+application where it's safe to modify the draft object you're given
+directly to add participants to the draft, add a signature, etc.
+
+By default, new drafts are considered `pristine`. If the user leaves the
+composer without making any changes, the draft is discarded. If your
+extension populates the draft in a way that makes it "populated" in a
+valuable way, you should set `draft.pristine = false` so the draft
+saves, even if no further changes are made.
+
+
+
+
+ applyTransformsForSending(draft)
+
+
+
+
applyTransformsToDraft is called when a draft the user is editing
+is saved to the server and/or sent. This method gives you an opportunity to
+remove any annotations you've inserted into the draft body, apply final changes
+to the body, etc.
+
+Note that your extension /must/ be able to reverse the changes it applies to
+the draft in `applyTransformsToDraft`. If the user re-opens the draft,
+`unapplyTransformsToDraft` will be called and must restore the draft to it's
+previous edit-ready state.
+
+Examples:
+
+This method should return a modified {Message} object, or a {Promise} which resolves
+to a modified Message object.
+
+
+Parameters
+
+
+
Argument
+
Description
+
+
+
+ draft
+
+
+
+ A {Message} the user is about to finish editing.
+
+
+
+
+
+ unapplyTransformsForSending()
+
+
+
+
unapplyTransformsToDraft should revert the changes made in
+`applyTransformsToDraft`. See the documentation for that method for more
+information.
An instance of this class is always available as the NylasEnv.config global.
+
Getting and setting config settings.
+
# Note that with no value set, ::get returns the setting's default value.
+NylasEnv.config.get('my-package.myKey') # -> 'defaultValue'
+
+NylasEnv.config.set('my-package.myKey', 'value')
+NylasEnv.config.get('my-package.myKey') # -> 'value'
+
+
You may want to watch for changes. Use observe to catch changes to the setting.
+
NylasEnv.config.set('my-package.myKey', 'value')
+NylasEnv.config.observe 'my-package.myKey', (newValue) ->
+ # `observe` calls immediately and every time the value is changed
+ console.log 'My configuration changed:', newValue
+
+
If you want a notification only when the value changes, use onDidChange.
Config settings each have a type specified by way of a
+schema. For example we might an integer setting that only
+allows integers greater than 0:
+
# When no value has been set, `::get` returns the setting's default value
+NylasEnv.config.get('my-package.anInt') # -> 12
+
+# The string will be coerced to the integer 123
+NylasEnv.config.set('my-package.anInt', '123')
+NylasEnv.config.get('my-package.anInt') # -> 123
+
+# The string will be coerced to an integer, but it must be greater than 0, so is set to 1
+NylasEnv.config.set('my-package.anInt', '-20')
+NylasEnv.config.get('my-package.anInt') # -> 1
+
+
Defining settings for your package
+
Define a schema under a config key in your package main.
We use json schema which allows you to define your value's
+default, the type it should be, etc. A simple example:
+
# We want to provide an `enableThing`, and a `thingVolume`
+config:
+ enableThing:
+ type: 'boolean'
+ default: false
+ thingVolume:
+ type: 'integer'
+ default: 5
+ minimum: 1
+ maximum: 11
+
+
The type keyword allows for type coercion and validation. If a thingVolume is
+set to a string '10', it will be coerced into an integer.
+
NylasEnv.config.set('my-package.thingVolume', '10')
+NylasEnv.config.get('my-package.thingVolume') # -> 10
+
+# It respects the min / max
+NylasEnv.config.set('my-package.thingVolume', '400')
+NylasEnv.config.get('my-package.thingVolume') # -> 11
+
+# If it cannot be coerced, the value will not be set
+NylasEnv.config.set('my-package.thingVolume', 'cats')
+NylasEnv.config.get('my-package.thingVolume') # -> 11
+
+
Supported Types
+
The type keyword can be a string with any one of the following. You can also
+chain them by specifying multiple in an an array. For example
Values will be coerced into a Boolean. 'true' and 'false' will be coerced into
+a boolean. Numbers, arrays, objects, and anything else will not be coerced.
Values will be coerced into a {Color} with red, green, blue, and alpha
+properties that all have numeric values. red, green, blue will be in
+the range 0 to 255 and value will be in the range 0 to 1. Values can be any
+valid CSS color format such as #abc, #abcdef, white,
+rgb(50, 100, 150), and rgba(25, 75, 125, .75).
All types support an enum key. The enum key lets you specify all values
+that the config setting can possibly be. enummust be an array of values
+of your specified type. Schema:
NylasEnv.config.set('my-package.someSetting', '2')
+NylasEnv.config.get('my-package.someSetting') # -> 2
+
+# will not set values outside of the enum values
+NylasEnv.config.set('my-package.someSetting', '3')
+NylasEnv.config.get('my-package.someSetting') # -> 2
+
+# If it cannot be coerced, the value will not be set
+NylasEnv.config.set('my-package.someSetting', '4')
+NylasEnv.config.get('my-package.someSetting') # -> 4
+
+
title and description
+
The settings view will use the title and description keys to display your
+config setting in a readable way. By default the settings view humanizes your
+config key, so someSetting becomes Some Setting. In some cases, this is
+confusing for users, and a more descriptive title is useful.
+
Descriptions will be displayed below the title in the settings view.
+
config:
+ someSetting:
+ title: 'Setting Magnitude'
+ description: 'This will affect the blah and the other blah'
+ type: 'integer'
+ default: 4
+
+
Note: You should strive to be so clear in your naming of the setting that
+you do not need to specify a title or description!
+
Best practices
+
+
Don't depend on (or write to) configuration keys outside of your keypath.
Add a listener for changes to a given key path. This is different
+than onDidChange in that it will immediately call your callback with the
+current value of the config entry.
+
+### Examples
+
+You might want to be notified when the themes change. We'll watch
+`core.themes` for changes
+
+```coffee
+NylasEnv.config.observe 'core.themes', (value) ->
+ # do stuff with value
+```
+
+
+
Parameters
+
+
+
Argument
+
Description
+
+
+
+ keyPath
+
+
+
+ {String} name of the key to observe
+
+
+
+
+ callback
+
+
+
+ {Function} to call when the value of the key changes.
+
+
+
+
+
Returns
+
+
+
Return Values
+
+
Returns a {Disposable} with the following keys on which you can call
+`.dispose()` to unsubscribe.
+
+
+ onDidChange([keyPath]callback)
+
+
+
+
Add a listener for changes to a given key path. If `keyPath` is
+not specified, your callback will be called on changes to any key.
+
+
+Parameters
+
+
+
Argument
+
Description
+
+
+
+ keyPath
+
+
+ Optional
+ {String} name of the key to observe.
+
+
+
+
+ callback
+
+
+
+ {Function} to call when the value of the key changes.
+
+
+
+
+
Returns
+
+
+
Return Values
+
+
Returns a {Disposable} with the following keys on which you can call
+`.dispose()` to unsubscribe.
+
+
+ get(keyPath)
+
+
+
+
Retrieves the setting for the given key.
+
+### Examples
+
+You might want to know what themes are enabled, so check `core.themes`
+
+```coffee
+NylasEnv.config.get('core.themes')
+```
+
+
+Parameters
+
+
+
Argument
+
Description
+
+
+
+ keyPath
+
+
+
+ The {String} name of the key to retrieve.
+
+
+
+
+
Returns
+
+
+
Return Values
+
+
Returns the value from N1's default settings, the user's configuration
+file in the type specified by the configuration schema.
+
+
+ set(keyPathvalue)
+
+
+
+
Sets the value for a configuration setting.
+
+This value is stored in N1's internal configuration file.
+
+### Examples
+
+You might want to change the themes programmatically:
+
+```coffee
+NylasEnv.config.set('core.themes', ['ui-light', 'my-custom-theme'])
+```
+
+
+Parameters
+
+
+
Argument
+
Description
+
+
+
+ keyPath
+
+
+
+ The {String} name of the key.
+
+
+
+
+ value
+
+
+
+ The value of the setting. Passing `undefined` will revert the setting to the default value.
+
+
+
+
+
Returns
+
+
+
Return Values
+
+
Returns a {Boolean}
+
+* `true` if the value was set.
+* `false` if the value was not able to be coerced to the type specified in the setting's schema.
+
+
+ unset(keyPath[options])
+
+
+
+
Restore the setting at `keyPath` to its default value.
+
+
+Parameters
+
+
+
Argument
+
Description
+
+
+
+ keyPath
+
+
+
+ The {String} name of the key.
+
+
+
+
+ options
+
+
+ Optional
+ {Object}
+
+
+
+
+
+ getSchema(keyPath)
+
+
+
+
Retrieve the schema for a specific key path. The schema will tell
+you what type the keyPath expects, and other metadata about the config
+option.
+
+
+
Parameters
+
+
+
Argument
+
Description
+
+
+
+ keyPath
+
+
+
+ The {String} name of the key.
+
+
+
+
+
Returns
+
+
+
Return Values
+
+
Returns an {Object} eg. `{type: 'integer', default: 23, minimum: 1}`.
+
Returns `null` when the keyPath has no schema specified.
+
+
+ transact(callback)
+
+
+
+
Suppress calls to handler functions registered with onDidChange
+and observe for the duration of `callback`. After `callback` executes,
+handlers will be called once if the value for their key-path has changed.
+
+
+Parameters
+
+
+
Argument
+
Description
+
+
+
+ callback
+
+
+
+ {Function} to execute while suppressing calls to handlers.
+
The Contact model represents a Contact object served by the Nylas Platform API.
+For more information about Contacts on the Nylas Platform, read the
+Contacts API Documentation
+
Attributes
+
name: {AttributeString} The name of the contact. Queryable.
+
email: {AttributeString} The email address of the contact. Queryable.
+
thirdPartyData: {AttributeObject} Extra data that we find out about a
+contact. The data is keyed by the 3rd party service that dumped the data
+there. The value is an object of raw data in the form that the service
+provides
+
We also have "normalized" optional data for each contact. This list may
+grow as the needs of a contact become more complex.
+
This class also inherits attributes from {Model}
+
+
+
+
+
+
+
+
+
+
Instance Methods
+
+ toString()
+
+
+
+
+
+
+
+
Returns
+
+
+
Return Values
+
+
Returns a string of the format `Full Name ` if
+the contact has a populated name, just the email address otherwise.
+
+
+ isValid()
+
+
+
+
+
+
+
+Returns
+
+
+
Return Values
+
+
Returns true if the contact provided is a {Contact} instance and
+contains a properly formatted email address.
+
+
+ isMe()
+
+
+
+
+
+
+
+Returns
+
+
+
Return Values
+
+
Returns true if the contact is the current user, false otherwise.
+You should use this method instead of comparing the user's email address to
+the account email, since it is case-insensitive and future-proof.
ContactStore provides convenience methods for searching contacts and
+formatting contacts. When Contacts become editable, this store will be expanded
+with additional actions.
+
+
+
+
+
+
+
+
+
+
Instance Methods
+
+ searchContacts(search[options])
+
+
+
+
Search the user's contact list for the given search term.
+This method compares the `search` string against each Contact's
+`name` and `email`.
+
+
+
Parameters
+
+
+
Argument
+
Description
+
+
+
+ search
+
+
+
+ {String} A search phrase, such as `ben@n` or `Ben G`
+
+
+
+
+ options
+
+
+ Optional
+ {Object} If you will only be displaying a few results, you should pass a limit value. searchContacts will return as soon as `limit` matches have been found.
+
perform an editing operation on the Contenteditable
+
+If the current selection at the time of running the extension is out of
+scope, it will be set to the last saved state. This ensures extensions
+operate on a valid {ExtendedSelection}.
+
+Edits made within the editing function will eventually fire _onDOMMutated
+
+
+
Parameters
+
+
+
Argument
+
Description
+
+
+
+ editingFunction
+
+
+
+ A function to mutate the DOM and {ExtendedSelection}. It gets passed an {EditorAPI} object that contains mutating methods.
+
ContenteditableExtension is an abstract base class.
+Implementations of this are used to make additional changes to a
+
component beyond a user's input intents. The hooks in
+this class provide the contenteditable DOM Node itself, allowing you to
+adjust selection ranges and change content as necessary.
+
While some ContenteditableExtension are included with the core
+<{Contenteditable} /> component, others may be added via the plugins
+prop when you use it inside your own components.
If you specifically want to enhance the Composer experience you should
+register a {ComposerExtension}
+
+
+
+
+
+
+
+
Class Methods
+
+ onContentChanged()
+
+
+
+
Gets called anytime any atomic change is made to the DOM of the
+contenteditable.
+
+When a user types a key, deletes some text, or does anything that
+changes the DOM. it will trigger `onContentChanged`. It is wrapper over
+a native DOM {MutationObserver}. It only gets called if there are
+mutations
+
+This also gets called at the end of callbacks that mutate the DOM. If
+another extension overrides `onClick` and performs several mutations to
+the DOM during that callback, those changes will be batched and then
+`onContentChanged` will be called once at the end of the callback with
+those mutations.
+
+Callback params:
+
+* editor: The {Editor} controller that provides a host of convenience
+ methods for manipulating the selection and DOM
+* mutations: An array of DOM Mutations as returned by the
+ {MutationObserver}. Note that these may not always be populated
+
+You may mutate the contenteditable in place, we do not expect any return
+value from this method.
+
+The onContentChanged event can be triggered by a variety of events, some
+of which could have been already been looked at by a callback. Any DOM
+mutation will fire this event. Sometimes those mutations are the cause
+of other callbacks.
+
+Example:
+
+The Nylas `templates` package uses this method to see if the user has
+populated a `` tag placed in the body and change it's CSS class to
+reflect that it is no longer empty.
+
+```coffee
+onContentChanged: ({editor, mutations}) ->
+ isWithinNode = (node) ->
+ test = selection.baseNode
+ while test isnt editableNode
+ return true if test is node
+ test = test.parentNode
+ return false
+
+ codeTags = editableNode.querySelectorAll('code.var.empty')
+ for codeTag in codeTags
+ if selection.containsNode(codeTag) or isWithinNode(codeTag)
+ codeTag.classList.remove('empty')
+```
+
+
+
+
+ onBlur()
+
+
+
+
Override onBlur to mutate the contenteditable DOM node whenever the
+onBlur event is fired on it. You may mutate the contenteditable in place, we
+not expect any return value from this method.
+
+* editor: The {Editor} controller that provides a host of convenience
+ methods for manipulating the selection and DOM
+* event: DOM event fired on the contenteditable
+
+
+
+
+ onFocus()
+
+
+
+
Override onFocus to mutate the contenteditable DOM node whenever the
+onFocus event is fired on it. You may mutate the contenteditable in place, we
+not expect any return value from this method.
+
+* editor: The {Editor} controller that provides a host of convenience
+ methods for manipulating the selection and DOM
+* event: DOM event fired on the contenteditable
+
+
+
+
+ onClick()
+
+
+
+
Override onClick to mutate the contenteditable DOM node whenever the
+onClick event is fired on it. You may mutate the contenteditable in place, we
+not expect any return value from this method.
+
+* editor: The {Editor} controller that provides a host of convenience
+ methods for manipulating the selection and DOM
+* event: DOM event fired on the contenteditable
+
+
+
+
+ onKeyDown()
+
+
+
+
Override onKeyDown to mutate the contenteditable DOM node whenever the
+onKeyDown event is fired on it.
+Public: Called when the user presses a key while focused on the contenteditable's body field.
+Override onKeyDown in your ContenteditableExtension to adjust the selection or
+perform other actions.
+
+If your package implements key down behavior for a particular scenario, you
+should prevent the default behavior of the key via `event.preventDefault()`.
+You may mutate the contenteditable in place, we not expect any return value
+from this method.
+
+Important: You should prevent the default key down behavior with great care.
+
+* editor: The {Editor} controller that provides a host of convenience
+ methods for manipulating the selection and DOM
+* event: DOM event fired on the contenteditable
+
+
+
+
+ onShowContextMenu()
+
+
+
+
Override onShowContextMenu to add new menu items to the right click menu
+inside the contenteditable.
+
+* editor: The {Editor} controller that provides a host of convenience
+ methods for manipulating the selection and DOM
+* event: DOM event fired on the contenteditable
+* menu: [Menu](https://github.com/atom/electron/blob/master/docs/api/menu.md)
+ object you can mutate in order to add new [MenuItems](https://github.com/atom/electron/blob/master/docs/api/menu-item.md)
+ to the context menu that will be displayed when you right click the contenteditable.
+
+
+
+
+ keyCommandHandlers()
+
+
+
+
Override `keyCommandHandlers` to declaratively map keyboard
+commands to callbacks.
+
+Return an object keyed by the command name whose values are the
+callbacks.
+
+Callbacks are automatically bound to the Contenteditable context and
+passed `({editor, event})` as its argument.
+
+New commands are defined in keymap.cson files.
+
+
+
+
+ toolbarButtons()
+
+
+
+
Override `toolbarButtons` to declaratively add your own button
+to the composer's toolbar.
+
+* toolbarState: The current state of the Toolbar and Composer. This is
+ Read only.
+
+Must return an array of objects obeying the following spec:
+
+* className: A string class name
+* onClick: Callback to fire when your button is clicked. The callback
+ is automatically bound to the editor and will get passed an single
+ object with the following args.
+ * editor - The {Editor} controller for manipulating the DOM
+ * event - The click Event object
+* tooltip: A string to display when users hover over your button
+* iconUrl: A url for the icon.
+
+
+
+
+ toolbarComponentConfig()
+
+
+
+
Override `toolbarComponentConfig` to declaratively show your own
+toolbar when certain conditions are met.
+
+If you want to hide your toolbar component, return null.
+
+If you want to display your toolbar, then return an object with the
+signature indicated below.
+
+This methods gets called anytime the `toolbarState` changes. Since
+`toolbarState` includes the current value of the Selection and any
+objects a user is hovering over, you should expect it to change very
+frequently.
+
+* toolbarState: The current state of the Toolbar and Composer. This is
+ Read only.
+ * dragging
+ * doubleDown
+ * hoveringOver
+ * editableNode
+ * exportedSelection
+ * extensions
+ * atomicEdit
+
+Must return an object with the following signature
+
+* component: A React component or null.
+* props: Props to be passed into your custom Component
+* locationRefNode: Anything (usually a DOM Node) that responds to
+ `getBoundingClientRect`. This is used to determine where to display
+ your component.
+* width: The width of your component. This is necessary because when
+ your component is displayed in the {FloatingToolbar}, the position is
+ pre-computed based on the absolute width of the item.
+* height: The height of your component. This is necessary for the same
+ reason listed above; the position of the toolbar will be determined
+ by the absolute height given.
N1 is built on top of a custom database layer modeled after
+ActiveRecord. For many parts of the application, the database is the source
+of truth. Data is retrieved from the API, written to the database, and changes
+to the database trigger Stores and components to refresh their contents.
+
The DatabaseStore is available in every application window and allows you to
+make queries against the local cache. Every change to the local cache is
+broadcast as a change event, and listening to the DatabaseStore keeps the
+rest of the application in sync.
+
// Listening for Changes
+
To listen for changes to the local cache, subscribe to the DatabaseStore and
+inspect the changes that are sent to your listener method.
+
this.unsubscribe = DatabaseStore.listen(this._onDataChanged, this.)
+
+...
+
+_onDataChanged: (change) ->
+ returnunless change.objectClass is Message
+ returnunlessthis._myMessageID in _.map change.objects, (m) -> m.id
+
+ // Refresh Data
+
+
The local cache changes very frequently, and your stores and components should
+carefully choose when to refresh their data. The `change` object passed to your
+event handler allows you to decide whether to refresh your data and exposes
+the following keys:
+
`objectClass`: The {Model} class that has been changed. If multiple types of models
+were saved to the database, you will receive multiple change events.
+
`objects`: An {Array} of {Model} instances that were either created, updated or
+deleted from the local cache. If your component or store presents a single object
+or a small collection of objects, you should look to see if any of the objects
+are in your displayed set before refreshing.
+
+
+
+
+
+
+
+
+
+
Instance Methods
+
+ find()
+
+
+
+
Creates a new Model Query for retrieving a single model specified by
+the class and id.
+
+* \`class\` The class of the {Model} you're trying to retrieve.
+* \`id\` The {String} id of the {Model} you're trying to retrieve
+
+Example:
+
+```coffee
+DatabaseStore.find(Thread, 'id-123').then (thread) ->
+// thread is a Thread object, or null if no match was found.
+```
+
+
+
+
Returns
+
+
+
Return Values
+
+
Returns a {Query}
+
+
+ findBy()
+
+
+
+
Creates a new Model Query for retrieving a single model matching the
+predicates provided.
+
+* \`class\` The class of the {Model} you're trying to retrieve.
+* \`predicates\` An {Array} of {matcher} objects. The set of predicates the
+ returned model must match.
+
+
+
+Returns
+
+
+
Return Values
+
+
Returns a {Query}
+
+
+ findAll()
+
+
+
+
Creates a new Model Query for retrieving all models matching the
+predicates provided.
+
+* \`class\` The class of the {Model} you're trying to retrieve.
+* \`predicates\` An {Array} of {matcher} objects. The set of predicates the
+ returned model must match.
+
+
+
+Returns
+
+
+
Return Values
+
+
Returns a {Query}
+
+
+ count()
+
+
+
+
Creates a new Model Query that returns the {Number} of models matching
+the predicates provided.
+
+* \`class\` The class of the {Model} you're trying to retrieve.
+* \`predicates\` An {Array} of {matcher} objects. The set of predicates the
+ returned model must match.
+
+
+
+Returns
+
+
+
Return Values
+
+
Returns a {Query}
+
+
+ modelify()
+
+
+
+
Modelify converts the provided array of IDs or models (or a mix of
+IDs and models) into an array of models of the \`klass\` provided by querying for the missing items.
+
+Modelify is efficient and uses a single database query. It resolves Immediately
+if no query is necessary.
+
+* \`class\` The {Model} class desired.
+* 'arr' An {Array} with a mix of string model IDs and/or models.
+
+
+
+
+ run()
+
+
+
+
Executes a {Query} on the local database.
+
+* \`modelQuery\` A {Query} to execute.
+
+
+
+Returns
+
+
+
Return Values
+
+
Returns a {Promise} that
+
+* resolves with the result of the database query.
+
+
+ inTransaction()
+
+
+
+
Opens a new database transaction for writing changes.
+DatabaseStore.inTransacion makes the following guarantees:
+
+* No other calls to \`inTransaction\` will run until the promise has finished.
+* No other process will be able to write to sqlite while the provided function
+ is running. `BEGIN IMMEDIATE TRANSACTION` semantics are:
+* No other connection will be able to write any changes.
+* Other connections can read from the database, but they will not see
+ pending changes.
+
+
+
+Returns
+
+
+
Return Values
+
+
this.param fn {function} callback that will be executed inside a database transaction
+
Returns a {Promise} that resolves when the transaction has successfully
+completed.
As the user interacts with the draft, changes are accumulated in the
+DraftChangeSet associated with the store session. The DraftChangeSet does two things:
+
+
It debounces changes and calls Actions.saveDraft() at a reasonable interval.
+
It exposes applyToModel, which allows you to optimistically apply changes
+to a draft object. When the session vends the draft, it passes it through this
+function to apply uncommitted changes. This means the Draft provided by the
+DraftEditingSession will always relfect recent changes, even though they're
+written to the database intermittently.
DraftEditingSession is a small class that makes it easy to implement components
+that display Draft objects or allow for interactive editing of Drafts.
+
+
It synchronously provides an instance of a draft via draft(), and
+triggers whenever that draft instance has changed.
+
It provides an interface for modifying the draft that transparently
+batches changes, and ensures that the draft provided via draft()
+always has pending changes applied.
+
+
+
+
+
+
+
+
+
+
+
Instance Methods
+
+ draft()
+
+
+
+
+
+
+
+
Returns
+
+
+
Return Values
+
+
Returns the draft object with the latest changes applied.
+
+
+ draftPristineBody()
+
+
+
+
+
+
+
+Returns
+
+
+
Return Values
+
+
Returns the initial body of the draft when it was pristine, or null if the
+draft was never pristine in this editing session. Useful for determining if the
+body is still in an unchanged / empty state.
EventedIFrame is a thin wrapper around the DOM's standard <iframe> element.
+You should always use EventedIFrame, because it provides important event hooks that
+ensure keyboard and mouse events are properly delivered to the application when
+fired within iFrames.
The FocusedContentStore provides access to the objects currently selected
+or otherwise focused in the window. Normally, focus would be maintained internally
+by components that show models. The FocusedContentStore makes the concept of
+selection public so that you can observe focus changes and trigger your own changes
+to focus.
+
Since {FocusedContentStore} is a Flux-compatible Store, you do not call setters
+on it directly. Instead, use Actions::setFocus or
+Actions::setCursorPosition to set focus. The FocusedContentStore observes
+these models, changes it's state, and broadcasts to it's observers.
+
Note: The {FocusedContentStore} triggers when a focused model is changed, even if
+it's ID has not. For example, if the user has a {Thread} selected and removes a tag,
+{FocusedContentStore} will trigger so you can fetch the new version of the
+{Thread}. If you observe the {FocusedContentStore} properly, you should always
+have the latest version of the the selected object.
+
Standard Collections:
+
+
thread
+
file
+
+
Example: Observing the Selected Thread
+
@unsubscribe = FocusedContentStore.listen(@_onFocusChanged, @)
+
+...
+
+# Called when focus has changed, or when the focused model has been modified.
+_onFocusChanged: ->
+ thread = FocusedContentStore.focused('thread')
+ if thread
+ console.log("#{thread.subject} is selected!")
+ else
+ console.log("No thread is selected!")
+
+
+
+
+
+
+
+
+
+
+
Instance Methods
+
+ focused(collection)
+
+
+
+
+
+
+
Parameters
+
+
+
Argument
+
Description
+
+
+
+ collection
+
+
+
+ The {String} name of a collection. Standard collections are listed above.
+
+
+
+
+
Returns
+
+
+
Return Values
+
+
Returns the focused {Model} in the collection specified,
+or undefined if no item is focused.
+
+
+ focusedId(collection)
+
+
+
+
+
+
+Parameters
+
+
+
Argument
+
Description
+
+
+
+ collection
+
+
+
+ The {String} name of a collection. Standard collections are listed above.
+
+
+
+
+
Returns
+
+
+
Return Values
+
+
Returns the ID of the focused {Model} in the collection specified,
+or undefined if no item is focused.
+
+
+ didFocusUsingClick(collection)
+
+
+
+
+
+
+Parameters
+
+
+
Argument
+
Description
+
+
+
+ collection
+
+
+
+ The {String} name of a collection. Standard collections are listed above.
+
+
+
+
+
Returns
+
+
+
Return Values
+
+
Returns true if the item for the collection was focused via a click or
+false otherwise.
+
+
+ keyboardCursor(collection)
+
+
+
+
+
+
+Parameters
+
+
+
Argument
+
Description
+
+
+
+ collection
+
+
+
+ The {String} name of a collection. Standard collections are listed above.
+
+
+
+
+
Returns
+
+
+
Return Values
+
+
Returns the {Model} the keyboard is currently focused on
+in the collection specified. Keyboard focus is not always separate from
+primary focus (selection). You can use keyboardCursorEnabled to determine
+whether keyboard focus is enabled.
+
+
+ keyboardCursorId(collection)
+
+
+
+
+
+
+Parameters
+
+
+
Argument
+
Description
+
+
+
+ collection
+
+
+
+ The {String} name of a collection. Standard collections are listed above.
+
+
+
+
+
Returns
+
+
+
Return Values
+
+
Returns the ID of the {Model} the keyboard is currently focused on
+in the collection specified. Keyboard focus is not always separate from
+primary focus (selection). You can use keyboardCursorEnabled to determine
+whether keyboard focus is enabled.
+
+
+ keyboardCursorEnabled()
+
+
+
+
+
+
+
+Returns
+
+
+
Return Values
+
+
Returns a {Boolean} - `true` if the keyboard cursor concept applies in
+the current {WorkspaceStore} layout mode. The keyboard cursor is currently only
+enabled in `list` mode.
InjectedComponent makes it easy to include dynamically registered
+components inside of your React render method. Rather than explicitly render
+a component, such as a <Composer>, you can use InjectedComponent:
InjectedComponent will look up the component registered with that role in the
+{ComponentRegistry} and render it, passing the exposedProps (draftClientId={123}) along.
+
InjectedComponent monitors the ComponentRegistry for changes. If a new component
+is registered that matches the descriptor you provide, InjectedComponent will refresh.
+
If no matching component is found, the InjectedComponent renders an empty div.
+
+
+
+
+
+
Class Properties
+
propTypes
+
React `props` supported by InjectedComponent:
+
+
+
+ matching
+
+
+
+ Pass an {Object} with ComponentRegistry descriptors. This set of descriptors is provided to ComponentRegistry::findComponentsForDescriptor to retrieve the component that will be displayed.
+
+
+
+
+ onComponentDidRender
+
+
+ Optional
+ Callback that will be called when the injected component is successfully rendered onto the DOM.
+
+
+
+
+ className
+
+
+ Optional
+ A {String} class name for the containing element.
+
+
+
+
+ exposedProps
+
+
+ Optional
+ An {Object} with props that will be passed to each item rendered into the set.
+
+
+
+
+ fallback
+
+
+ Optional
+ A {Component} to default to in case there are no matching components in the ComponentRegistry
+
+
+
+
+ requiredMethods
+
+
+
+ (options) An {Array} with a list of methods that should be implemented by the registered component instance. If these are not implemented, an error will be thrown.
+
InjectedComponent makes it easy to include a set of dynamically registered
+components inside of your React render method. Rather than explicitly render
+an array of buttons, for example, you can use InjectedComponentSet:
InjectedComponentSet will look up components registered for the location you provide,
+render them inside a {Flexbox} and pass them exposedProps. By default, all injected
+children are rendered inside {UnsafeComponent} wrappers to prevent third-party code
+from throwing exceptions that break React renders.
+
InjectedComponentSet monitors the ComponentRegistry for changes. If a new component
+is registered into the location you provide, InjectedComponentSet will re-render.
+
If no matching components is found, the InjectedComponent renders an empty span.
A mapping between a command and a callback handler
+
+
// Mapping keys to commands (not handled by this component)
+
The keyboard -> command mapping is defined in a separate .cson file.
+A majority of the commands your component would want to listen to you have
+already been defined by core N1 defaults, as well as custom user
+overrides. See 'keymaps/base.cson' for more information.
+
You can define additional, custom keyboard -> command mappings in your own
+package-specific keymap .cson file. The file can be named anything but
+must exist in a folder called keymaps in the root of your package's
+directory.
+
// Mapping commands to callbacks (handled by this component)
+
When a keystroke sequence matches a binding in a given context, a custom
+DOM event with a type based on the command is dispatched on the target of
+the keyboard event.
+
That custom DOM event (whose type is the command you want to listen to)
+will propagate up from its original target. That original target may or
+may not be a descendent of your component.
+
Frequently components will want to listen to a keyboard command regardless
+of where it was fired from. For those, use the globalHandlers prop. The
+DOM event will NOT be passed to globalHandlers callbacks.
+
Components may also want to listen to keyboard commands that originate
+within one of their descendents. For those use the localHandlers prop.
+The DOM event WILL be passed to localHandlers callback because it is
+sometimes valuable to call stopPropagataion on the custom command event.
The Matcher class encapsulates a particular comparison clause on an {Attribute}.
+Matchers can evaluate whether or not an object matches them, and also compose
+SQL clauses for the DatabaseStore. Each matcher has a reference to a model
+attribute, a comparator and a value.
+
+// Retrieving Matchers
+
+isUnread = Thread.attributes.unread.equal(true)
+
+hasLabel = Thread.attributes.categories.contains('label-id-123')
+
+// Using Matchers in Database Queries
+
+DatabaseStore.findAll(Thread).where(isUnread)...
+
+// Using Matchers to test Models
+
+threadA = new Thread(unread: true)
+threadB = new Thread(unread: false)
+
+isUnread.evaluate(threadA)
+// => true
+isUnread.evaluate(threadB)
+// => false
+
React component for multi-section Menus with key binding
+
The Menu component allows you to display a list of items. Menu takes care of
+several important things, ensuring that your menu is consistent with the rest
+of the N1 application and offers a near-native experience:
+
+
Keyboard Interaction with the Up and Down arrow keys, Enter to select
+
Maintaining selection across content changes
+
Highlighted state
+
+
Menus are often, but not always, used in conjunction with {Popover} to display
+a floating "popup" menu. See template-picker.cjsx for an example.
+
The Menu also exposes "header" and "footer" regions you can fill with arbitrary
+components by providing the headerComponents and footerComponents props.
+These items are nested within .header-container. and .footer-container,
+and you can customize their appearance by providing CSS selectors scoped to your
+component's Menu instance:
+ Optional
+ The {String} class name applied to the Menu
+
+
+
+
+ itemContent
+
+
+
+ A {Function} that returns a {MenuItem}, {String}, or React component for the given `item`. If you return a {MenuItem}, your item is injected into the list directly. If you return a string or React component, the result is placed within a {MenuItem}, resulting in the following DOM: `
{your content}
`. To create dividers and other special menu items, return an instance of:
+
+
+
+
+ itemKey
+
+
+
+ A {Function} that returns a unique string key for the given `item`. Keys are important for efficient React rendering when `items` is changed, and a key function is required.
+
+
+
+
+ itemChecked
+
+
+
+ A {Function} that returns true if the given item should be shown with a checkmark. If you don't provide an implementation for `itemChecked`, no checkmarks are ever shown.
+
+
+
+
+ items
+
+
+
+ An {Array} of arbitrary objects the menu should display.
+
+
+
+
+ onSelect
+
+
+
+ A {Function} called with the selected item when the user clicks an item in the menu or confirms their selection with the Enter key.
+
+
+
+
+ onEscape
+
+
+
+ A {Function} called when a user presses escape in the input.
+
+
+
+
+ defaultSelectedIndex
+
+
+
+ The index of the item first selected if there was no other previous index. Defaults to 0. Set to -1 if you want nothing selected.
+
MenuItem components can be provided to the {Menu} by the itemContent function.
+MenuItem's props allow you to display dividers as well as standard items.
+
+
+
+
+
+
Class Properties
+
propTypes
+
React `props` supported by MenuItem:
+
+
+
+ divider
+
+
+ Optional
+ Pass a {Boolean} to render the menu item as a section divider.
+
+
+
+
+ key
+
+
+ Optional
+ Pass a {String} to be the React key to optimize rendering lists of items.
+
+
+
+
+ selected
+
+
+ Optional
+ Pass a {Boolean} to specify whether the item is selected.
+
+
+
+
+ checked
+
+
+ Optional
+ Pass a {Boolean} to specify whether the item is checked.
+
The Message model represents a Message object served by the Nylas Platform API.
+For more information about Messages on the Nylas Platform, read the
+Messages API Documentation
+
Messages are a sub-object of threads. The content of a message === immutable (with the
+exception being drafts). Nylas does not support operations such as move || delete on
+individual messages; those operations should be performed on the message’s thread.
+All messages are part of a thread, even if that thread has only one message.
+
Attributes
+
to: {AttributeCollection} A collection of {Contact} objects
+
cc: {AttributeCollection} A collection of {Contact} objects
+
bcc: {AttributeCollection} A collection of {Contact} objects
+
from: {AttributeCollection} A collection of {Contact} objects.
+
replyTo: {AttributeCollection} A collection of {Contact} objects.
+
date: {AttributeDateTime} When the message was delivered. Queryable.
+
subject: {AttributeString} The subject of the thread. Queryable.
+
snippet: {AttributeString} A short, 140-character plain-text summary of the message body.
+
unread: {AttributeBoolean} True if the message === unread. Queryable.
+
starred: {AttributeBoolean} True if the message === starred. Queryable.
+
draft: {AttributeBoolean} True if the message === a draft. Queryable.
+
version: {AttributeNumber} The version number of the message. Message
+ versions are used for drafts, && increment when attributes are changed.
+
files: {AttributeCollection} A set of {File} models representing
+ the attachments on this thread.
+
body: {AttributeJoinedData} The HTML body of the message. You must specifically
+ request this attribute when querying for a Message using the {AttributeJoinedData::include}
+ method.
+
pristine: {AttributeBoolean} True if the message === a draft which has not been
+ edited since it was created.
+
threadId: {AttributeString} The ID of the Message's parent {Thread}. Queryable.
+
replyToMessageId: {AttributeString} The ID of a {Message} that this message
+ === in reply to.
+
This class also inherits attributes from {Model}
+
+
+
+
+
+
+
+
+
+
Instance Methods
+
+ participants()
+
+
+
+
+
+
+
+
Returns
+
+
+
Return Values
+
+
Returns a set of uniqued message participants by combining the
+`to`, `cc`, `bcc` && (optionally) `from` fields.
+
+
+ participantsForReplyAll()
+
+
+
+
+
+
+
+Returns
+
+
+
Return Values
+
+
Returns a hash with `to` && `cc` keys for authoring a new draft in
+"reply all" to this message. This method takes into account whether the
+message === from the current user, && also looks at the replyTo field.
+
+
+ participantsForReply()
+
+
+
+
+
+
+
+Returns
+
+
+
Return Values
+
+
Returns a hash with `to` && `cc` keys for authoring a new draft in
+"reply" to this message. This method takes into account whether the
+message === from the current user, && also looks at the replyTo field.
+
+
+ fileIds()
+
+
+
+
+
+
+
+Returns
+
+
+
Return Values
+
+
Returns an {Array} of {File} IDs
+
+
+ isFromMe()
+
+
+
+
+
+
+
+Returns
+
+
+
Return Values
+
+
Returns true if this message === from the current user's email
+address. In the future, this method will take into account all of the
+user's email addresses && accounts.
+
+
+ computePlainText()
+
+
+
+
+
+
+
+Returns
+
+
+
Return Values
+
+
Returns a plaintext version of the message body using Chromium's
+DOMParser. Use with care.
+
+
+ replyAttributionLine()
+
+
+
+
+
+
+
+Returns
+
+
+
Return Values
+
+
Returns the standard attribution line for this message,
+localized for the current user.
+ie "On Dec. 12th, 2015 at 4:00PM, Ben Gotow wrote:"
To create MessageViewExtension that customize message viewing, you
+should create objects that implement the interface defined at {MessageViewExtension}.
+
To register your extension with the ExtensionRegistry, call {ExtensionRegistry::MessageView::registerExtension}.
+When your package is being unloaded, you must call the corresponding
+{ExtensionRegistry::MessageView::unregisterExtension} to unhook your extension.
The MessageViewExtension API does not currently expose any asynchronous or {Promise}-based APIs.
+This will likely change in the future. If you have a use-case for a Message Store extension that
+is not possible with the current API, please let us know.
+
+
+
+
+
+
+
+
Class Methods
+
+ formatMessageBody()
+
+
+
+
Modify the body of the message provided. Note that you're provided
+the entire message object, but you can only change `message.body`.
+
+
+
+
+ renderedMessageBodyIntoDocument()
+
+
+
+
Modify the rendered message body using the DOM.
+Runs after messages goes through `formatMessageBody` and is placed
+into the DOM.
A base class for API objects that provides abstract support for
+serialization and deserialization, matching by attributes, and ID-based equality.
+
Attributes
+
id: {AttributeString} The resolved canonical ID of the model used in the
+database and generally throughout the app. The id property is a custom
+getter that resolves to the serverId first, and then the clientId.
+
clientId: {AttributeString} An ID created at object construction and
+persists throughout the lifetime of the object. This is extremely useful
+for optimistically creating objects (like drafts and categories) and
+having a constant reference to it. In all other cases, use the resolved
+id field.
+
serverId: {AttributeServerId} The server ID of the model. In most cases,
+except optimistic creation, this will also be the canonical id of the
+object.
+
object: {AttributeString} The model's type. This field is used by the JSON
+ deserializer to create an instance of the correct class when inflating the object.
+
accountId: {AttributeString} The string Account Id this model belongs to.
+
+
+
+
+
+
+
+
+
+
Instance Methods
+
+ attributes()
+
+
+
+
+
+
+
+
Returns
+
+
+
Return Values
+
+
Returns an {Array} of {Attribute} objects defined on the Model's constructor
+
+
+ toJSON([options])
+
+
+
+
Deflates the model to a plain JSON object. Only attributes defined
+on the model are included in the JSON.
+
+
+Parameters
+
+
+
Argument
+
Description
+
+
+
+ options
+
+
+ Optional
+ An {Object} with additional options. To skip joined data attributes in the toJSON representation, pass the `joined:false`
+
+
+
+
+
Returns
+
+
+
Return Values
+
+
Returns an {Object} with the JSON representation of the model.
+
+
+ matches(criteria)
+
+
+
+
Evaluates the model against one or more {Matcher} objects.
+
+
+Parameters
+
+
+
Argument
+
Description
+
+
+
+ criteria
+
+
+
+ An {Array} of {Matcher}s to run on the model.
+
ModelQuery exposes an ActiveRecord-style syntax for building database queries
+that return models and model counts. Model queries are returned from the factory methods
+DatabaseStore::find, DatabaseStore::findBy, DatabaseStore::findAll, and DatabaseStore::count, and are the primary interface for retrieving data
+from the app's local cache.
Add one or more where clauses to the query
+
+This method is chainable.
+
+
+
Parameters
+
+
+
Argument
+
Description
+
+
+
+ matchers
+
+
+
+ An {Array} of {Matcher} objects that add where clauses to the underlying query.
+
+
+
+
+
+ include(attr)
+
+
+
+
Include specific joined data attributes in result objects.
+
+This method is chainable.
+
+
+
Parameters
+
+
+
Argument
+
Description
+
+
+
+ attr
+
+
+
+ A {AttributeJoinedData} that you want to be populated in the returned models. Note: This results in a LEFT OUTER JOIN. See {AttributeJoinedData} for more information.
+
+
+
+
+
+ includeAll()
+
+
+
+
Include all of the available joined data attributes in returned models.
+
+This method is chainable.
+
+
+
+
+ order(orders)
+
+
+
+
Apply a sort order to the query.
+
+This method is chainable.
+
+
+
Parameters
+
+
+
Argument
+
Description
+
+
+
+ orders
+
+
+
+ An {Array} of one or more {SortOrder} objects that determine the sort order of returned models.
+
+
+
+
+
+ one()
+
+
+
+
Set the `singular` flag - only one model will be returned from the
+query, and a `LIMIT 1` clause will be used.
+
+This method is chainable.
+
+
+
+
+ limit(limit)
+
+
+
+
Limit the number of query results.
+
+This method is chainable.
+
+
+
Parameters
+
+
+
Argument
+
Description
+
+
+
+ limit
+
+
+
+ {Number} The number of models that should be returned.
+
+
+
+
+
+ offset(offset)
+
+
+
+
+
+This method is chainable.
+
+
+
Parameters
+
+
+
Argument
+
Description
+
+
+
+ offset
+
+
+
+ {Number} The start offset of the query.
+
+
+
+
+
+ page()
+
+
+
+
+
+A convenience method for setting both limit and offset given a desired page size.
+
+
+
+
+ count()
+
+
+
+
Set the `count` flag - instead of returning inflated models,
+the query will return the result `COUNT`.
+
+This method is chainable.
+
+
+
+
+ then()
+
+
+
+
Short-hand syntax that calls run().then(fn) with the provided function.
+
+
+
+
Returns
+
+
+
Return Values
+
+
Returns a {Promise} that resolves with the Models returned by the
+query, or rejects with an error from the Database layer.
+
+
+ run()
+
+
+
+
+
+
+
+Returns
+
+
+
Return Values
+
+
Returns a {Promise} that resolves with the Models returned by the
+query, or rejects with an error from the Database layer.
MultiselectActionBar is a simple component that can be placed in a {Sheet} Toolbar.
+When the provided dataStore has a selection, it appears over the other items in the toolbar.
+
Generally, you wrap {MultiselectActionBar} in your own simple component to provide a dataStore
+and other settings:
The MultiselectActionBar uses the ComponentRegistry to find items to display for the given
+collection name. To add an item to the bar created in the example above, register it like this:
+
+ The name of the collection. The collection name is used for the text that appears in the bar "1 thread selected" and is also used to find components in the component registry that should appear in the bar (`thread` => `thread:BulkAtion`)
+
MultiselectList wraps {ListTabular} and makes it easy to present a
+{ListDataSource} with selection support. It adds a checkbox column to the columns
+you provide, and also handles:
report an error through the `ErrorLogger`
+
+Takes an error and an extra object to report. Hooks into the
+`onWillThrowError` and `onDidThrowError` callbacks. If someone
+registered with `onWillThrowError` calls `preventDefault` on the event
+object it's given, then no error will be reported.
+
+The difference between this and `ErrorLogger.reportError` is that
+`NylasEnv.reportError` will hook into the event callbacks and handle
+test failures and dev tool popups.
+
+
+
+
+ onDidBeep(callback)
+
+
+
+
Invoke the given callback whenever beep is called.
+
+
+
Parameters
+
+
+
Argument
+
Description
+
+
+
+ callback
+
+
+
+ {Function} to be called whenever beep is called.
+
+
+
+
+
Returns
+
+
+
Return Values
+
+
Returns a {Disposable} on which `.dispose()` can be called to unsubscribe.
+
+
+ onWillThrowError(callback)
+
+
+
+
Invoke the given callback when there is an unhandled error, but
+before the devtools pop open
+
+
+Parameters
+
+
+
Argument
+
Description
+
+
+
+ callback
+
+
+
+ {Function} to be called whenever there is an unhandled error
+
+
+
+
+
Returns
+
+
+
Return Values
+
+
Returns a {Disposable} on which `.dispose()` can be called to unsubscribe.
+
+
+ onDidThrowError(callback)
+
+
+
+
Invoke the given callback whenever there is an unhandled error.
+
+
+Parameters
+
+
+
Argument
+
Description
+
+
+
+ callback
+
+
+
+ {Function} to be called whenever there is an unhandled error
+
+
+
+
+
Returns
+
+
+
Return Values
+
+
Returns a {Disposable} on which `.dispose()` can be called to unsubscribe.
+
+
+ trace()
+
+
+
+
Run the Chromium content-tracing module for five seconds, and save
+the output to a file which is printed to the command-line output of the app.
+You can take the file exported by this function and load it into Chrome's
+content trace visualizer (chrome://tracing). It's like Chromium Developer
+Tools Profiler, but for all processes and threads.
+
+
+
+
+ inDevMode()
+
+
+
+
Is the current window in development mode?
+
+
+
+
+ inSafeMode()
+
+
+
+
Is the current window in safe mode?
+
+
+
+
+ inSpecMode()
+
+
+
+
Is the current window running specs?
+
+
+
+
+ getVersion()
+
+
+
+
Get the version of N1.
+
+
+
+Returns
+
+
+
Return Values
+
+
Returns the version text {String}.
+
+
+ isReleasedVersion()
+
+
+
+
Determine whether the current version is an official release.
+
+
+
+
+ getConfigDirPath()
+
+
+
+
Get the directory path to N1's configuration area.
+
+
+
+
+ getWindowLoadTime()
+
+
+
+
Get the time taken to completely load the current window.
+
+This time include things like loading and activating packages, creating
+DOM elements for the editor, and reading the config.
+
+
+
+Returns
+
+
+
Return Values
+
+
Returns the {Number} of milliseconds taken to load the window or null
+if the window hasn't finished loading yet.
+
+
+ close()
+
+
+
+
Close the current window.
+
+
+
+
+ getSize()
+
+
+
+
Get the size of current window.
+
+
+
+Returns
+
+
+
Return Values
+
+
Returns an {Object} in the format `{width: 1000, height: 700}`
+
+
+ setSize(widthheight)
+
+
+
+
Set the size of current window.
+
+
+Parameters
+
+
+
Argument
+
Description
+
+
+
+ width
+
+
+
+ The {Number} of pixels.
+
+
+
+
+ height
+
+
+
+ The {Number} of pixels.
+
+
+
+
+
+ setSizeAnimated(widthheightduration)
+
+
+
+
Transition and set the size of the current window.
+
+
+
Parameters
+
+
+
Argument
+
Description
+
+
+
+ width
+
+
+
+ The {Number} of pixels.
+
+
+
+
+ height
+
+
+
+ The {Number} of pixels.
+
+
+
+
+ duration
+
+
+
+ The {Number} of pixels.
+
+
+
+
+
+ getPosition()
+
+
+
+
Get the position of current window.
+
+
+
+
Returns
+
+
+
Return Values
+
+
Returns an {Object} in the format `{x: 10, y: 20}`
+
+
+ setPosition(xy)
+
+
+
+
Set the position of current window.
+
+
+Parameters
+
+
+
Argument
+
Description
+
+
+
+ x
+
+
+
+ The {Number} of pixels.
+
+
+
+
+ y
+
+
+
+ The {Number} of pixels.
+
+
+
+
+
+ center()
+
+
+
+
Move current window to the center of the screen.
+
+
+
+
+ focus()
+
+
+
+
Focus the current window. Note: this will not open the window
+if it is hidden.
+
+
+
+
+ show()
+
+
+
+
Show the current window.
+
+
+
+
+ hide()
+
+
+
+
Hide the current window.
+
+
+
+
+ reload()
+
+
+
+
Reload the current window.
+
+
+
+
+ getWindowProps()
+
+
+
+
The windowProps passed when creating the window via `newWindow`.
+
+
+
+
+ onWindowPropsReceived()
+
+
+
+
If your package declares hot-loaded window types, `onWindowPropsReceived`
+fires when your hot-loaded window is about to be shown so you can update
+components to reflect the new window props.
+
+* callback: A function to call when window props are received, just before
+ the hot window is shown. The first parameter is the new windowProps.
+
+
+
+
+ isMaximixed()
+
+
+
+
Is the current window maximized?
+
+
+
+
+ isFullScreen()
+
+
+
+
Is the current window in full screen mode?
+
+
+
+
+ setFullScreen()
+
+
+
+
Set the full screen state of the current window.
+
+
+
+
+ toggleFullScreen()
+
+
+
+
Toggle the full screen state of the current window.
+
+
+
+
+ beep()
+
+
+
+
Visually and audibly trigger a beep.
+
+
+
+
+ confirm(options)
+
+
+
+
A flexible way to open a dialog akin to an alert dialog.
+
+
+
Parameters
+
+
+
Argument
+
Description
+
+
+
+ options
+
+
+
+ An {Object} with the following keys:
+
+
+
+
+
Returns
+
+
+
Return Values
+
+
Returns the chosen button index {Number} if the buttons option was an array.
+
+
+ openDevTools()
+
+
+
+
Open the dev tools for the current window.
+
+
+
+
+ toggleDevTools()
+
+
+
+
Toggle the visibility of the dev tools for the current window.
Invoke the given callback when all packages have been loaded.
+
+
+
Parameters
+
+
+
Argument
+
Description
+
+
+
+ callback
+
+
+
+ {Function}
+
+
+
+
+
Returns
+
+
+
Return Values
+
+
Returns a {Disposable} on which `.dispose()` can be called to unsubscribe.
+
+
+ onDidActivateInitialPackages(callback)
+
+
+
+
Invoke the given callback when all packages have been activated.
+
+
+Parameters
+
+
+
Argument
+
Description
+
+
+
+ callback
+
+
+
+ {Function}
+
+
+
+
+
Returns
+
+
+
Return Values
+
+
Returns a {Disposable} on which `.dispose()` can be called to unsubscribe.
+
+
+ onDidActivatePackage(callback)
+
+
+
+
Invoke the given callback when a package is activated.
+
+
+Parameters
+
+
+
Argument
+
Description
+
+
+
+ callback
+
+
+
+ A {Function} to be invoked when a package is activated.
+
+
+
+
+
Returns
+
+
+
Return Values
+
+
Returns a {Disposable} on which `.dispose()` can be called to unsubscribe.
+
+
+ onDidDeactivatePackage(callback)
+
+
+
+
Invoke the given callback when a package is deactivated.
+
+
+Parameters
+
+
+
Argument
+
Description
+
+
+
+ callback
+
+
+
+ A {Function} to be invoked when a package is deactivated.
+
+
+
+
+
Returns
+
+
+
Return Values
+
+
Returns a {Disposable} on which `.dispose()` can be called to unsubscribe.
+
+
+ onDidLoadPackage(callback)
+
+
+
+
Invoke the given callback when a package is loaded.
+
+
+Parameters
+
+
+
Argument
+
Description
+
+
+
+ callback
+
+
+
+ A {Function} to be invoked when a package is loaded.
+
+
+
+
+
Returns
+
+
+
Return Values
+
+
Returns a {Disposable} on which `.dispose()` can be called to unsubscribe.
+
+
+ onDidUnloadPackage(callback)
+
+
+
+
Invoke the given callback when a package is unloaded.
+
+
+Parameters
+
+
+
Argument
+
Description
+
+
+
+ callback
+
+
+
+ A {Function} to be invoked when a package is unloaded.
+
+
+
+
+
Returns
+
+
+
Return Values
+
+
Returns a {Disposable} on which `.dispose()` can be called to unsubscribe.
+
+
+ getApmPath()
+
+
+
+
Get the path to the apm command.
+
+Return a {String} file path to apm.
+
+
+
+
+ getPackageDirPaths()
+
+
+
+
Get the paths being used to look for packages.
+
+
+
+Returns
+
+
+
Return Values
+
+
Returns an {Array} of {String} directory paths.
+
+
+ resolvePackagePath(name)
+
+
+
+
Resolve the given package name to a path on disk.
+
+Return a {String} folder path or undefined if it could not be resolved.
+
+
+Parameters
+
+
+
Argument
+
Description
+
+
+
+ name
+
+
+
+ The {String} package name.
+
+
+
+
+
+ isBundledPackage(name)
+
+
+
+
Is the package with the given name bundled with Nylas?
+
+
+
Parameters
+
+
+
Argument
+
Description
+
+
+
+ name
+
+
+
+ The {String} package name.
+
+
+
+
+
Returns
+
+
+
Return Values
+
+
Returns a {Boolean}.
+
+
+ enablePackage()
+
+
+
+
Enable the package with the given name.
+
+
+
+Returns
+
+
+
Return Values
+
+
Returns the {Package} that was enabled or null if it isn't loaded.
+
+
+ disablePackage()
+
+
+
+
Disable the package with the given name.
+
+
+
+Returns
+
+
+
Return Values
+
+
Returns the {Package} that was disabled or null if it isn't loaded.
+
+
+ isPackageDisabled(name)
+
+
+
+
Is the package with the given name disabled?
+
+
+Parameters
+
+
+
Argument
+
Description
+
+
+
+ name
+
+
+
+ The {String} package name.
+
+
+
+
+
Returns
+
+
+
Return Values
+
+
Returns a {Boolean}.
+
+
+ getActivePackages()
+
+
+
+
Get an {Array} of all the active {Package}s.
+
+
+
+
+ getActivePackage(name)
+
+
+
+
Get the active {Package} with the given name.
+
+
+Parameters
+
+
+
Argument
+
Description
+
+
+
+ name
+
+
+
+ The {String} package name.
+
+
+
+
+
Returns
+
+
+
Return Values
+
+
Returns a {Package} or .
+
+
+ isPackageActive(name)
+
+
+
+
Is the {Package} with the given name active?
+
+
+Parameters
+
+
+
Argument
+
Description
+
+
+
+ name
+
+
+
+ The {String} package name.
+
+
+
+
+
Returns
+
+
+
Return Values
+
+
Returns a {Boolean}.
+
+
+ getLoadedPackages()
+
+
+
+
Get an {Array} of all the loaded {Package}s
+
+
+
+
+ getLoadedPackage(name)
+
+
+
+
Get the loaded {Package} with the given name.
+
+
+Parameters
+
+
+
Argument
+
Description
+
+
+
+ name
+
+
+
+ The {String} package name.
+
+
+
+
+
Returns
+
+
+
Return Values
+
+
Returns a {Package} or .
+
+
+ getPluginIdsByPathBase()
+
+
+
+
Gets the root paths of all loaded packages.
+
+Useful when determining if an error originated from a package.
+
+
+
+
+ isPackageLoaded(name)
+
+
+
+
Is the package with the given name loaded?
+
+
+Parameters
+
+
+
Argument
+
Description
+
+
+
+ name
+
+
+
+ The {String} package name.
+
+
+
+
+
Returns
+
+
+
Return Values
+
+
Returns a {Boolean}.
+
+
+ getAvailablePackagePaths()
+
+
+
+
Get an {Array} of {String}s of all the available package paths.
+
+If the optional windowType is passed, it will only load packages
+that declare that windowType in their package.json
+
+
+
+
+ getAvailablePackageNames()
+
+
+
+
Get an {Array} of {String}s of all the available package names.
+
+
+
+
+ getAvailablePackageMetadata()
+
+
+
+
Get an {Array} of {String}s of all the available package metadata.
Instances of QueryResultSet hold a set of models retrieved
+from the database at a given offset.
+
Complete vs Incomplete:
+
QueryResultSet keeps an array of item ids and a lookup table of models.
+The lookup table may be incomplete if the QuerySubscription isn't finished
+preparing results. You can use isComplete to determine whether the set
+has every model.
+
Offset vs Index:
+
To avoid confusion, "index" refers to an item's position in an
+array, and "offset" refers to it's position in the query result set. For example,
+an item might be at index 20 in the _ids array, but at offset 120 in the result.
+
Ids and clientIds:
+
QueryResultSet calways returns object ids when asked for ids, but lookups
+for models by clientId work once models are loaded.
The QuerySubscriptionPool maintains a list of all of the query
+subscriptions in the app. In the future, this class will monitor performance,
+merge equivalent subscriptions, etc.
ResizableRegion wraps it's children in a div with a fixed width or height, and a
+draggable edge. It is used throughout N1 to implement resizable columns, trays, etc.
RetinaImg wraps the DOM's standard <img> tag and implements a UIImage style
+interface. Rather than specifying an image src, RetinaImg allows you to provide
+an image name. Like UIImage on iOS, it automatically finds the best image for the current
+display based on pixel density. Given image.png, on a Retina screen, it looks for
+image@2x.png, image.png, image@1x.png in that order. It uses a lookup table and caches
+image names, so images generally resolve immediately.
+
RetinaImg also introduces the concept of image modes. Specifying an image mode
+is important for theming: it describes the content of your image, allowing theme
+developers to properly adjust it. The four modes are described below:
+
+
ContentPreserve: Your image contains color or should not be adjusted by any theme.
+
ContentLight: Your image is a grayscale image with light colors, intended to be shown
+against a dark background. If a theme developer changes the background to be light, they
+can safely apply CSS filters to invert or darken this image. This mode adds the
+content-light CSS class to the image.
+
ContentDark: Your image is a grayscale image with dark colors, intended to be shown
+against a light background. If a theme developer changes the background to be dark, they
+can safely apply CSS filters to invert or brighten this image. This mode adds the
+content-dark CSS class to the image.
+
ContentIsMask: This image provides alpha information only, and color should
+be based on the background-color of the RetinaImg. This mode adds the
+content-mask CSS class to the image, and leverages -webkit-mask-image.
+Example: Icons displayed within buttons specify ContentIsMask, and their
+color is declared via CSS to be the same as the button text color. Changing
+@text-color-subtle in a theme changes both button text and button icons!
Represents a particular sort direction on a particular column. You should not
+instantiate SortOrders manually. Instead, call Attribute::ascending or
+Attribute::descending to obtain a sort order instance:
A singleton instance of this class available via NylasEnv.styles,
+which you can use to globally query and observe the set of active style
+sheets. The StyleManager doesn't add any style elements to the DOM on its
+own, but is instead subscribed to by individual <nylas-styles> elements,
+which clone and attach style elements in different contexts.
The Task system handles dependencies between multiple queued tasks. For
+example, the {SendDraftTask} has a dependency on the {SyncbackDraftTask}
+(aka saving) succeeding. To establish dependencies between tasks, your
+subclass may implement one or more of the following methods:
All tasks should gracefully handle the case when there is no network
+connection.
+
if we're offline the common behavior is for a task to:
+
+
Perform its local change
+
Attempt the remote request, which will fail
+
Have performRemote resolve a Task.Status.Retry
+
Sit queued up waiting to be retried
+
+
Remember that a user may be offline for hours and perform thousands of
+tasks in the meantime. It's important that your tasks implement
+shouldDequeueOtherTask and isDependentOnTask to make sure ordering
+always remains correct.
+
Serialization and Window Considerations
+
The whole {TaskQueue} and all of its Tasks are serialized and stored in
+the Database. This allows the {TaskQueue} to work across windows and
+ensures we don't lose any pending tasks if (a user is offline for a while)
+and quits and relaunches the application.
+
All instance variables you create must be able to be serialized to a
+JSON string and re-inflated. Notably, function objects will not be
+properly re-inflated.
+
if (you have instance variables that are instances of core {Model})
+classes or {Task} classes, they will be automatically re-inflated to the
+correct class via Utils::deserializeRegisteredObject. if (you create)
+your own custom classes, they must be registered once per window via
+TaskRegistry::register
import {Actions} from 'nylas-exports';
+import UpdateTodoTask from './update-todo-task';
+
+someMethod() {
+...
+const task = new UpdateTodoTask(existingTodo, {name: "Test"});
+Actions.queueTask(task);
+...
+}
+
+
This example UpdateTodoTask does not handle undo/redo, nor does it
+rollback the changes if (there's an API error. See examples in)
+Task::performLocal for ideas on how to handle this.
+
+
+
+
+
+
+
+
+
+
Instance Methods
+
+ constructor()
+
+
+
+
Override the constructor to pass initial args to your Task and
+initialize instance variables.
+
+**IMPORTANT:** if (you override the constructor, be sure to call)
+`super`.
+
+On construction, all Tasks instances are given a unique `id`.
**Required** | Put the actual API request code here.
+
+You must return a {Promise} that resolves to one of the following
+status constants:
+
+The resolved status will determine what the {TaskQueue} does with this
+task when it is finished.
+
+This is where you should put your actual API code. You can use the
+node `request` library to easily hit APIs, or use the {NylasAPI} class
+to talk to the [Nylas Platform API](https://nylas.com/cloud/docs/).
+
+Here is a more detailed explanation of Task Statuses:
+
+### Task.Status.Success
+
+Resolve to `Task.Status.Success` when the task successfully completes.
+Once done, the task will be dequeued and logged as a success.
+
+### Task.Status.Retry
+
+if (you resolve `Task.Status.Retry`, the task will remain on the queue)
+and tried again later. Any other task dependent on the current one
+will also continue waiting.
+
+`Task.Status.Retry` is useful if (it looks like we're offline, or you)
+get an API error code that indicates temporary failure.
+
+### Task.Status.Continue
+
+Resolving `Task.Status.Continue` will silently dequeue the task, allow
+dependent tasks through, but not mark it as successfully resolved.
+
+This is useful if (you get permanent API errors, but don't really care)
+if (the task failed.)
+
+### Task.Status.Failed
+
+if (you catch a permanent API error code (like a 500), or something)
+else goes wrong then resolve to `Task.Status.Failed`.
+
+Resolving `Task.Status.Failed` will dequeue this task, and **dequeue
+all dependent tasks**.
+
+You can optionally return the error object itself for debugging
+purposes by resolving an array of the form: `[Task.Status.Failed,
+errorObject]`
+
+You should not `throw` exceptions. Catch all cases yourself and
+determine which `Task.Status` to resolve to. if (due to programmer)
+error an exception is thrown, our {TaskQueue} will catch it, log it,
+and deal with the task as if (it resolved `Task.Status.Failed`.)
+
+
+
Parameters
+
+
+
Argument
+
Description
+
+
+
+ Task.Status.Success
+
+
+
+
+
+
+
+
+ Task.Status.Retry
+
+
+
+
+
+
+
+
+ Task.Status.Continue
+
+
+
+
+
+
+
+
+ Task.Status.Failed
+
+
+
+
+
+
+
+
+
Returns
+
+
+
Return Values
+
+
Returns a {Promise} that resolves to a valid `Task.Status` type.
+
+
+ isDependentOnTask(other)
+
+
+
+
determines which other tasks this one is dependent on.
+
+Any task that passes the truth test will be considered a "dependency".
+
+if a "dependency" has a `Task.Status.Failed`, then all downstream
+tasks will get dequeued recursively for any of the downstream tasks that
+return true for `shouldBeDequeuedOnDependencyFailure`
+
+A task will also never be run at the same time as one of its
+dependencies.
+
+
+Parameters
+
+
+
Argument
+
Description
+
+
+
+ other
+
+
+
+ An instance of a {Task} you must test to see if (it's a) dependency of this one.
+
+
+
+
+
Returns
+
+
+
Return Values
+
+
Returns `true` (is dependent on) or `false` (is not dependent on)
+
+
+ shouldDequeueOtherTask(other)
+
+
+
+
determines which other tasks this one should dequeue when
+it is first queued.
+
+Any task that passes the truth test will be considered "obsolete" and
+dequeued immediately.
+
+This is particularly useful in offline mode. Users may queue up tons
+of tasks but when we come back online to process them, we only want to
+process the latest one.
+
+
+Parameters
+
+
+
Argument
+
Description
+
+
+
+ other
+
+
+
+ An instance of a {Task} you must test to see if (it's now) obsolete.
+
+
+
+
+
Returns
+
+
+
Return Values
+
+
Returns `true` (should dequeue) or `false` (should not dequeue)
+
+
+ shouldBeDequeuedOnDependencyFailure()
+
+
+
+
determines if the current task should be dequeued if one of the
+tasks it depends on fails.
+
+
+
+
Returns
+
+
+
Return Values
+
+
Returns `true` (should dequeue) or `false` (should not dequeue)
+
+
+ isUndo()
+
+
+
+
It's up to you to determine how you want to indicate whether
+or not you have an instance of an "Undo Task". We commonly use a
+simple instance variable boolean flag.
+
+
+
+
Returns
+
+
+
Return Values
+
+
Returns `true` (is an Undo Task) or `false` (is not an Undo Task)
+
+
+ canBeUndone()
+
+
+
+
Determines whether or not this task can be undone via the
+{UndoRedoStore}
+
+
+
+
Returns
+
+
+
Return Values
+
+
Returns `true` (can be undone) or `false` (can't be undone)
+
+
+ createUndoTask()
+
+
+
+
Return from `createIdenticalTask` and set a flag so your
+`performLocal` and `performRemote` methods know that this is an undo
+task.
+
+
+
+
+ createIdenticalTask()
+
+
+
+
Return a deep-cloned task to be used for an undo task
+
+
+
+
+ cancel()
+
+
+
+
code to run if (someone tries to dequeue your task while it is)
+in flight.
+
+
+
+
+ label()
+
+
+
+
(optional) A string displayed to users when your task is run.
+
+When tasks are run, we automatically display a notification to users
+of the form "label (numberOfImpactedItems)". if (this does not a return)
+a string, no notification is displayed
+
+
+
+
+ numberOfImpactedItems()
+
+
+
+
A string displayed to users indicating how many items your
+task affected.
The TaskQueue is a Flux-compatible Store that manages a queue of {Task}
+objects. Each {Task} represents an individual API action, like sending a draft
+or marking a thread as "read". Tasks optimistically make changes to the app's
+local cache and encapsulate logic for performing changes on the server, rolling
+back in case of failure, and waiting on dependent tasks.
+
The TaskQueue is essential to offline mode in N1. It automatically pauses
+when the user's internet connection is unavailable and resumes when online.
+
The task queue is persisted to disk, ensuring that tasks are executed later,
+even if the user quits N1.
+
The TaskQueue is only available in the app's main window. Rather than directly
+queuing tasks, you should use the {Actions} to interact with the {TaskQueue}.
+Tasks queued from secondary windows are serialized and sent to the application's
+main window via IPC.
+
+ The string name of the task class, or the Task class itself. (ie: {SaveDraftTask} or 'SaveDraftTask')
+
+
+
+
+ matching
+
+
+
+ Optional An {Object} with criteria to pass to _.isMatch. For a SaveDraftTask, this could be {draftClientId: "123123"}
+
+
+
+
+
Returns
+
+
+
Return Values
+
+
Returns an existing task in the queue that matches the type you provide,
+and any other match properties. Useful for checking to see if something, like
+a "SendDraft" task is in-flight.
The Thread model represents a Thread object served by the Nylas Platform API.
+For more information about Threads on the Nylas Platform, read the
+Threads API Documentation
+
Attributes
+
snippet: {AttributeString} A short, ~140 character string with the content
+ of the last message in the thread. Queryable.
+
subject: {AttributeString} The subject of the thread. Queryable.
+
unread: {AttributeBoolean} True if the thread is unread. Queryable.
+
starred: {AttributeBoolean} True if the thread is starred. Queryable.
+
version: {AttributeNumber} The version number of the thread.
+
participants: {AttributeCollection} A set of {Contact} models
+ representing the participants in the thread.
+ Note: Contacts on Threads do not have IDs.
+
lastMessageReceivedTimestamp: {AttributeDateTime} The timestamp of the
+ last message on the thread.
Renders a component provided via the component prop, and ensures that
+failures in the component's code do not cause state inconsistencies elsewhere in
+the application. This component is used by {InjectedComponent} and
+{InjectedComponentSet} to isolate third party code that could be buggy.
+
Occasionally, having your component wrapped in {UnsafeComponent} can cause style
+issues. For example, in a Flexbox, the div.unsafe-component-wrapper will cause
+your flex and order values to be one level too deep. For these scenarios,
+UnsafeComponent looks for containerStyles on your React component and attaches
+them to the wrapper div:
The WorkspaceStore manages Sheets and layout modes in the application.
+Observing the WorkspaceStore makes it easy to monitor the sheet stack. To learn
+more about sheets and layout in N1, see the {InterfaceConcepts.md}
+documentation.
+
+
+
+
+
+
+
+
+
+
Instance Methods
+
+ topSheet()
+
+
+
+
+
+
+
+
Returns
+
+
+
Return Values
+
+
Returns The top {Sheet} in the current stack. Use this method to determine
+the sheet the user is looking at.
+
+
+ rootSheet()
+
+
+
+
+
+
+
+Returns
+
+
+
Return Values
+
+
Returns The {Sheet} at the root of the current stack.
+
+
+ sheetStack()
+
+
+
+
+
+
+
+Returns
+
+
+
Return Values
+
+
Returns an {Array} The stack of sheets
+
+
+ hiddenLocations()
+
+
+
+
+
+
+
+Returns
+
+
+
Return Values
+
+
Returns an {Array} of locations that have been hidden.
+
+
+ isLocationHidden()
+
+
+
+
+
+
+
+Returns
+
+
+
Return Values
+
+
Returns a {Boolean} indicating whether the location provided is hidden.
+You should provide one of the WorkspaceStore.Location constant values.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/docs/classes/api.json b/docs/classes/api.json
new file mode 100644
index 000000000..a6cfd4524
--- /dev/null
+++ b/docs/classes/api.json
@@ -0,0 +1,4449 @@
+{
+ "classes": {
+ "AccountStore": {
+ "name": "AccountStore",
+ "superClass": "NylasStore",
+ "filename": "docs_src/classes/temp-cjsx/account-store.js",
+ "srcUrl": null,
+ "sections": [],
+ "classMethods": [],
+ "instanceMethods": [
+ {
+ "name": "accountForId",
+ "sectionName": null,
+ "srcUrl": null,
+ "visibility": "Public",
+ "summary": "",
+ "description": "",
+ "returnValues": [
+ {
+ "type": "Account",
+ "description": "Returns the {Account} for the given account id, or null."
+ }
+ ]
+ },
+ {
+ "name": "current",
+ "sectionName": null,
+ "srcUrl": null,
+ "visibility": "Public",
+ "summary": "",
+ "description": "",
+ "returnValues": [
+ {
+ "type": "Account",
+ "description": "Returns the currently active {Account}."
+ }
+ ]
+ }
+ ],
+ "classProperties": [],
+ "instanceProperties": [],
+ "visibility": "Public",
+ "summary": "The AccountStore listens to changes to the available accounts in\nthe database and exposes the currently active Account via {::current}",
+ "description": "The AccountStore listens to changes to the available accounts in\nthe database and exposes the currently active Account via {::current}\n\nSection: Stores"
+ },
+ "Actions": {
+ "name": "Actions",
+ "superClass": null,
+ "filename": "docs_src/classes/temp-cjsx/actions.js",
+ "srcUrl": null,
+ "sections": [],
+ "classMethods": [],
+ "instanceMethods": [],
+ "classProperties": [],
+ "instanceProperties": [],
+ "visibility": "Public",
+ "summary": "In the Flux {Architecture.md}, almost every user action\nis translated into an Action object and fired globally. Stores in the app observe\nthese actions and perform business logic. This loose coupling means that your\npackages can observe actions and perform additional logic, or fire actions which\nthe rest of the app will handle.",
+ "description": "In the Flux {Architecture.md}, almost every user action\nis translated into an Action object and fired globally. Stores in the app observe\nthese actions and perform business logic. This loose coupling means that your\npackages can observe actions and perform additional logic, or fire actions which\nthe rest of the app will handle.\n\nIn Reflux, each {Action} is an independent object that acts as an event emitter.\nYou can listen to an Action, or invoke it as a function to fire it.\n\n## Action Scopes\n\nN1 is a multi-window application. The `scope` of an Action dictates\nhow it propogates between windows.\n\n* **Global**: These actions can be listened to from any window and fired from any\n window. The action is sent from the originating window to all other windows via\n IPC, so they should be used with care. Firing this action from anywhere will\n cause all listeners in all windows to fire.\n* **Main Window**: You can fire these actions in any window. They'll be sent\n to the main window and triggered there.\n* **Window**: These actions only trigger listeners in the window they're fired in.\n\n## Firing Actions\n\n```coffee\nActions.queueTask(new ChangeStarredTask(thread: @_thread, starred: true))\n```\n\n## Listening for Actions\n\nIf you're using Reflux to create your own Store, you can use the `listenTo`\nconvenience method to listen for an Action. If you're creating your own class\nthat is not a Store, you can still use the `listen` method provided by Reflux:\n\n```coffee\nsetup: ->\n @unlisten = Actions.onNewMailDeltas.listen(@onNewMailReceived, @)\n\nonNewMailReceived: (data) ->\n console.log(\"You've got mail!\", data)\n\nteardown: ->\n @unlisten()\n```\n\nSection: General"
+ },
+ "Attribute": {
+ "name": "Attribute",
+ "superClass": null,
+ "filename": "docs_src/classes/temp-cjsx/attribute.js",
+ "srcUrl": null,
+ "sections": [],
+ "classMethods": [],
+ "instanceMethods": [
+ {
+ "name": "equal",
+ "sectionName": null,
+ "srcUrl": null,
+ "visibility": "Public",
+ "summary": "",
+ "description": "",
+ "returnValues": [
+ {
+ "type": "Matcher",
+ "description": "Returns a {Matcher} for objects `=` to the provided value."
+ }
+ ]
+ },
+ {
+ "name": "in",
+ "sectionName": null,
+ "srcUrl": null,
+ "visibility": "Public",
+ "summary": "",
+ "description": "",
+ "returnValues": [
+ {
+ "type": "Matcher",
+ "description": "Returns a {Matcher} for objects `=` to the provided value."
+ }
+ ]
+ },
+ {
+ "name": "not",
+ "sectionName": null,
+ "srcUrl": null,
+ "visibility": "Public",
+ "summary": "",
+ "description": "",
+ "returnValues": [
+ {
+ "type": "Matcher",
+ "description": "Returns a {Matcher} for objects `!=` to the provided value."
+ }
+ ]
+ },
+ {
+ "name": "descending",
+ "sectionName": null,
+ "srcUrl": null,
+ "visibility": "Public",
+ "summary": "",
+ "description": "",
+ "returnValues": [
+ {
+ "type": "SortOrder",
+ "description": "Returns a descending {SortOrder} for this attribute."
+ }
+ ]
+ },
+ {
+ "name": "ascending",
+ "sectionName": null,
+ "srcUrl": null,
+ "visibility": "Public",
+ "summary": "",
+ "description": "",
+ "returnValues": [
+ {
+ "type": "SortOrder",
+ "description": "Returns an ascending {SortOrder} for this attribute."
+ }
+ ]
+ }
+ ],
+ "classProperties": [],
+ "instanceProperties": [],
+ "visibility": "Public",
+ "summary": "The Attribute class represents a single model attribute, like 'account_id'.\nSubclasses of {Attribute} like {AttributeDateTime} know how to covert between\nthe JSON representation of that type and the javascript representation.\nThe Attribute class also exposes convenience methods for generating {Matcher} objects.",
+ "description": "The Attribute class represents a single model attribute, like 'account_id'.\nSubclasses of {Attribute} like {AttributeDateTime} know how to covert between\nthe JSON representation of that type and the javascript representation.\nThe Attribute class also exposes convenience methods for generating {Matcher} objects.\n\nSection: Database"
+ },
+ "AttributeBoolean": {
+ "name": "AttributeBoolean",
+ "superClass": "Attribute",
+ "filename": "docs_src/classes/temp-cjsx/attribute-boolean.js",
+ "srcUrl": null,
+ "sections": [],
+ "classMethods": [],
+ "instanceMethods": [],
+ "classProperties": [],
+ "instanceProperties": [],
+ "visibility": "Public",
+ "summary": "The value of this attribute is always a boolean. Null values are coerced to false.",
+ "description": "The value of this attribute is always a boolean. Null values are coerced to false.\n\nString attributes can be queries using `equal` and `not`. Matching on\n`greaterThan` and `lessThan` is not supported.\n\nSection: Database"
+ },
+ "AttributeCollection": {
+ "name": "AttributeCollection",
+ "superClass": "Attribute",
+ "filename": "docs_src/classes/temp-cjsx/attribute-collection.js",
+ "srcUrl": null,
+ "sections": [],
+ "classMethods": [],
+ "instanceMethods": [
+ {
+ "name": "contains",
+ "sectionName": null,
+ "srcUrl": null,
+ "visibility": "Public",
+ "summary": "",
+ "description": "",
+ "returnValues": [
+ {
+ "type": "Matcher",
+ "description": "Returns a {Matcher} for objects containing the provided value."
+ }
+ ]
+ }
+ ],
+ "classProperties": [],
+ "instanceProperties": [],
+ "visibility": "Public",
+ "summary": "Collection attributes provide basic support for one-to-many relationships.\nFor example, Threads in N1 have a collection of Labels or Folders.",
+ "description": "Collection attributes provide basic support for one-to-many relationships.\nFor example, Threads in N1 have a collection of Labels or Folders.\n\nWhen Collection attributes are marked as `queryable`, the DatabaseStore\nautomatically creates a join table and maintains it as you create, save,\nand delete models. When you call `persistModel`, entries are added to the\njoin table associating the ID of the model with the IDs of models in the collection.\n\nCollection attributes have an additional clause builder, `contains`:\n\n```coffee\nDatabaseStore.findAll(Thread).where([Thread.attributes.categories.contains('inbox')])\n```\n\nThis is equivalent to writing the following SQL:\n\n```sql\nSELECT `Thread`.`data` FROM `Thread`\nINNER JOIN `ThreadLabel` AS `M1` ON `M1`.`id` = `Thread`.`id`\nWHERE `M1`.`value` = 'inbox'\nORDER BY `Thread`.`last_message_received_timestamp` DESC\n```\n\nThe value of this attribute is always an array of other model objects.\n\nSection: Database"
+ },
+ "AttributeDateTime": {
+ "name": "AttributeDateTime",
+ "superClass": "Attribute",
+ "filename": "docs_src/classes/temp-cjsx/attribute-datetime.js",
+ "srcUrl": null,
+ "sections": [],
+ "classMethods": [],
+ "instanceMethods": [
+ {
+ "name": "greaterThan",
+ "sectionName": null,
+ "srcUrl": null,
+ "visibility": "Public",
+ "summary": "",
+ "description": "",
+ "returnValues": [
+ {
+ "type": "Matcher",
+ "description": "Returns a {Matcher} for objects greater than the provided value."
+ }
+ ]
+ },
+ {
+ "name": "lessThan",
+ "sectionName": null,
+ "srcUrl": null,
+ "visibility": "Public",
+ "summary": "",
+ "description": "",
+ "returnValues": [
+ {
+ "type": "Matcher",
+ "description": "Returns a {Matcher} for objects less than the provided value."
+ }
+ ]
+ },
+ {
+ "name": "greaterThanOrEqualTo",
+ "sectionName": null,
+ "srcUrl": null,
+ "visibility": "Public",
+ "summary": "",
+ "description": "",
+ "returnValues": [
+ {
+ "type": "Matcher",
+ "description": "Returns a {Matcher} for objects greater than the provided value."
+ }
+ ]
+ },
+ {
+ "name": "lessThanOrEqualTo",
+ "sectionName": null,
+ "srcUrl": null,
+ "visibility": "Public",
+ "summary": "",
+ "description": "",
+ "returnValues": [
+ {
+ "type": "Matcher",
+ "description": "Returns a {Matcher} for objects less than the provided value."
+ }
+ ]
+ }
+ ],
+ "classProperties": [],
+ "instanceProperties": [],
+ "visibility": "Public",
+ "summary": "The value of this attribute is always a Javascript `Date`, or `null`.",
+ "description": "The value of this attribute is always a Javascript `Date`, or `null`.\n\nSection: Database"
+ },
+ "AttributeJoinedData": {
+ "name": "AttributeJoinedData",
+ "superClass": "Attribute",
+ "filename": "docs_src/classes/temp-cjsx/attribute-joined-data.js",
+ "srcUrl": null,
+ "sections": [],
+ "classMethods": [],
+ "instanceMethods": [],
+ "classProperties": [],
+ "instanceProperties": [],
+ "visibility": "Public",
+ "summary": "Joined Data attributes allow you to store certain attributes of an\nobject in a separate table in the database. We use this attribute\ntype for Message bodies. Storing message bodies, which can be very\nlarge, in a separate table allows us to make queries on message\nmetadata extremely fast, and inflate Message objects without their\nbodies to build the thread list.",
+ "description": "Joined Data attributes allow you to store certain attributes of an\nobject in a separate table in the database. We use this attribute\ntype for Message bodies. Storing message bodies, which can be very\nlarge, in a separate table allows us to make queries on message\nmetadata extremely fast, and inflate Message objects without their\nbodies to build the thread list.\n\nWhen building a query on a model with a JoinedData attribute, you need\nto call `include` to explicitly load the joined data attribute.\nThe query builder will automatically perform a `LEFT OUTER JOIN` with\nthe secondary table to retrieve the attribute:\n\n```coffee\nDatabaseStore.find(Message, '123').then (message) ->\n // message.body is undefined\n\nDatabaseStore.find(Message, '123').include(Message.attributes.body).then (message) ->\n // message.body is defined\n```\n\nWhen you call `persistModel`, JoinedData attributes are automatically\nwritten to the secondary table.\n\nJoinedData attributes cannot be `queryable`.\n\nSection: Database"
+ },
+ "AttributeNumber": {
+ "name": "AttributeNumber",
+ "superClass": "Attribute",
+ "filename": "docs_src/classes/temp-cjsx/attribute-number.js",
+ "srcUrl": null,
+ "sections": [],
+ "classMethods": [],
+ "instanceMethods": [
+ {
+ "name": "greaterThan",
+ "sectionName": null,
+ "srcUrl": null,
+ "visibility": "Public",
+ "summary": "",
+ "description": "",
+ "returnValues": [
+ {
+ "type": "Matcher",
+ "description": "Returns a {Matcher} for objects greater than the provided value."
+ }
+ ]
+ },
+ {
+ "name": "lessThan",
+ "sectionName": null,
+ "srcUrl": null,
+ "visibility": "Public",
+ "summary": "",
+ "description": "",
+ "returnValues": [
+ {
+ "type": "Matcher",
+ "description": "Returns a {Matcher} for objects less than the provided value."
+ }
+ ]
+ },
+ {
+ "name": "greaterThanOrEqualTo",
+ "sectionName": null,
+ "srcUrl": null,
+ "visibility": "Public",
+ "summary": "",
+ "description": "",
+ "returnValues": [
+ {
+ "type": "Matcher",
+ "description": "Returns a {Matcher} for objects greater than the provided value."
+ }
+ ]
+ },
+ {
+ "name": "lessThanOrEqualTo",
+ "sectionName": null,
+ "srcUrl": null,
+ "visibility": "Public",
+ "summary": "",
+ "description": "",
+ "returnValues": [
+ {
+ "type": "Matcher",
+ "description": "Returns a {Matcher} for objects less than the provided value."
+ }
+ ]
+ }
+ ],
+ "classProperties": [],
+ "instanceProperties": [],
+ "visibility": "Public",
+ "summary": "The value of this attribute is always a number, or null.",
+ "description": "The value of this attribute is always a number, or null.\n\nSection: Database"
+ },
+ "AttributeObject": {
+ "name": "AttributeObject",
+ "superClass": "Attribute",
+ "filename": "docs_src/classes/temp-cjsx/attribute-object.js",
+ "srcUrl": null,
+ "sections": [],
+ "classMethods": [],
+ "instanceMethods": [],
+ "classProperties": [],
+ "instanceProperties": [],
+ "visibility": "Public",
+ "summary": "An object that can be cast to `itemClass`\nSection: Database",
+ "description": "An object that can be cast to `itemClass`\nSection: Database"
+ },
+ "AttributeServerId": {
+ "name": "AttributeServerId",
+ "superClass": "AttributeString",
+ "filename": "docs_src/classes/temp-cjsx/attribute-serverid.js",
+ "srcUrl": null,
+ "sections": [],
+ "classMethods": [],
+ "instanceMethods": [],
+ "classProperties": [],
+ "instanceProperties": [],
+ "visibility": "Public",
+ "summary": "The value of this attribute is always a string or `null`.",
+ "description": "The value of this attribute is always a string or `null`.\n\nString attributes can be queries using `equal`, `not`, and `startsWith`. Matching on\n`greaterThan` and `lessThan` is not supported.\n\nSection: Database"
+ },
+ "AttributeString": {
+ "name": "AttributeString",
+ "superClass": "Attribute",
+ "filename": "docs_src/classes/temp-cjsx/attribute-string.js",
+ "srcUrl": null,
+ "sections": [],
+ "classMethods": [],
+ "instanceMethods": [
+ {
+ "name": "startsWith",
+ "sectionName": null,
+ "srcUrl": null,
+ "visibility": "Public",
+ "summary": "",
+ "description": "",
+ "returnValues": [
+ {
+ "type": "Matcher",
+ "description": "Returns a {Matcher} for objects starting with the provided value."
+ }
+ ]
+ }
+ ],
+ "classProperties": [],
+ "instanceProperties": [],
+ "visibility": "Public",
+ "summary": "The value of this attribute is always a string or `null`.",
+ "description": "The value of this attribute is always a string or `null`.\n\nString attributes can be queries using `equal`, `not`, and `startsWith`. Matching on\n`greaterThan` and `lessThan` is not supported.\n\nSection: Database"
+ },
+ "BufferedProcess": {
+ "name": "BufferedProcess",
+ "filename": "buffered-process.coffee",
+ "srcUrl": null,
+ "sections": [
+ {
+ "name": "Construction",
+ "description": ""
+ },
+ {
+ "name": "Event Subscription",
+ "description": ""
+ },
+ {
+ "name": "Helper Methods",
+ "description": ""
+ }
+ ],
+ "classMethods": [],
+ "instanceMethods": [
+ {
+ "name": "constructor",
+ "sectionName": "Construction",
+ "srcUrl": null,
+ "visibility": "Public",
+ "summary": "Runs the given command by spawning a new child process.",
+ "description": "Runs the given command by spawning a new child process.",
+ "arguments": [
+ {
+ "children": [
+ {
+ "name": "command",
+ "description": "The {String} command to execute.",
+ "type": "String",
+ "isOptional": false
+ },
+ {
+ "name": "args",
+ "description": "The {Array} of arguments to pass to the command (optional).",
+ "type": "Array",
+ "isOptional": false
+ },
+ {
+ "name": "options",
+ "description": "{Object} (optional) The options {Object} to pass to Node's `ChildProcess.spawn` method.",
+ "type": "Object",
+ "isOptional": false
+ },
+ {
+ "children": [
+ {
+ "name": "data",
+ "description": "{String}",
+ "type": "String",
+ "isOptional": false
+ }
+ ],
+ "name": "stdout",
+ "description": "{Function} (optional) The callback that receives a single argument which contains the standard output from the command. The callback is called as data is received but it's buffered to ensure only complete lines are passed until the source stream closes. After the source stream has closed all remaining data is sent in a final call.",
+ "type": "Function",
+ "isOptional": false
+ },
+ {
+ "children": [
+ {
+ "name": "data",
+ "description": "{String}",
+ "type": "String",
+ "isOptional": false
+ }
+ ],
+ "name": "stderr",
+ "description": "{Function} (optional) The callback that receives a single argument which contains the standard error output from the command. The callback is called as data is received but it's buffered to ensure only complete lines are passed until the source stream closes. After the source stream has closed all remaining data is sent in a final call.",
+ "type": "Function",
+ "isOptional": false
+ },
+ {
+ "children": [
+ {
+ "name": "code",
+ "description": "{Number} ",
+ "type": "Number",
+ "isOptional": false
+ }
+ ],
+ "name": "exit",
+ "description": "{Function} (optional) The callback which receives a single argument containing the exit status.",
+ "type": "Function",
+ "isOptional": false
+ }
+ ],
+ "name": "options",
+ "description": "An {Object} with the following keys:",
+ "type": "Object",
+ "isOptional": false
+ }
+ ]
+ },
+ {
+ "name": "onWillThrowError",
+ "sectionName": "Event Subscription",
+ "srcUrl": null,
+ "visibility": "Public",
+ "summary": "Will call your callback when an error will be raised by the process.\nUsually this is due to the command not being available or not on the PATH.\nYou can call `handle()` on the object passed to your callback to indicate\nthat you have handled this error.",
+ "description": "Will call your callback when an error will be raised by the process.\nUsually this is due to the command not being available or not on the PATH.\nYou can call `handle()` on the object passed to your callback to indicate\nthat you have handled this error.",
+ "arguments": [
+ {
+ "children": [
+ {
+ "children": [
+ {
+ "name": "error",
+ "description": "{Object} the error object",
+ "type": "Object",
+ "isOptional": false
+ },
+ {
+ "name": "handle",
+ "description": "{Function} call this to indicate you have handled the error. The error will not be thrown if this function is called.",
+ "type": "Function",
+ "isOptional": false
+ }
+ ],
+ "name": "errorObject",
+ "description": "{Object}",
+ "type": "Object",
+ "isOptional": false
+ }
+ ],
+ "name": "callback",
+ "description": "{Function} callback",
+ "type": "Function",
+ "isOptional": false
+ }
+ ],
+ "returnValues": [
+ {
+ "type": "Disposable",
+ "description": "Returns a {Disposable}"
+ }
+ ]
+ },
+ {
+ "name": "kill",
+ "sectionName": "Helper Methods",
+ "srcUrl": null,
+ "visibility": "Public",
+ "summary": "Terminate the process. ",
+ "description": "Terminate the process. "
+ }
+ ],
+ "classProperties": [],
+ "instanceProperties": [],
+ "visibility": "Extended",
+ "summary": "A wrapper which provides standard error/output line buffering for\nNode's ChildProcess.",
+ "description": "A wrapper which provides standard error/output line buffering for\nNode's ChildProcess.",
+ "examples": [
+ {
+ "description": "",
+ "lang": "coffee",
+ "code": "{BufferedProcess} = require 'nylas-exports'\n\ncommand = 'ps'\nargs = ['-ef']\nstdout = (output) -> console.log(output)\nexit = (code) -> console.log(\"ps -ef exited with #{code}\")\nprocess = new BufferedProcess({command, args, stdout, exit})",
+ "raw": "```coffee\n{BufferedProcess} = require 'nylas-exports'\n\ncommand = 'ps'\nargs = ['-ef']\nstdout = (output) -> console.log(output)\nexit = (code) -> console.log(\"ps -ef exited with #{code}\")\nprocess = new BufferedProcess({command, args, stdout, exit})\n```"
+ }
+ ]
+ },
+ "ChangeFolderTask": {
+ "name": "ChangeFolderTask",
+ "superClass": "ChangeMailTask",
+ "filename": "docs_src/classes/temp-cjsx/change-folder-task.js",
+ "srcUrl": null,
+ "sections": [],
+ "classMethods": [],
+ "instanceMethods": [],
+ "classProperties": [],
+ "instanceProperties": [],
+ "visibility": "Public",
+ "summary": "Create a new task to apply labels to a message or thread.",
+ "description": "Create a new task to apply labels to a message or thread.\n\nTakes an options object of the form:\n\n* folder: The {Folder} or {Folder} IDs to move to\n* threads: An array of {Thread}s or {Thread} IDs\n* threads: An array of {Message}s or {Message} IDs\n* undoData: Since changing the folder is a destructive action,\n undo tasks need to store the configuration of what folders messages\n were in. When creating an undo task, we fill this parameter with\n that configuration"
+ },
+ "ChangeLabelsTask": {
+ "name": "ChangeLabelsTask",
+ "superClass": "ChangeMailTask",
+ "filename": "docs_src/classes/temp-cjsx/change-labels-task.js",
+ "srcUrl": null,
+ "sections": [],
+ "classMethods": [],
+ "instanceMethods": [],
+ "classProperties": [],
+ "instanceProperties": [],
+ "visibility": "Public",
+ "summary": "Create a new task to apply labels to a message or thread.",
+ "description": "Create a new task to apply labels to a message or thread.\n\nTakes an options object of the form:\n\n* labelsToAdd: An {Array} of {Category}s or {Category} ids to add\n* labelsToRemove: An {Array} of {Category}s or {Category} ids to remove\n* threads: An {Array} of {Thread}s or {Thread} ids\n* messages: An {Array} of {Message}s or {Message} ids"
+ },
+ "ChangeMailTask": {
+ "name": "ChangeMailTask",
+ "superClass": "Task",
+ "filename": "docs_src/classes/temp-cjsx/change-mail-task.js",
+ "srcUrl": null,
+ "sections": [],
+ "classMethods": [],
+ "instanceMethods": [
+ {
+ "name": "changesToModel",
+ "sectionName": null,
+ "srcUrl": null,
+ "visibility": "Public",
+ "summary": "Override this method and return an object with key-value pairs\nrepresenting changed values. For example, if (your task sets unread:)\nfalse, return {unread: false}.",
+ "description": "Override this method and return an object with key-value pairs\nrepresenting changed values. For example, if (your task sets unread:)\nfalse, return {unread: false}.",
+ "arguments": [
+ {
+ "name": "model",
+ "description": "an individual {Thread} or {Message}",
+ "type": "Thread",
+ "isOptional": false
+ }
+ ],
+ "returnValues": [
+ {
+ "type": null,
+ "description": "Returns an object whos key-value pairs represent the desired changed\nobject."
+ }
+ ]
+ },
+ {
+ "name": "requestBodyForModel",
+ "sectionName": null,
+ "srcUrl": null,
+ "visibility": "Public",
+ "summary": "Override this method and return an object that will be the\nrequest body used for saving changes to `model`.",
+ "description": "Override this method and return an object that will be the\nrequest body used for saving changes to `model`.",
+ "arguments": [
+ {
+ "name": "model",
+ "description": "an individual {Thread} or {Message}",
+ "type": "Thread",
+ "isOptional": false
+ }
+ ],
+ "returnValues": [
+ {
+ "type": null,
+ "description": "Returns an object that will be passed as the `body` to the actual API\n`request` object"
+ }
+ ]
+ },
+ {
+ "name": "processNestedMessages",
+ "sectionName": null,
+ "srcUrl": null,
+ "visibility": "Public",
+ "summary": "Override to indicate whether actions need to be taken for all\nmessages of each thread.",
+ "description": "Override to indicate whether actions need to be taken for all\nmessages of each thread.\n\nGenerally, you cannot provide both messages and threads at the same\ntime. However, ChangeMailTask runs for provided threads first and then\nmessages. Override and return true, and you will receive\n`changesToModel` for messages in changed threads, and any changes you\nmake will be written to the database and undone during undo.\n\nNote that API requests are only made for threads if (threads are)\npresent."
+ },
+ {
+ "name": "categoriesToAdd",
+ "sectionName": null,
+ "srcUrl": null,
+ "visibility": "Public",
+ "summary": "",
+ "description": "",
+ "returnValues": [
+ {
+ "type": null,
+ "description": "Returns categories that this task will add to the set of threads\nMust be overriden"
+ }
+ ]
+ },
+ {
+ "name": "categoriesToRemove",
+ "sectionName": null,
+ "srcUrl": null,
+ "visibility": "Public",
+ "summary": "",
+ "description": "",
+ "returnValues": [
+ {
+ "type": null,
+ "description": "Returns categories that this task will remove the set of threads\nMust be overriden"
+ }
+ ]
+ }
+ ],
+ "classProperties": [],
+ "instanceProperties": [],
+ "visibility": "Public",
+ "summary": "The ChangeMailTask is a base class for all tasks that modify sets\nof threads or messages.",
+ "description": "The ChangeMailTask is a base class for all tasks that modify sets\nof threads or messages.\n\nSubclasses implement {ChangeMailTask::changesToModel} and\n{ChangeMailTask::requestBodyForModel} to define the specific transforms\nthey provide, and override {ChangeMailTask::performLocal} to perform\nadditional consistency checks.\n\nChangeMailTask aims to be fast and efficient. It does not write changes to\nthe database or make API requests for models that are unmodified by\n{ChangeMailTask::changesToModel}\n\nChangeMailTask stores the previous values of all models it changes into\nthis._restoreValues and handles undo/redo. When undoing, it restores previous\nvalues and calls {ChangeMailTask::requestBodyForModel} to make undo API\nrequests. It does not call {ChangeMailTask::changesToModel}."
+ },
+ "Color": {
+ "name": "Color",
+ "filename": "color.coffee",
+ "srcUrl": null,
+ "sections": [],
+ "classMethods": [
+ {
+ "name": "parse",
+ "sectionName": null,
+ "srcUrl": null,
+ "visibility": "Essential",
+ "summary": "Parse a {String} or {Object} into a {Color}.",
+ "description": "Parse a {String} or {Object} into a {Color}.",
+ "arguments": [
+ {
+ "name": "value",
+ "description": "A {String} such as `'white'`, `#ff00ff`, or `'rgba(255, 15, 60, .75)'` or an {Object} with `red`, `green`, `blue`, and `alpha` properties.",
+ "type": "String",
+ "isOptional": false
+ }
+ ],
+ "returnValues": [
+ {
+ "type": "Color",
+ "description": "Returns a {Color} or `null` if it cannot be parsed."
+ }
+ ]
+ }
+ ],
+ "instanceMethods": [
+ {
+ "name": "toHexString",
+ "sectionName": null,
+ "srcUrl": null,
+ "visibility": "Essential",
+ "summary": "",
+ "description": "",
+ "returnValues": [
+ {
+ "type": "String",
+ "description": "Returns a {String} in the form `'#abcdef'`."
+ }
+ ]
+ },
+ {
+ "name": "toRGBAString",
+ "sectionName": null,
+ "srcUrl": null,
+ "visibility": "Essential",
+ "summary": "",
+ "description": "",
+ "returnValues": [
+ {
+ "type": "String",
+ "description": "Returns a {String} in the form `'rgba(25, 50, 75, .9)'`."
+ }
+ ]
+ }
+ ],
+ "classProperties": [],
+ "instanceProperties": [],
+ "visibility": "Essential",
+ "summary": "A simple color class returned from {Config::get} when the value\nat the key path is of type 'color'. ",
+ "description": "A simple color class returned from {Config::get} when the value\nat the key path is of type 'color'. "
+ },
+ "ComponentRegistry": {
+ "name": "ComponentRegistry",
+ "filename": "component-registry.coffee",
+ "srcUrl": null,
+ "sections": [],
+ "classMethods": [],
+ "instanceMethods": [
+ {
+ "name": "register",
+ "sectionName": null,
+ "srcUrl": null,
+ "visibility": "Public",
+ "summary": "Register a new component with the Component Registry.\nTypically, packages call this method from their main `activate` method\nto extend the Nylas user interface, and call the corresponding `unregister`\nmethod in `deactivate`.",
+ "description": "Register a new component with the Component Registry.\nTypically, packages call this method from their main `activate` method\nto extend the Nylas user interface, and call the corresponding `unregister`\nmethod in `deactivate`.\n\nThis method is chainable.",
+ "arguments": [
+ {
+ "name": "component",
+ "description": "{Object} A React Component with a `displayName`",
+ "type": "Object",
+ "isOptional": false
+ },
+ {
+ "children": [
+ {
+ "name": "role",
+ "description": "{String} If you want to display your component in a location desigated by a role, pass the role identifier.",
+ "type": "String",
+ "isOptional": true
+ },
+ {
+ "name": "modes",
+ "description": "{Array} If your component should only be displayed in particular Workspace Modes, pass an array of supported modes. ('list', 'split', etc.)",
+ "type": "Array",
+ "isOptional": true
+ },
+ {
+ "name": "location",
+ "description": "{Object} If your component should be displayed in a column or toolbar, pass the fully qualified location object, such as: `WorkspaceStore.Location.ThreadList`",
+ "type": "Object",
+ "isOptional": true
+ }
+ ],
+ "name": "options",
+ "description": "{Object}: Note that for advanced use cases, you can also pass (`modes`, `roles`, `locations`) with arrays instead of single values.",
+ "type": "Object",
+ "isOptional": false
+ }
+ ]
+ },
+ {
+ "name": "findComponentByName",
+ "sectionName": null,
+ "srcUrl": null,
+ "visibility": "Public",
+ "summary": "Retrieve the registry entry for a given name.",
+ "description": "Retrieve the registry entry for a given name.",
+ "arguments": [
+ {
+ "name": "name",
+ "description": "The {String} name of the registered component to retrieve.",
+ "type": "String",
+ "isOptional": false
+ }
+ ],
+ "returnValues": [
+ {
+ "type": "React.Component",
+ "description": "Returns a {React.Component}"
+ }
+ ]
+ },
+ {
+ "name": "findComponentsMatching",
+ "sectionName": null,
+ "srcUrl": null,
+ "visibility": "Public",
+ "summary": "Retrieve all of the registry entries matching a given descriptor.",
+ "description": "Retrieve all of the registry entries matching a given descriptor.\n\n```coffee\n ComponentRegistry.findComponentsMatching({\n role: 'Composer:ActionButton'\n })\n\n ComponentRegistry.findComponentsMatching({\n location: WorkspaceStore.Location.RootSidebar.Toolbar\n })\n```",
+ "arguments": [
+ {
+ "children": [
+ {
+ "name": "mode",
+ "description": "{String} Components that specifically list modes will only be returned if they include this mode.",
+ "type": "String",
+ "isOptional": true
+ },
+ {
+ "name": "role",
+ "description": "{String} Only return components that have registered for this role.",
+ "type": "String",
+ "isOptional": true
+ },
+ {
+ "name": "location",
+ "description": "{Object} Only return components that have registered for this location.",
+ "type": "Object",
+ "isOptional": true
+ }
+ ],
+ "name": "descriptor",
+ "description": "An {Object} that specifies set of components using the available keys below. Note that for advanced use cases, you can also pass (`modes`, `roles`, `locations`) with arrays instead of single values.",
+ "type": "Object",
+ "isOptional": false
+ }
+ ],
+ "returnValues": [
+ {
+ "type": "Array",
+ "description": "Returns an {Array} of {React.Component} objects"
+ }
+ ]
+ }
+ ],
+ "classProperties": [],
+ "instanceProperties": [],
+ "visibility": "Public",
+ "summary": "The ComponentRegistry maintains an index of React components registered\nby Nylas packages. Components can use {InjectedComponent} and {InjectedComponentSet}\nto dynamically render components registered with the ComponentRegistry.",
+ "description": "The ComponentRegistry maintains an index of React components registered\nby Nylas packages. Components can use {InjectedComponent} and {InjectedComponentSet}\nto dynamically render components registered with the ComponentRegistry.\n\nSection: Stores"
+ },
+ "ComposerExtension": {
+ "name": "ComposerExtension",
+ "superClass": "ContenteditableExtension",
+ "filename": "composer-extension.coffee",
+ "srcUrl": null,
+ "sections": [],
+ "classMethods": [
+ {
+ "name": "sendActions",
+ "sectionName": null,
+ "srcUrl": null,
+ "visibility": "Public",
+ "summary": "Allows the addition of new types of send actions such as \"Send\nLater\"",
+ "description": "Allows the addition of new types of send actions such as \"Send\nLater\"\n\nReturn an array of objects that adhere to the following spec. If the draft data\nindicates that your action should not be available, then return null.",
+ "arguments": [
+ {
+ "name": "title",
+ "description": "A short, single string that is displayed to users when describing your component. It is used in the hover title text of your option in the dropdown menu. It is also used in the \"Default Send Behavior\" dropdown setting. If your string is selected, then the `core.sending.defaultSendType` will be set to your string and your option will appear as the default.",
+ "type": null,
+ "isOptional": false
+ },
+ {
+ "name": "performSendAction",
+ "description": "Callback for when your option is clicked as the primary action. The function will be passed `{draft}` as its only argument. It does not need to return anything. It may be asynchronous and likely queue Tasks.",
+ "type": "draft",
+ "isOptional": false
+ },
+ {
+ "name": "isEnabled",
+ "description": "Callback to determine if this send action should be rendered for the given draft. Takes a draft: A fully populated {Message} object that is about to be sent.",
+ "type": "Message",
+ "isOptional": false
+ },
+ {
+ "name": "iconUrl",
+ "description": "A custom icon to be placed in the Send button. SendAction extensions have the form \"Send + {ICON}\"",
+ "type": "ICON",
+ "isOptional": false
+ }
+ ]
+ },
+ {
+ "name": "warningsForSending",
+ "sectionName": null,
+ "srcUrl": null,
+ "visibility": "Public",
+ "summary": "Inspect the draft, and return any warnings that need to be\ndisplayed before the draft is sent. Warnings should be string phrases,\nsuch as \"without an attachment\" that fit into a message of the form:\n\"Send #{phase1} and #{phase2}?\"",
+ "description": "Inspect the draft, and return any warnings that need to be\ndisplayed before the draft is sent. Warnings should be string phrases,\nsuch as \"without an attachment\" that fit into a message of the form:\n\"Send #{phase1} and #{phase2}?\"",
+ "arguments": [
+ {
+ "name": "draft",
+ "description": "A fully populated {Message} object that is about to be sent.",
+ "type": "Message",
+ "isOptional": false
+ }
+ ],
+ "returnValues": [
+ {
+ "type": null,
+ "description": "Returns a list of warning strings, or an empty array if no warnings need\nto be displayed."
+ }
+ ]
+ },
+ {
+ "name": "prepareNewDraft",
+ "sectionName": null,
+ "srcUrl": null,
+ "visibility": "Public",
+ "summary": "Override prepareNewDraft to modify a brand new draft before it\nis displayed in a composer. This is one of the only places in the\napplication where it's safe to modify the draft object you're given\ndirectly to add participants to the draft, add a signature, etc.",
+ "description": "Override prepareNewDraft to modify a brand new draft before it\nis displayed in a composer. This is one of the only places in the\napplication where it's safe to modify the draft object you're given\ndirectly to add participants to the draft, add a signature, etc.\n\nBy default, new drafts are considered `pristine`. If the user leaves the\ncomposer without making any changes, the draft is discarded. If your\nextension populates the draft in a way that makes it \"populated\" in a\nvaluable way, you should set `draft.pristine = false` so the draft\nsaves, even if no further changes are made."
+ },
+ {
+ "name": "applyTransformsForSending",
+ "sectionName": null,
+ "srcUrl": null,
+ "visibility": "Public",
+ "summary": "applyTransformsToDraft is called when a draft the user is editing\nis saved to the server and/or sent. This method gives you an opportunity to\nremove any annotations you've inserted into the draft body, apply final changes\nto the body, etc.",
+ "description": "applyTransformsToDraft is called when a draft the user is editing\nis saved to the server and/or sent. This method gives you an opportunity to\nremove any annotations you've inserted into the draft body, apply final changes\nto the body, etc.\n\nNote that your extension /must/ be able to reverse the changes it applies to\nthe draft in `applyTransformsToDraft`. If the user re-opens the draft,\n`unapplyTransformsToDraft` will be called and must restore the draft to it's\nprevious edit-ready state.\n\nExamples:\n\nThis method should return a modified {Message} object, or a {Promise} which resolves\nto a modified Message object.",
+ "arguments": [
+ {
+ "name": "draft",
+ "description": "A {Message} the user is about to finish editing.",
+ "type": "Message",
+ "isOptional": false
+ }
+ ]
+ },
+ {
+ "name": "unapplyTransformsForSending",
+ "sectionName": null,
+ "srcUrl": null,
+ "visibility": "Public",
+ "summary": "unapplyTransformsToDraft should revert the changes made in\n`applyTransformsToDraft`. See the documentation for that method for more\ninformation.",
+ "description": "unapplyTransformsToDraft should revert the changes made in\n`applyTransformsToDraft`. See the documentation for that method for more\ninformation."
+ }
+ ],
+ "instanceMethods": [],
+ "classProperties": [],
+ "instanceProperties": [],
+ "visibility": "Public",
+ "summary": "To create ComposerExtensions that enhance the composer experience,\nyou should create objects that implement the interface defined at\n{ComposerExtension}.",
+ "description": "To create ComposerExtensions that enhance the composer experience,\nyou should create objects that implement the interface defined at\n{ComposerExtension}.\n\n{ComposerExtension} extends {ContenteditableExtension}, so you can also\nimplement the methods defined there to further enhance the composer\nexperience.\n\nTo register your extension with the ExtensionRegistry, call\n{ExtensionRegistry::Composer::register}. When your package is being\nunloaded, you *must* call the corresponding\n{ExtensionRegistry::Composer::unregister} to unhook your extension.\n\n```\ncoffee activate: -> ExtensionRegistry.Composer.register(MyExtension)\n\n...\n\ndeactivate: -> ExtensionRegistry.Composer.unregister(MyExtension)\n```\n\n**Your ComposerExtension should be stateless**. The user may have multiple\ndrafts open at any time, and the methods of your ComposerExtension may be\ncalled for different drafts at any time. You should not expect that the\nsession you receive in {::applyTransformsToDraft} is for the same\ndraft you previously received in {::warningsForSending}, etc.\n\nThe ComposerExtension API does not currently expose any asynchronous or\n{Promise}-based APIs, except for applyTransformsToDraft and unapplyTransformsToDraft,\nwhich can optionally return a promsie. This will likely change in the future.\nIf you have a use-case for a ComposerExtension that is not possible with the current\nAPI, please let us know.\n\nSection: Extensions"
+ },
+ "Config": {
+ "name": "Config",
+ "filename": "config.coffee",
+ "srcUrl": null,
+ "sections": [
+ {
+ "name": "Config Subscription",
+ "description": ""
+ },
+ {
+ "name": "Managing Settings",
+ "description": ""
+ }
+ ],
+ "classMethods": [],
+ "instanceMethods": [
+ {
+ "name": "observe",
+ "sectionName": "Config Subscription",
+ "srcUrl": null,
+ "visibility": "Essential",
+ "summary": "Add a listener for changes to a given key path. This is different\nthan {::onDidChange} in that it will immediately call your callback with the\ncurrent value of the config entry.",
+ "description": "Add a listener for changes to a given key path. This is different\nthan {::onDidChange} in that it will immediately call your callback with the\ncurrent value of the config entry.\n\n### Examples\n\nYou might want to be notified when the themes change. We'll watch\n`core.themes` for changes\n\n```coffee\nNylasEnv.config.observe 'core.themes', (value) ->\n # do stuff with value\n```",
+ "arguments": [
+ {
+ "name": "keyPath",
+ "description": "{String} name of the key to observe",
+ "type": "String",
+ "isOptional": false
+ },
+ {
+ "children": [
+ {
+ "name": "value",
+ "description": "the new value of the key",
+ "type": null,
+ "isOptional": false
+ }
+ ],
+ "name": "callback",
+ "description": "{Function} to call when the value of the key changes.",
+ "type": "Function",
+ "isOptional": false
+ }
+ ],
+ "returnValues": [
+ {
+ "type": "Disposable",
+ "description": "Returns a {Disposable} with the following keys on which you can call\n`.dispose()` to unsubscribe."
+ }
+ ]
+ },
+ {
+ "name": "onDidChange",
+ "sectionName": "Config Subscription",
+ "srcUrl": null,
+ "visibility": "Essential",
+ "summary": "Add a listener for changes to a given key path. If `keyPath` is\nnot specified, your callback will be called on changes to any key.",
+ "description": "Add a listener for changes to a given key path. If `keyPath` is\nnot specified, your callback will be called on changes to any key.",
+ "arguments": [
+ {
+ "name": "keyPath",
+ "description": "{String} name of the key to observe.",
+ "type": "String",
+ "isOptional": true
+ },
+ {
+ "children": [
+ {
+ "children": [
+ {
+ "name": "newValue",
+ "description": "the new value of the key",
+ "type": null,
+ "isOptional": false
+ },
+ {
+ "name": "oldValue",
+ "description": "the prior value of the key.",
+ "type": null,
+ "isOptional": false
+ },
+ {
+ "name": "keyPath",
+ "description": "the keyPath of the changed key",
+ "type": null,
+ "isOptional": false
+ }
+ ],
+ "name": "event",
+ "description": "{Object}",
+ "type": "Object",
+ "isOptional": false
+ }
+ ],
+ "name": "callback",
+ "description": "{Function} to call when the value of the key changes.",
+ "type": "Function",
+ "isOptional": false
+ }
+ ],
+ "returnValues": [
+ {
+ "type": "Disposable",
+ "description": "Returns a {Disposable} with the following keys on which you can call\n`.dispose()` to unsubscribe."
+ }
+ ]
+ },
+ {
+ "name": "get",
+ "sectionName": "Managing Settings",
+ "srcUrl": null,
+ "visibility": "Essential",
+ "summary": "Retrieves the setting for the given key.",
+ "description": "Retrieves the setting for the given key.\n\n### Examples\n\nYou might want to know what themes are enabled, so check `core.themes`\n\n```coffee\nNylasEnv.config.get('core.themes')\n```",
+ "arguments": [
+ {
+ "name": "keyPath",
+ "description": "The {String} name of the key to retrieve.",
+ "type": "String",
+ "isOptional": false
+ }
+ ],
+ "returnValues": [
+ {
+ "type": null,
+ "description": "Returns the value from N1's default settings, the user's configuration\nfile in the type specified by the configuration schema."
+ }
+ ]
+ },
+ {
+ "name": "set",
+ "sectionName": "Managing Settings",
+ "srcUrl": null,
+ "visibility": "Essential",
+ "summary": "Sets the value for a configuration setting.",
+ "description": "Sets the value for a configuration setting.\n\nThis value is stored in N1's internal configuration file.\n\n### Examples\n\nYou might want to change the themes programmatically:\n\n```coffee\nNylasEnv.config.set('core.themes', ['ui-light', 'my-custom-theme'])\n```",
+ "arguments": [
+ {
+ "name": "keyPath",
+ "description": "The {String} name of the key.",
+ "type": "String",
+ "isOptional": false
+ },
+ {
+ "name": "value",
+ "description": "The value of the setting. Passing `undefined` will revert the setting to the default value.",
+ "type": null,
+ "isOptional": false
+ }
+ ],
+ "returnValues": [
+ {
+ "type": "Boolean",
+ "description": "Returns a {Boolean}\n\n* `true` if the value was set.\n* `false` if the value was not able to be coerced to the type specified in the setting's schema."
+ }
+ ]
+ },
+ {
+ "name": "unset",
+ "sectionName": "Managing Settings",
+ "srcUrl": null,
+ "visibility": "Essential",
+ "summary": "Restore the setting at `keyPath` to its default value.",
+ "description": "Restore the setting at `keyPath` to its default value.",
+ "arguments": [
+ {
+ "name": "keyPath",
+ "description": "The {String} name of the key.",
+ "type": "String",
+ "isOptional": false
+ },
+ {
+ "name": "options",
+ "description": "{Object} ",
+ "type": "Object",
+ "isOptional": true
+ }
+ ]
+ },
+ {
+ "name": "getSchema",
+ "sectionName": "Managing Settings",
+ "srcUrl": null,
+ "visibility": "Extended",
+ "summary": "Retrieve the schema for a specific key path. The schema will tell\nyou what type the keyPath expects, and other metadata about the config\noption.",
+ "description": "Retrieve the schema for a specific key path. The schema will tell\nyou what type the keyPath expects, and other metadata about the config\noption.",
+ "arguments": [
+ {
+ "name": "keyPath",
+ "description": "The {String} name of the key.",
+ "type": "String",
+ "isOptional": false
+ }
+ ],
+ "returnValues": [
+ {
+ "type": "Object",
+ "description": "Returns an {Object} eg. `{type: 'integer', default: 23, minimum: 1}`."
+ },
+ {
+ "type": null,
+ "description": "Returns `null` when the keyPath has no schema specified."
+ }
+ ]
+ },
+ {
+ "name": "transact",
+ "sectionName": "Managing Settings",
+ "srcUrl": null,
+ "visibility": "Extended",
+ "summary": "Suppress calls to handler functions registered with {::onDidChange}\nand {::observe} for the duration of `callback`. After `callback` executes,\nhandlers will be called once if the value for their key-path has changed.",
+ "description": "Suppress calls to handler functions registered with {::onDidChange}\nand {::observe} for the duration of `callback`. After `callback` executes,\nhandlers will be called once if the value for their key-path has changed.",
+ "arguments": [
+ {
+ "name": "callback",
+ "description": "{Function} to execute while suppressing calls to handlers. ",
+ "type": "Function",
+ "isOptional": false
+ }
+ ]
+ }
+ ],
+ "classProperties": [],
+ "instanceProperties": [],
+ "visibility": "Essential",
+ "summary": "Used to access all of N1's configuration details.",
+ "description": "Used to access all of N1's configuration details.\n\nAn instance of this class is always available as the `NylasEnv.config` global.\n\n## Getting and setting config settings.\n\n```coffee\n# Note that with no value set, ::get returns the setting's default value.\nNylasEnv.config.get('my-package.myKey') # -> 'defaultValue'\n\nNylasEnv.config.set('my-package.myKey', 'value')\nNylasEnv.config.get('my-package.myKey') # -> 'value'\n```\n\nYou may want to watch for changes. Use {::observe} to catch changes to the setting.\n\n```coffee\nNylasEnv.config.set('my-package.myKey', 'value')\nNylasEnv.config.observe 'my-package.myKey', (newValue) ->\n # `observe` calls immediately and every time the value is changed\n console.log 'My configuration changed:', newValue\n```\n\nIf you want a notification only when the value changes, use {::onDidChange}.\n\n```coffee\nNylasEnv.config.onDidChange 'my-package.myKey', ({newValue, oldValue}) ->\n console.log 'My configuration changed:', newValue, oldValue\n```\n\n### Value Coercion\n\nConfig settings each have a type specified by way of a\n[schema](json-schema.org). For example we might an integer setting that only\nallows integers greater than `0`:\n\n```coffee\n# When no value has been set, `::get` returns the setting's default value\nNylasEnv.config.get('my-package.anInt') # -> 12\n\n# The string will be coerced to the integer 123\nNylasEnv.config.set('my-package.anInt', '123')\nNylasEnv.config.get('my-package.anInt') # -> 123\n\n# The string will be coerced to an integer, but it must be greater than 0, so is set to 1\nNylasEnv.config.set('my-package.anInt', '-20')\nNylasEnv.config.get('my-package.anInt') # -> 1\n```\n\n## Defining settings for your package\n\nDefine a schema under a `config` key in your package main.\n\n```coffee\nmodule.exports =\n # Your config schema\n config:\n someInt:\n type: 'integer'\n default: 23\n minimum: 1\n\n activate: (state) -> # ...\n # ...\n```\n\n## Config Schemas\n\nWe use [json schema](http://json-schema.org) which allows you to define your value's\ndefault, the type it should be, etc. A simple example:\n\n```coffee\n# We want to provide an `enableThing`, and a `thingVolume`\nconfig:\n enableThing:\n type: 'boolean'\n default: false\n thingVolume:\n type: 'integer'\n default: 5\n minimum: 1\n maximum: 11\n```\n\nThe type keyword allows for type coercion and validation. If a `thingVolume` is\nset to a string `'10'`, it will be coerced into an integer.\n\n```coffee\nNylasEnv.config.set('my-package.thingVolume', '10')\nNylasEnv.config.get('my-package.thingVolume') # -> 10\n\n# It respects the min / max\nNylasEnv.config.set('my-package.thingVolume', '400')\nNylasEnv.config.get('my-package.thingVolume') # -> 11\n\n# If it cannot be coerced, the value will not be set\nNylasEnv.config.set('my-package.thingVolume', 'cats')\nNylasEnv.config.get('my-package.thingVolume') # -> 11\n```\n\n### Supported Types\n\nThe `type` keyword can be a string with any one of the following. You can also\nchain them by specifying multiple in an an array. For example\n\n```coffee\nconfig:\n someSetting:\n type: ['boolean', 'integer']\n default: 5\n\n# Then\nNylasEnv.config.set('my-package.someSetting', 'true')\nNylasEnv.config.get('my-package.someSetting') # -> true\n\nNylasEnv.config.set('my-package.someSetting', '12')\nNylasEnv.config.get('my-package.someSetting') # -> 12\n```\n\n#### string\n\nValues must be a string.\n\n```coffee\nconfig:\n someSetting:\n type: 'string'\n default: 'hello'\n```\n\n#### integer\n\nValues will be coerced into integer. Supports the (optional) `minimum` and\n`maximum` keys.\n\n```coffee\n config:\n someSetting:\n type: 'integer'\n default: 5\n minimum: 1\n maximum: 11\n```\n\n#### number\n\nValues will be coerced into a number, including real numbers. Supports the\n(optional) `minimum` and `maximum` keys.\n\n```coffee\nconfig:\n someSetting:\n type: 'number'\n default: 5.3\n minimum: 1.5\n maximum: 11.5\n```\n\n#### boolean\n\nValues will be coerced into a Boolean. `'true'` and `'false'` will be coerced into\na boolean. Numbers, arrays, objects, and anything else will not be coerced.\n\n```coffee\nconfig:\n someSetting:\n type: 'boolean'\n default: false\n```\n\n#### array\n\nValue must be an Array. The types of the values can be specified by a\nsubschema in the `items` key.\n\n```coffee\nconfig:\n someSetting:\n type: 'array'\n default: [1, 2, 3]\n items:\n type: 'integer'\n minimum: 1.5\n maximum: 11.5\n```\n\n#### object\n\nValue must be an object. This allows you to nest config options. Sub options\nmust be under a `properties key`\n\n```coffee\nconfig:\n someSetting:\n type: 'object'\n properties:\n myChildIntOption:\n type: 'integer'\n minimum: 1.5\n maximum: 11.5\n```\n\n#### color\n\nValues will be coerced into a {Color} with `red`, `green`, `blue`, and `alpha`\nproperties that all have numeric values. `red`, `green`, `blue` will be in\nthe range 0 to 255 and `value` will be in the range 0 to 1. Values can be any\nvalid CSS color format such as `#abc`, `#abcdef`, `white`,\n`rgb(50, 100, 150)`, and `rgba(25, 75, 125, .75)`.\n\n```coffee\nconfig:\n someSetting:\n type: 'color'\n default: 'white'\n```\n\n### Other Supported Keys\n\n#### enum\n\nAll types support an `enum` key. The enum key lets you specify all values\nthat the config setting can possibly be. `enum` _must_ be an array of values\nof your specified type. Schema:\n\n```coffee\nconfig:\n someSetting:\n type: 'integer'\n default: 4\n enum: [2, 4, 6, 8]\n```\n\nUsage:\n\n```coffee\nNylasEnv.config.set('my-package.someSetting', '2')\nNylasEnv.config.get('my-package.someSetting') # -> 2\n\n# will not set values outside of the enum values\nNylasEnv.config.set('my-package.someSetting', '3')\nNylasEnv.config.get('my-package.someSetting') # -> 2\n\n# If it cannot be coerced, the value will not be set\nNylasEnv.config.set('my-package.someSetting', '4')\nNylasEnv.config.get('my-package.someSetting') # -> 4\n```\n\n#### title and description\n\nThe settings view will use the `title` and `description` keys to display your\nconfig setting in a readable way. By default the settings view humanizes your\nconfig key, so `someSetting` becomes `Some Setting`. In some cases, this is\nconfusing for users, and a more descriptive title is useful.\n\nDescriptions will be displayed below the title in the settings view.\n\n```coffee\nconfig:\n someSetting:\n title: 'Setting Magnitude'\n description: 'This will affect the blah and the other blah'\n type: 'integer'\n default: 4\n```\n\n__Note__: You should strive to be so clear in your naming of the setting that\nyou do not need to specify a title or description!\n\n## Best practices\n\n* Don't depend on (or write to) configuration keys outside of your keypath."
+ },
+ "Contact": {
+ "name": "Contact",
+ "superClass": "Model",
+ "filename": "docs_src/classes/temp-cjsx/contact.js",
+ "srcUrl": null,
+ "sections": [],
+ "classMethods": [],
+ "instanceMethods": [
+ {
+ "name": "toString",
+ "sectionName": null,
+ "srcUrl": null,
+ "visibility": "Public",
+ "summary": "",
+ "description": "",
+ "returnValues": [
+ {
+ "type": null,
+ "description": "Returns a string of the format `Full Name ` if\nthe contact has a populated name, just the email address otherwise."
+ }
+ ]
+ },
+ {
+ "name": "isValid",
+ "sectionName": null,
+ "srcUrl": null,
+ "visibility": "Public",
+ "summary": "",
+ "description": "",
+ "returnValues": [
+ {
+ "type": "Contact",
+ "description": "Returns true if the contact provided is a {Contact} instance and\ncontains a properly formatted email address."
+ }
+ ]
+ },
+ {
+ "name": "isMe",
+ "sectionName": null,
+ "srcUrl": null,
+ "visibility": "Public",
+ "summary": "",
+ "description": "",
+ "returnValues": [
+ {
+ "type": null,
+ "description": "Returns true if the contact is the current user, false otherwise.\nYou should use this method instead of comparing the user's email address to\nthe account email, since it is case-insensitive and future-proof."
+ }
+ ]
+ }
+ ],
+ "classProperties": [],
+ "instanceProperties": [],
+ "visibility": "Public",
+ "summary": "The Contact model represents a Contact object served by the Nylas Platform API.\nFor more information about Contacts on the Nylas Platform, read the\n[Contacts API Documentation](https://nylas.com/cloud/docs#contacts)",
+ "description": "The Contact model represents a Contact object served by the Nylas Platform API.\nFor more information about Contacts on the Nylas Platform, read the\n[Contacts API Documentation](https://nylas.com/cloud/docs#contacts)\n\nAttributes\n\n`name`: {AttributeString} The name of the contact. Queryable.\n\n`email`: {AttributeString} The email address of the contact. Queryable.\n\n`thirdPartyData`: {AttributeObject} Extra data that we find out about a\ncontact. The data is keyed by the 3rd party service that dumped the data\nthere. The value is an object of raw data in the form that the service\nprovides\n\nWe also have \"normalized\" optional data for each contact. This list may\ngrow as the needs of a contact become more complex.\n\nThis class also inherits attributes from {Model}\n\nSection: Models"
+ },
+ "ContactStore": {
+ "name": "ContactStore",
+ "superClass": "NylasStore",
+ "filename": "contact-store.coffee",
+ "srcUrl": null,
+ "sections": [],
+ "classMethods": [],
+ "instanceMethods": [
+ {
+ "name": "searchContacts",
+ "sectionName": null,
+ "srcUrl": null,
+ "visibility": "Public",
+ "summary": "Search the user's contact list for the given search term.\nThis method compares the `search` string against each Contact's\n`name` and `email`.",
+ "description": "Search the user's contact list for the given search term.\nThis method compares the `search` string against each Contact's\n`name` and `email`.",
+ "arguments": [
+ {
+ "name": "search",
+ "description": "{String} A search phrase, such as `ben@n` or `Ben G`",
+ "type": "String",
+ "isOptional": false
+ },
+ {
+ "name": "options",
+ "description": "{Object} If you will only be displaying a few results, you should pass a limit value. {::searchContacts} will return as soon as `limit` matches have been found.",
+ "type": "Object",
+ "isOptional": true
+ }
+ ],
+ "returnValues": [
+ {
+ "type": "Array",
+ "description": "Returns an {Array} of matching {Contact} models"
+ }
+ ]
+ }
+ ],
+ "classProperties": [],
+ "instanceProperties": [],
+ "visibility": "Public",
+ "summary": "ContactStore provides convenience methods for searching contacts and\nformatting contacts. When Contacts become editable, this store will be expanded\nwith additional actions.",
+ "description": "ContactStore provides convenience methods for searching contacts and\nformatting contacts. When Contacts become editable, this store will be expanded\nwith additional actions.\n\nSection: Stores"
+ },
+ "Contenteditable": {
+ "name": "Contenteditable",
+ "superClass": "React",
+ "filename": "contenteditable.coffee",
+ "srcUrl": null,
+ "sections": [],
+ "classMethods": [],
+ "instanceMethods": [
+ {
+ "name": "atomicEdit",
+ "sectionName": null,
+ "srcUrl": null,
+ "visibility": "Public",
+ "summary": "perform an editing operation on the Contenteditable",
+ "description": "perform an editing operation on the Contenteditable\n\nIf the current selection at the time of running the extension is out of\nscope, it will be set to the last saved state. This ensures extensions\noperate on a valid {ExtendedSelection}.\n\nEdits made within the editing function will eventually fire _onDOMMutated",
+ "arguments": [
+ {
+ "name": "editingFunction",
+ "description": "A function to mutate the DOM and {ExtendedSelection}. It gets passed an {EditorAPI} object that contains mutating methods.",
+ "type": "ExtendedSelection",
+ "isOptional": false
+ }
+ ]
+ }
+ ],
+ "classProperties": [],
+ "instanceProperties": [],
+ "visibility": "Public",
+ "summary": "A modern React-compatible contenteditable",
+ "description": "A modern React-compatible contenteditable\n\nThis component is fully React-compatible and behaves\nlike a standard controlled input.\n\n```javascript\ngetInitialState: function() {\n return {value: 'Hello!'};\n},\nhandleChange: function(event) {\n this.setState({value: event.target.value});\n},\nrender: function() {\n var value = this.state.value;\n return ;\n}\n```"
+ },
+ "ContenteditableExtension": {
+ "name": "ContenteditableExtension",
+ "filename": "contenteditable-extension.coffee",
+ "srcUrl": null,
+ "sections": [],
+ "classMethods": [
+ {
+ "name": "onContentChanged",
+ "sectionName": null,
+ "srcUrl": null,
+ "visibility": "Public",
+ "summary": "Gets called anytime any atomic change is made to the DOM of the\ncontenteditable.",
+ "description": "Gets called anytime any atomic change is made to the DOM of the\ncontenteditable.\n\nWhen a user types a key, deletes some text, or does anything that\nchanges the DOM. it will trigger `onContentChanged`. It is wrapper over\na native DOM {MutationObserver}. It only gets called if there are\nmutations\n\nThis also gets called at the end of callbacks that mutate the DOM. If\nanother extension overrides `onClick` and performs several mutations to\nthe DOM during that callback, those changes will be batched and then\n`onContentChanged` will be called once at the end of the callback with\nthose mutations.\n\nCallback params:\n\n* editor: The {Editor} controller that provides a host of convenience\n methods for manipulating the selection and DOM\n* mutations: An array of DOM Mutations as returned by the\n {MutationObserver}. Note that these may not always be populated\n\nYou may mutate the contenteditable in place, we do not expect any return\nvalue from this method.\n\nThe onContentChanged event can be triggered by a variety of events, some\nof which could have been already been looked at by a callback. Any DOM\nmutation will fire this event. Sometimes those mutations are the cause\nof other callbacks.\n\nExample:\n\nThe Nylas `templates` package uses this method to see if the user has\npopulated a `` tag placed in the body and change it's CSS class to\nreflect that it is no longer empty.\n\n```coffee\nonContentChanged: ({editor, mutations}) ->\n isWithinNode = (node) ->\n test = selection.baseNode\n while test isnt editableNode\n return true if test is node\n test = test.parentNode\n return false\n\n codeTags = editableNode.querySelectorAll('code.var.empty')\n for codeTag in codeTags\n if selection.containsNode(codeTag) or isWithinNode(codeTag)\n codeTag.classList.remove('empty')\n```"
+ },
+ {
+ "name": "onBlur",
+ "sectionName": null,
+ "srcUrl": null,
+ "visibility": "Public",
+ "summary": "Override onBlur to mutate the contenteditable DOM node whenever the\nonBlur event is fired on it. You may mutate the contenteditable in place, we\nnot expect any return value from this method.",
+ "description": "Override onBlur to mutate the contenteditable DOM node whenever the\nonBlur event is fired on it. You may mutate the contenteditable in place, we\nnot expect any return value from this method.\n\n* editor: The {Editor} controller that provides a host of convenience\n methods for manipulating the selection and DOM\n* event: DOM event fired on the contenteditable"
+ },
+ {
+ "name": "onFocus",
+ "sectionName": null,
+ "srcUrl": null,
+ "visibility": "Public",
+ "summary": "Override onFocus to mutate the contenteditable DOM node whenever the\nonFocus event is fired on it. You may mutate the contenteditable in place, we\nnot expect any return value from this method.",
+ "description": "Override onFocus to mutate the contenteditable DOM node whenever the\nonFocus event is fired on it. You may mutate the contenteditable in place, we\nnot expect any return value from this method.\n\n* editor: The {Editor} controller that provides a host of convenience\n methods for manipulating the selection and DOM\n* event: DOM event fired on the contenteditable"
+ },
+ {
+ "name": "onClick",
+ "sectionName": null,
+ "srcUrl": null,
+ "visibility": "Public",
+ "summary": "Override onClick to mutate the contenteditable DOM node whenever the\nonClick event is fired on it. You may mutate the contenteditable in place, we\nnot expect any return value from this method.",
+ "description": "Override onClick to mutate the contenteditable DOM node whenever the\nonClick event is fired on it. You may mutate the contenteditable in place, we\nnot expect any return value from this method.\n\n* editor: The {Editor} controller that provides a host of convenience\n methods for manipulating the selection and DOM\n* event: DOM event fired on the contenteditable"
+ },
+ {
+ "name": "onKeyDown",
+ "sectionName": null,
+ "srcUrl": null,
+ "visibility": "Public",
+ "summary": "Override onKeyDown to mutate the contenteditable DOM node whenever the\nonKeyDown event is fired on it.\nPublic: Called when the user presses a key while focused on the contenteditable's body field.\nOverride onKeyDown in your ContenteditableExtension to adjust the selection or\nperform other actions.",
+ "description": "Override onKeyDown to mutate the contenteditable DOM node whenever the\nonKeyDown event is fired on it.\nPublic: Called when the user presses a key while focused on the contenteditable's body field.\nOverride onKeyDown in your ContenteditableExtension to adjust the selection or\nperform other actions.\n\nIf your package implements key down behavior for a particular scenario, you\nshould prevent the default behavior of the key via `event.preventDefault()`.\nYou may mutate the contenteditable in place, we not expect any return value\nfrom this method.\n\nImportant: You should prevent the default key down behavior with great care.\n\n* editor: The {Editor} controller that provides a host of convenience\n methods for manipulating the selection and DOM\n* event: DOM event fired on the contenteditable"
+ },
+ {
+ "name": "onShowContextMenu",
+ "sectionName": null,
+ "srcUrl": null,
+ "visibility": "Public",
+ "summary": "Override onShowContextMenu to add new menu items to the right click menu\ninside the contenteditable.",
+ "description": "Override onShowContextMenu to add new menu items to the right click menu\ninside the contenteditable.\n\n* editor: The {Editor} controller that provides a host of convenience\n methods for manipulating the selection and DOM\n* event: DOM event fired on the contenteditable\n* menu: [Menu](https://github.com/atom/electron/blob/master/docs/api/menu.md)\n object you can mutate in order to add new [MenuItems](https://github.com/atom/electron/blob/master/docs/api/menu-item.md)\n to the context menu that will be displayed when you right click the contenteditable."
+ },
+ {
+ "name": "keyCommandHandlers",
+ "sectionName": null,
+ "srcUrl": null,
+ "visibility": "Public",
+ "summary": "Override `keyCommandHandlers` to declaratively map keyboard\ncommands to callbacks.",
+ "description": "Override `keyCommandHandlers` to declaratively map keyboard\ncommands to callbacks.\n\nReturn an object keyed by the command name whose values are the\ncallbacks.\n\nCallbacks are automatically bound to the Contenteditable context and\npassed `({editor, event})` as its argument.\n\nNew commands are defined in keymap.cson files."
+ },
+ {
+ "name": "toolbarButtons",
+ "sectionName": null,
+ "srcUrl": null,
+ "visibility": "Public",
+ "summary": "Override `toolbarButtons` to declaratively add your own button\nto the composer's toolbar.",
+ "description": "Override `toolbarButtons` to declaratively add your own button\nto the composer's toolbar.\n\n* toolbarState: The current state of the Toolbar and Composer. This is\n Read only.\n\nMust return an array of objects obeying the following spec:\n\n* className: A string class name\n* onClick: Callback to fire when your button is clicked. The callback\n is automatically bound to the editor and will get passed an single\n object with the following args.\n * editor - The {Editor} controller for manipulating the DOM\n * event - The click Event object\n* tooltip: A string to display when users hover over your button\n* iconUrl: A url for the icon."
+ },
+ {
+ "name": "toolbarComponentConfig",
+ "sectionName": null,
+ "srcUrl": null,
+ "visibility": "Public",
+ "summary": "Override `toolbarComponentConfig` to declaratively show your own\ntoolbar when certain conditions are met.",
+ "description": "Override `toolbarComponentConfig` to declaratively show your own\ntoolbar when certain conditions are met.\n\nIf you want to hide your toolbar component, return null.\n\nIf you want to display your toolbar, then return an object with the\nsignature indicated below.\n\nThis methods gets called anytime the `toolbarState` changes. Since\n`toolbarState` includes the current value of the Selection and any\nobjects a user is hovering over, you should expect it to change very\nfrequently.\n\n* toolbarState: The current state of the Toolbar and Composer. This is\n Read only.\n * dragging\n * doubleDown\n * hoveringOver\n * editableNode\n * exportedSelection\n * extensions\n * atomicEdit\n\nMust return an object with the following signature\n\n* component: A React component or null.\n* props: Props to be passed into your custom Component\n* locationRefNode: Anything (usually a DOM Node) that responds to\n `getBoundingClientRect`. This is used to determine where to display\n your component.\n* width: The width of your component. This is necessary because when\n your component is displayed in the {FloatingToolbar}, the position is\n pre-computed based on the absolute width of the item.\n* height: The height of your component. This is necessary for the same\n reason listed above; the position of the toolbar will be determined\n by the absolute height given."
+ }
+ ],
+ "instanceMethods": [],
+ "classProperties": [],
+ "instanceProperties": [],
+ "visibility": "Public",
+ "summary": "ContenteditableExtension is an abstract base class.\nImplementations of this are used to make additional changes to a",
+ "description": "ContenteditableExtension is an abstract base class.\nImplementations of this are used to make additional changes to a\n\n component beyond a user's input intents. The hooks in\nthis class provide the contenteditable DOM Node itself, allowing you to\nadjust selection ranges and change content as necessary.\n\nWhile some ContenteditableExtension are included with the core\n<{Contenteditable} /> component, others may be added via the `plugins`\nprop when you use it inside your own components.\n\nExample:\n\n```javascript\nrender() {\n return(\n
\n \n
\n );\n}\n```\n\nIf you specifically want to enhance the Composer experience you should\nregister a {ComposerExtension}\n\nSection: Extensions"
+ },
+ "DatabaseStore": {
+ "name": "DatabaseStore",
+ "superClass": "NylasStore",
+ "filename": "docs_src/classes/temp-cjsx/database-store.js",
+ "srcUrl": null,
+ "sections": [],
+ "classMethods": [],
+ "instanceMethods": [
+ {
+ "name": "find",
+ "sectionName": null,
+ "srcUrl": null,
+ "visibility": "Public",
+ "summary": "Creates a new Model Query for retrieving a single model specified by\nthe class and id.",
+ "description": "Creates a new Model Query for retrieving a single model specified by\nthe class and id.\n\n* \\`class\\` The class of the {Model} you're trying to retrieve.\n* \\`id\\` The {String} id of the {Model} you're trying to retrieve\n\nExample:\n\n```coffee\nDatabaseStore.find(Thread, 'id-123').then (thread) ->\n// thread is a Thread object, or null if no match was found.\n```",
+ "returnValues": [
+ {
+ "type": "Query",
+ "description": "Returns a {Query}"
+ }
+ ]
+ },
+ {
+ "name": "findBy",
+ "sectionName": null,
+ "srcUrl": null,
+ "visibility": "Public",
+ "summary": "Creates a new Model Query for retrieving a single model matching the\npredicates provided.",
+ "description": "Creates a new Model Query for retrieving a single model matching the\npredicates provided.\n\n* \\`class\\` The class of the {Model} you're trying to retrieve.\n* \\`predicates\\` An {Array} of {matcher} objects. The set of predicates the\n returned model must match.",
+ "returnValues": [
+ {
+ "type": "Query",
+ "description": "Returns a {Query}"
+ }
+ ]
+ },
+ {
+ "name": "findAll",
+ "sectionName": null,
+ "srcUrl": null,
+ "visibility": "Public",
+ "summary": "Creates a new Model Query for retrieving all models matching the\npredicates provided.",
+ "description": "Creates a new Model Query for retrieving all models matching the\npredicates provided.\n\n* \\`class\\` The class of the {Model} you're trying to retrieve.\n* \\`predicates\\` An {Array} of {matcher} objects. The set of predicates the\n returned model must match.",
+ "returnValues": [
+ {
+ "type": "Query",
+ "description": "Returns a {Query}"
+ }
+ ]
+ },
+ {
+ "name": "count",
+ "sectionName": null,
+ "srcUrl": null,
+ "visibility": "Public",
+ "summary": "Creates a new Model Query that returns the {Number} of models matching\nthe predicates provided.",
+ "description": "Creates a new Model Query that returns the {Number} of models matching\nthe predicates provided.\n\n* \\`class\\` The class of the {Model} you're trying to retrieve.\n* \\`predicates\\` An {Array} of {matcher} objects. The set of predicates the\n returned model must match.",
+ "returnValues": [
+ {
+ "type": "Query",
+ "description": "Returns a {Query}"
+ }
+ ]
+ },
+ {
+ "name": "modelify",
+ "sectionName": null,
+ "srcUrl": null,
+ "visibility": "Public",
+ "summary": "Modelify converts the provided array of IDs or models (or a mix of\nIDs and models) into an array of models of the \\`klass\\` provided by querying for the missing items.",
+ "description": "Modelify converts the provided array of IDs or models (or a mix of\nIDs and models) into an array of models of the \\`klass\\` provided by querying for the missing items.\n\nModelify is efficient and uses a single database query. It resolves Immediately\nif no query is necessary.\n\n* \\`class\\` The {Model} class desired.\n* 'arr' An {Array} with a mix of string model IDs and/or models."
+ },
+ {
+ "name": "run",
+ "sectionName": null,
+ "srcUrl": null,
+ "visibility": "Public",
+ "summary": "Executes a {Query} on the local database.",
+ "description": "Executes a {Query} on the local database.\n\n* \\`modelQuery\\` A {Query} to execute.",
+ "returnValues": [
+ {
+ "type": "Promise",
+ "description": "Returns a {Promise} that\n\n* resolves with the result of the database query."
+ }
+ ]
+ },
+ {
+ "name": "inTransaction",
+ "sectionName": null,
+ "srcUrl": null,
+ "visibility": "Public",
+ "summary": "Opens a new database transaction for writing changes.\nDatabaseStore.inTransacion makes the following guarantees:",
+ "description": "Opens a new database transaction for writing changes.\nDatabaseStore.inTransacion makes the following guarantees:\n\n* No other calls to \\`inTransaction\\` will run until the promise has finished.\n* No other process will be able to write to sqlite while the provided function\n is running. `BEGIN IMMEDIATE TRANSACTION` semantics are:\n* No other connection will be able to write any changes.\n* Other connections can read from the database, but they will not see\n pending changes.",
+ "returnValues": [
+ {
+ "type": "function",
+ "description": "this.param fn {function} callback that will be executed inside a database transaction"
+ },
+ {
+ "type": "Promise",
+ "description": "Returns a {Promise} that resolves when the transaction has successfully\ncompleted."
+ }
+ ]
+ }
+ ],
+ "classProperties": [],
+ "instanceProperties": [],
+ "visibility": "Public",
+ "summary": "N1 is built on top of a custom database layer modeled after\nActiveRecord. For many parts of the application, the database is the source\nof truth. Data is retrieved from the API, written to the database, and changes\nto the database trigger Stores and components to refresh their contents.",
+ "description": "N1 is built on top of a custom database layer modeled after\nActiveRecord. For many parts of the application, the database is the source\nof truth. Data is retrieved from the API, written to the database, and changes\nto the database trigger Stores and components to refresh their contents.\n\nThe DatabaseStore is available in every application window and allows you to\nmake queries against the local cache. Every change to the local cache is\nbroadcast as a change event, and listening to the DatabaseStore keeps the\nrest of the application in sync.\n\n#// Listening for Changes\n\nTo listen for changes to the local cache, subscribe to the DatabaseStore and\ninspect the changes that are sent to your listener method.\n\n```coffeescript\nthis.unsubscribe = DatabaseStore.listen(this._onDataChanged, this.)\n\n...\n\n_onDataChanged: (change) ->\n return unless change.objectClass is Message\n return unless this._myMessageID in _.map change.objects, (m) -> m.id\n\n // Refresh Data\n```\n\nThe local cache changes very frequently, and your stores and components should\ncarefully choose when to refresh their data. The \\`change\\` object passed to your\nevent handler allows you to decide whether to refresh your data and exposes\nthe following keys:\n\n\\`objectClass\\`: The {Model} class that has been changed. If multiple types of models\nwere saved to the database, you will receive multiple change events.\n\n\\`objects\\`: An {Array} of {Model} instances that were either created, updated or\ndeleted from the local cache. If your component or store presents a single object\nor a small collection of objects, you should look to see if any of the objects\nare in your displayed set before refreshing.\n\nSection: Database"
+ },
+ "DraftChangeSet": {
+ "name": "DraftChangeSet",
+ "filename": "draft-editing-session.coffee",
+ "srcUrl": null,
+ "sections": [],
+ "classMethods": [],
+ "instanceMethods": [],
+ "classProperties": [],
+ "instanceProperties": [],
+ "visibility": "Public",
+ "summary": "As the user interacts with the draft, changes are accumulated in the\nDraftChangeSet associated with the store session. The DraftChangeSet does two things:",
+ "description": "As the user interacts with the draft, changes are accumulated in the\nDraftChangeSet associated with the store session. The DraftChangeSet does two things:\n\n1. It debounces changes and calls Actions.saveDraft() at a reasonable interval.\n1. It exposes `applyToModel`, which allows you to optimistically apply changes\n to a draft object. When the session vends the draft, it passes it through this\n function to apply uncommitted changes. This means the Draft provided by the\n DraftEditingSession will always relfect recent changes, even though they're\n written to the database intermittently.\n\nSection: Drafts"
+ },
+ "DraftEditingSession": {
+ "name": "DraftEditingSession",
+ "filename": "draft-editing-session.coffee",
+ "srcUrl": null,
+ "sections": [],
+ "classMethods": [],
+ "instanceMethods": [
+ {
+ "name": "draft",
+ "sectionName": null,
+ "srcUrl": null,
+ "visibility": "Public",
+ "summary": "",
+ "description": "",
+ "returnValues": [
+ {
+ "type": null,
+ "description": "Returns the draft object with the latest changes applied."
+ }
+ ]
+ },
+ {
+ "name": "draftPristineBody",
+ "sectionName": null,
+ "srcUrl": null,
+ "visibility": "Public",
+ "summary": "",
+ "description": "",
+ "returnValues": [
+ {
+ "type": null,
+ "description": "Returns the initial body of the draft when it was pristine, or null if the\ndraft was never pristine in this editing session. Useful for determining if the\nbody is still in an unchanged / empty state."
+ }
+ ]
+ }
+ ],
+ "classProperties": [],
+ "instanceProperties": [],
+ "visibility": "Public",
+ "summary": "DraftEditingSession is a small class that makes it easy to implement components\nthat display Draft objects or allow for interactive editing of Drafts.",
+ "description": "DraftEditingSession is a small class that makes it easy to implement components\nthat display Draft objects or allow for interactive editing of Drafts.\n\n1. It synchronously provides an instance of a draft via `draft()`, and\n triggers whenever that draft instance has changed.\n1. It provides an interface for modifying the draft that transparently\n batches changes, and ensures that the draft provided via `draft()`\n always has pending changes applied.\n\nSection: Drafts"
+ },
+ "DraftStore": {
+ "name": "DraftStore",
+ "superClass": "NylasStore",
+ "filename": "docs_src/classes/temp-cjsx/draft-store.js",
+ "srcUrl": null,
+ "sections": [],
+ "classMethods": [],
+ "instanceMethods": [
+ {
+ "name": "isSendingDraft",
+ "sectionName": null,
+ "srcUrl": null,
+ "visibility": "Public",
+ "summary": "Look up the sending state of the given draftClientId.\nIn popout windows the existance of the window is the sending state.",
+ "description": "Look up the sending state of the given draftClientId.\nIn popout windows the existance of the window is the sending state."
+ }
+ ],
+ "classProperties": [],
+ "instanceProperties": [],
+ "visibility": "Public",
+ "summary": "DraftStore responds to Actions that interact with Drafts and exposes\npublic getter methods to return Draft objects and sessions.",
+ "description": "DraftStore responds to Actions that interact with Drafts and exposes\npublic getter methods to return Draft objects and sessions.\n\nIt also creates and queues {Task} objects to persist changes to the Nylas\nAPI.\n\nRemember that a \"Draft\" is actually just a \"Message\" with `draft: true`.\n\nSection: Drafts"
+ },
+ "DraftStoreExtension": {
+ "name": "DraftStoreExtension",
+ "filename": "draft-store-extension.coffee",
+ "srcUrl": null,
+ "sections": [],
+ "classMethods": [],
+ "instanceMethods": [],
+ "classProperties": [],
+ "instanceProperties": [],
+ "visibility": "Public",
+ "summary": "DraftStoreExtension is deprecated. Use {ComposerExtension} instead.\nSection: Extensions",
+ "description": "DraftStoreExtension is deprecated. Use {ComposerExtension} instead.\nSection: Extensions"
+ },
+ "EventedIFrame": {
+ "name": "EventedIFrame",
+ "superClass": "React",
+ "filename": "evented-iframe.coffee",
+ "srcUrl": null,
+ "sections": [],
+ "classMethods": [],
+ "instanceMethods": [
+ {
+ "name": "didReplaceDocument",
+ "sectionName": null,
+ "srcUrl": null,
+ "visibility": "Public",
+ "summary": "Call this method if you replace the contents of the iframe's document.\nThis allows {EventedIframe} to re-attach it's event listeners.",
+ "description": "Call this method if you replace the contents of the iframe's document.\nThis allows {EventedIframe} to re-attach it's event listeners."
+ }
+ ],
+ "classProperties": [],
+ "instanceProperties": [],
+ "visibility": "Public",
+ "summary": "EventedIFrame is a thin wrapper around the DOM's standard `