Last active
May 27, 2016 21:16
-
-
Save ryanschuhler/732cde43b461e36c5245ee028fc95db0 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<#assign layout_service = serviceLocator.findService("com.liferay.portal.service.LayoutLocalService") /> | |
<#assign theme_display = request["theme-display"] /> | |
<#assign plid = theme_display["plid"] /> | |
<#assign layout = layout_service.getLayout(plid?number) /> | |
<div class="lego-article ${article_class.data}" id="article-${.vars['reserved-article-id'].data}"> | |
<#list section.siblings as cur_section> | |
<section class="block-container lego-section section-${cur_section_index + 1} ${cur_section.section_class.data}" ${cur_section.data}> | |
<#list cur_section.block.siblings as cur_block> | |
<div class="block block-${cur_block_index + 1} content-column lego-block w${cur_block.width.data} ${cur_block.block_class.data}" ${cur_block.data}> | |
<#list cur_block.element.siblings as cur_element> | |
<#assign cur_element_tag = cur_element.tag.data> | |
<#if !cur_element_tag?has_content> | |
<#assign cur_element_tag = "div"> | |
</#if> | |
<${cur_element_tag} | |
<#assign cur_element_css_class = "lego-element " + cur_element.element_class.data /> | |
<#assign button_attrs = cur_element.data /> | |
<#if layoutPermission.contains(permissionChecker, layout, "UPDATE")> | |
<#assign cur_element_css_class = cur_element_css_class + " live-edit" /> | |
<#assign button_attrs = button_attrs + " | |
data-article-id='${.vars[\"reserved-article-id\"].data}' | |
data-level-path='${cur_section.name}::${cur_section_index},${cur_block.name}::${cur_block_index},${cur_element.name}::${cur_element_index},${cur_element.content.name}::0' | |
" /> | |
</#if> | |
class="${cur_element_css_class}" | |
${button_attrs} | |
> | |
${cur_element.content.data} | |
</${cur_element_tag}> | |
</#list> | |
<#if cur_block.article_id?? && cur_block.article_id.data?has_content> | |
<#list cur_block.article_id.siblings as article_id> | |
<#if article_id.data?has_content> | |
<runtime-portlet name="56" instance="${article_id.data}" /> | |
</#if> | |
</#list> | |
</#if> | |
</div> | |
</#list> | |
</section> | |
</#list> | |
</div> | |
<#if css.data?has_content> | |
<style type="text/css"> | |
${css.data} | |
</style> | |
</#if> | |
<#if javascript?? && javascript.data?has_content> | |
<script type="text/javascript"> | |
${javascript.data} | |
</script> | |
</#if> | |
<script type="text/javascript"> | |
AUI().ready( | |
'aui-io-request', | |
'datatype-xml', | |
'liferay-portlet-url', | |
function(A) { | |
if (typeof ranCode !== 'undefined') { | |
return; | |
} | |
window.ranCode = true; | |
var addInfo = function(node) { | |
var articleId = node.attr('data-article-id'); | |
var levelPath = node.attr('data-level-path'); | |
var content = node.getContent(); | |
if ((content == '') || (node._initialContent.trim() == content.trim())) { | |
clearField(node, true); | |
return; | |
} | |
if (!liveEditInfo[articleId]) { | |
liveEditInfo[articleId] = {}; | |
} | |
liveEditInfo[articleId][levelPath] = content; | |
clearControls(); | |
liveEditControls.addClass('edits-pending'); | |
node.addClass('live-edited'); | |
}; | |
var clearControls = function() { | |
liveEditControls.removeClass('edits-pending'); | |
liveEditControls.removeClass('update-failure'); | |
liveEditControls.removeClass('update-sending'); | |
liveEditControls.removeClass('update-success'); | |
}; | |
var clearField = function(node, reset) { | |
var articleId = node.attr('data-article-id'); | |
var levelPath = node.attr('data-level-path'); | |
if (liveEditInfo[articleId] && liveEditInfo[articleId][levelPath]) { | |
delete liveEditInfo[articleId][levelPath]; | |
if (Object.keys(liveEditInfo[articleId]).length == 0) { | |
delete liveEditInfo[articleId]; | |
} | |
if (Object.keys(liveEditInfo).length == 0) { | |
clearControls(); | |
} | |
} | |
node.removeClass('live-edited'); | |
if (reset) { | |
node.setContent(node._initialContent); | |
} | |
}; | |
var clearFields = function(reset) { | |
A.all('.live-edited').each( | |
function(node) { | |
clearField(node, reset); | |
} | |
); | |
}; | |
var getArticle = function(groupId, articleId, updates) { | |
Liferay.Service( | |
'/journalarticle/get-article', | |
{ | |
articleId: articleId, | |
groupId: groupId, | |
status: -1 | |
}, | |
function(obj) { | |
var exception = obj.exception; | |
if (!exception) { | |
sendUpdate(obj, updates); | |
} | |
else { | |
liveEditControls.addClass('update-failure'); | |
} | |
} | |
); | |
}; | |
var sendUpdate = function(article, updates) { | |
if (!article) { | |
liveEditControls.addClass('update-failure'); | |
return; | |
} | |
var content = A.XML.parse(article.content); | |
var availableLocales = content.firstChild.getAttribute('available-locales'); | |
if (availableLocales.indexOf(themeDisplay.getLanguageId()) == -1) { | |
updateTranslation(article, content, updates); | |
} | |
else { | |
updateArticle(article, content, updates); | |
} | |
}; | |
var updateArticle = function(article, content, updates) { | |
content = updateContent(content, updates); | |
Liferay.Service( | |
'/journalarticle/update-article', | |
{ | |
articleId: article.articleId, | |
content: (new XMLSerializer()).serializeToString(content), | |
folderId: article.folderId, | |
groupId: article.groupId, | |
version: article.version | |
}, | |
function(obj) { | |
var exception = obj.exception; | |
if (!exception) { | |
updateSuccessCount++; | |
if (updateSuccessCount == Object.keys(liveEditInfo).length) { | |
clearControls(); | |
clearFields(); | |
liveEditControls.addClass('update-success'); | |
} | |
} | |
else { | |
clearControls(); | |
liveEditControls.addClass('update-failure'); | |
} | |
} | |
); | |
}; | |
var updateContent = function(content, updates) { | |
for (var key in updates) { | |
if (updates.hasOwnProperty(key)) { | |
var currentElement = content; | |
var levels = key.split(','); | |
for (var i in levels) { | |
var levelObj = levels[i].split('::'); | |
var index = levelObj[1]; | |
var name = levelObj[0]; | |
var dynamicElements = currentElement.getElementsByTagName('dynamic-element'); | |
var dynamicElementCount = 0; | |
for (var i in dynamicElements) { | |
if (dynamicElements[i].getAttribute('name') == name) { | |
if (dynamicElementCount == index) { | |
currentElement = dynamicElements[i]; | |
break; | |
} | |
dynamicElementCount++; | |
} | |
} | |
} | |
var currentElementChildren = currentElement.childNodes; | |
var languageFound = false; | |
for (var i in currentElementChildren) { | |
var currentElementChild = currentElementChildren[i]; | |
if ((currentElementChild.tagName == 'dynamic-content') && (themeDisplay.getLanguageId() == currentElementChild.getAttribute('language-id'))) { | |
var cdataSection = content.createCDATASection(updates[key]); | |
currentElementChild.replaceChild(cdataSection, currentElementChild.firstChild); | |
languageFound = true; | |
} | |
} | |
if (!languageFound) { | |
var dynamicContent = content.createElement('dynamic-content'); | |
dynamicContent.setAttribute('language-id', themeDisplay.getLanguageId()); | |
var cdataSection = content.createCDATASection(updates[key]); | |
dynamicContent.appendChild(cdataSection); | |
currentElement.appendChild(dynamicContent); | |
} | |
} | |
} | |
return content; | |
}; | |
var updateTranslation = function(article, content, updates) { | |
var rootElement = content.firstChild; | |
var availableLocales = rootElement.getAttribute('available-locales') + ',' + themeDisplay.getLanguageId(); | |
rootElement.setAttribute('available-locales', availableLocales); | |
Liferay.Service( | |
'/journalarticle/update-article-translation', | |
{ | |
articleId: article.articleId, | |
content: (new XMLSerializer()).serializeToString(content), | |
description: '', | |
groupId: article.groupId, | |
images: {}, | |
locale: themeDisplay.getLanguageId(), | |
title: '', | |
version: article.version | |
}, | |
function(obj) { | |
var exception = obj.exception; | |
if (!exception) { | |
updateArticle(obj, A.XML.parse(obj.content), updates); | |
} | |
else { | |
clearControls(); | |
liveEditControls.addClass('update-failure'); | |
} | |
} | |
); | |
}; | |
window.liveEditClear = function() { | |
clearFields(true); | |
}; | |
window.liveEditInfo = {}; | |
window.liveEditSave = function() { | |
liveEditControls.addClass('update-sending'); | |
updateSuccessCount = 0; | |
for (var key in liveEditInfo) { | |
if (liveEditInfo.hasOwnProperty(key)) { | |
getArticle(themeDisplay.getScopeGroupId(), key, liveEditInfo[key]); | |
} | |
} | |
}; | |
var body = A.getBody(); | |
body.append('<div id="liveEditControls"><a href="javascript:;" onclick="liveEditSave()">Save</a><a href="javascript:;" onclick="liveEditClear()">Cancel</a></div>'); | |
var liveEditControls = A.one('#liveEditControls'); | |
body.delegate( | |
'focus', | |
function(event) { | |
if (!body.hasClass('controls-visible')) { | |
return; | |
} | |
event.preventDefault(); | |
var node = event.currentTarget; | |
if (!node._initialContent) { | |
node._initialContent = node.getContent(); | |
} | |
node.on( | |
'blur', | |
function(event) { | |
node.detach('blur'); | |
addInfo(node); | |
} | |
); | |
}, | |
'.live-edit' | |
); | |
} | |
); | |
</script> | |
<style> | |
#liveEditControls { | |
background: #DFDFDF; | |
bottom: 0; | |
position: fixed; | |
right: 0; | |
transform: translateY(100%); | |
transition: transform .25s .25s; | |
} | |
#liveEditControls.edits-pending, #liveEditControls.update-failure { | |
transform: translateY(0); | |
} | |
#liveEditControls.edits-pending { | |
background: yellow; | |
} | |
#liveEditControls.update-failure { | |
background: red; | |
} | |
#liveEditControls.update-sending { | |
background: orange; | |
} | |
#liveEditControls.update-success { | |
background: lightgreen; | |
} | |
#liveEditControls a { | |
color: #4c4c4c; | |
display: inline-block; | |
padding: 1em; | |
} | |
.live-edit.live-edited { | |
text-shadow: yellow 1px 1px 1px; | |
} | |
</style> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment