Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Configurable Note plugin #43

Open
wants to merge 4 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 11 additions & 6 deletions cnx/aloha-config.coffee
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
@Aloha.settings =
jQuery: @jQuery # Use the same version of jQuery
logLevels:
error: true
error: false
warn: true
info: false
debug: false
Expand Down Expand Up @@ -47,11 +47,16 @@
'oer/note'
]

note:
types:
'note': true
'noteish': true
'noteish-notitle': false
note: [
{ label: 'Note', cls: 'note', hasTitle: true }
{ label: 'Aside', cls: 'note', hasTitle: true, type: 'aside' }
{ label: 'Warning', cls: 'note', hasTitle: true, type: 'warning' }
{ label: 'Tip', cls: 'note', hasTitle: true, type: 'tip' }
{ label: 'Important', cls: 'note', hasTitle: true, type: 'important' }

{ label: 'Noteish', cls: 'noteish', hasTitle: true }
{ label: 'Noteish (no Title)', cls: 'noteish-notitle', hasTitle: false }
]

# This whole thing is what's needed to:
#
Expand Down
44 changes: 36 additions & 8 deletions cnx/aloha-config.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

103 changes: 82 additions & 21 deletions src/plugins/oer/note/lib/note-plugin.coffee
Original file line number Diff line number Diff line change
Expand Up @@ -8,41 +8,71 @@ define [
'semanticblock/semanticblock-plugin'
'css!note/css/note-plugin.css'], (Aloha, Plugin, jQuery, Ephemera, UI, Button, semanticBlock) ->

TITLE_CONTAINER = '''
TITLE_CONTAINER = jQuery('''
<div class="type-container dropdown">
<a class="type" data-toggle="dropdown"></a>
<span class="title" placeholder="Add a title (optional)"></span>
<ul class="dropdown-menu">
<li><a href="">Note</a></li>
<li><a href="">Aside</a></li>
<li><a href="">Warning</a></li>
<li><a href="">Tip</a></li>
<li><a href="">Important</a></li>
</ul>
</div>
'''
''')

# Find all classes that could mean something is "notish"
# so they can be removed when the type is changed from the dropdown.
notishClasses = {}

Plugin.create 'note',
# Default Settings
# -------
# The plugin can listen to various classes that should "behave" like a note.
# For each notish element provide a:
# - `label`: **Required** Shows up in dropdown
# - `cls` : **Required** The classname to enable this plugin on
# - `hasTitle`: **Required** `true` if the element allows optional titles
# - `type`: value in the `data-type` attribute.
# - `tagName`: Default: `div`. The HTML element name to use when creating a new note
# - `titleTagName`: Default: `div`. The HTML element name to use when creating a new title
#
# For example, a Warning could look like this:
#
# { label:'Warning', cls:'note', hasTitle:false, type:'warning'}
#
# Then, when the user selects "Warning" from the dropdown the element's
# class and type will be changed and its `> .title` will be removed.
defaults: [
{ label: 'Note', cls: 'note', hasTitle: true }
]
init: () ->
# Load up specific classes to listen to or use the default
types = @settings.types or {note: true}
jQuery.map types, (hasTitle, className) ->

# These 2 variables should be moved into the config so other note-ish classes
# can define what the element name is that is generated for the note and
types = @settings
jQuery.each types, (i, type) =>
className = type.cls or throw 'BUG Invalid configuration of not plugin. cls required!'
typeName = type.type
hasTitle = !!type.hasTitle
label = type.label or throw 'BUG Invalid configuration of not plugin. label required!'

# These 2 variables allow other note-ish classes
# to define what the element name is that is generated for the note and
# for the title.
#
# Maybe they could eventually be functions so titles for inline notes generate
# a `span` instead of a `div` for example.
tagName = 'div'
titleTagName = 'div'
tagName = type.tagName or 'div'
titleTagName = type.titleTagName or 'div'

selector = ".#{className}:not([data-type])"
selector = ".#{className}[data-type='#{typeName}']" if typeName

notishClasses[className] = true


newTemplate = jQuery("<#{tagName}></#{tagName}")
newTemplate.addClass(className)
newTemplate.attr('data-type', className)
newTemplate.attr('data-type', typeName) if typeName
if hasTitle
newTemplate.append("<#{titleTagName} class='title'></#{titleTagName}")

semanticBlock.activateHandler(className, (element) ->
semanticBlock.activateHandler(selector, (element) =>
if hasTitle
titleElement = element.children('.title')

Expand All @@ -58,9 +88,40 @@ define [
element.children().remove()

if hasTitle
titleContainer = jQuery(TITLE_CONTAINER)
titleContainer = TITLE_CONTAINER.clone()
# Add dropdown elements for each possible type
jQuery.each @settings, (i, foo) =>
$option = jQuery('<li><a href=""></a></li>')
$option.appendTo(titleContainer.find('.dropdown-menu'))
$option = $option.children('a')
$option.text(foo.label)
$option.on 'click', =>
# Remove the title if this type does not have one
# The title was moved into `.type-container` for some reason
if foo.hasTitle
# If there is no `.title` element then add one in and enable it as an Aloha block
if not element.find('> .type-container > .title')[0]
$newTitle = jQuery("<#{foo.titleTagName or 'span'} class='title'></#{foo.titleTagName or 'span'}")
element.children('.type-container').append($newTitle)
$newTitle.aloha()

else
element.find('> .type-container > .title').remove()

# Remove the `data-type` if this type does not have one
if foo.type
element.attr('data-type', foo.type)
else
element.removeAttr('data-type')

# Remove all notish class names and then add this one in
for key of notishClasses
element.removeClass key
element.addClass(foo.cls)


titleContainer.find('.title').text(title)
titleContainer.find('.type').text(type.charAt(0).toUpperCase() + type.slice(1) )
titleContainer.find('.type').text(label)
titleContainer.prependTo(element)
titleContainer.children('.title').aloha()

Expand All @@ -71,7 +132,7 @@ define [
.appendTo(element)
.aloha()
)
semanticBlock.deactivateHandler(className, (element) ->
semanticBlock.deactivateHandler(selector, (element) ->
bodyElement = element.children('.body')
body = bodyElement.children()

Expand All @@ -93,10 +154,10 @@ define [
element.append(body)
)
# Add a listener
UI.adopt "insert-#{className}", Button,
UI.adopt "insert-#{className}#{typeName}", Button,
click: -> semanticBlock.insertAtCursor(newTemplate.clone())

# For legacy toolbars listen to 'insertNote'
if 'note' == className
if 'note' == className and not typeName
UI.adopt "insertNote", Button,
click: -> semanticBlock.insertAtCursor(newTemplate.clone())
86 changes: 68 additions & 18 deletions src/plugins/oer/note/lib/note-plugin.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading