/*
Copyright (c) 2012, Motorola Mobility LLC.
All Rights Reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
* Neither the name of Motorola Mobility LLC nor the names of its
contributors may be used to endorse or promote products derived from this
software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.
*/
////////////////////////////////////////////////////////////////////////
//
var Montage = require("montage/core/core").Montage,
Component = require("montage/ui/component").Component,
TemplateCreator = require("node_modules/tools/template/template-creator").TemplateCreator,
ClassUuid = require("js/components/core/class-uuid").ClassUuid;
////////////////////////////////////////////////////////////////////////
//
exports.TemplateDocumentMediator = Montage.create(Component, {
////////////////////////////////////////////////////////////////////
//
hasTemplate: {
value: false
},
////////////////////////////////////////////////////////////////////
//
getAppTemplatesUrlRegEx: {
value: function () {
var regex = new RegExp(chrome.extension.getURL(this.application.ninja.currentDocument.model.views.design.iframe.src.split(chrome.extension.getURL('/'))[1]).replace(/\//gi, '\\\/'), 'gi');
return regex;
}
},
////////////////////////////////////////////////////////////////////
//
getDataDirectory: {
value: function (path) {
//TODO: Implement user overwrite
return this._getUserDirectory(path+'data/');
}
},
////////////////////////////////////////////////////////////////////
//
getNinjaDirectory: {
value: function (path) {
//TODO: Implement user overwrite
return this._getUserDirectory(this.getDataDirectory(path)+'ninja/');
}
},
////////////////////////////////////////////////////////////////////
//
getCanvasDirectory: {
value: function (path) {
//TODO: Implement user overwrite
return this._getUserDirectory(this.getNinjaDirectory(path)+'canvas/');
}
},
////////////////////////////////////////////////////////////////////
//
_getUserDirectory: {
value: function (path) {
//Checking for data directory
var check = this.application.ninja.coreIoApi.fileExists({uri: path}), directory;
//Creating directory if doesn't exists
switch (check.status) {
case 204: //Exists
directory = path;
break;
case 404: //Doesn't exists
directory = this.application.ninja.coreIoApi.createDirectory({uri: path});
//Checking for success
if (directory.status === 201) {
directory = path;
} else {
//Error
directory = null;
}
break;
default: //Error
directory = null;
break;
}
//Returning the path to the directory on disk (null for any error)
return directory;
}
},
////////////////////////////////////////////////////////////////////
//
parseHtmlToNinjaTemplate: {
value: function (html) {
//Creating temp object to mimic HTML
var doc = window.document.implementation.createHTMLDocument(), template, docHtmlTag,
hackHtml = document.createElement('html'), hackTag;
//Setting content to temp
doc.getElementsByTagName('html')[0].innerHTML = html;
//TODO: Improve this, very bad way of copying attributes (in a pinch to get it working)
hackHtml.innerHTML = html.replace(/html/gi, 'ninjahtmlhack');
hackTag = hackHtml.getElementsByTagName('ninjahtmlhack')[0];
docHtmlTag = doc.getElementsByTagName('html')[0];
//Looping through the attributes to copy them
if (hackTag) {
for (var m in hackTag.attributes) {
if (hackTag.attributes[m].value) {
docHtmlTag.setAttribute(hackTag.attributes[m].name.replace(/ninjahtmlhack/gi, 'html'), hackTag.attributes[m].value.replace(/ninjahtmlhack/gi, 'html'));
}
}
}
//Garbage collection
hackHtml = hackTag = null;
//Creating return object
return {head: doc.head.innerHTML, body: doc.body.innerHTML, document: doc};
}
},
////////////////////////////////////////////////////////////////////
//TODO: Expand to allow more templates, clean up variables
parseNinjaTemplateToHtml: {
value: function (saveExternalData, template, ninjaWrapper, libCopyCallback) {
//TODO: Improve reference for rootUrl
var regexRootUrl,
rootUrl = this.application.ninja.coreIoApi.rootUrl + escape((this.application.ninja.documentController.documentHackReference.root.split(this.application.ninja.coreIoApi.cloudData.root)[1])),
mjsCreator = template.mjsTemplateCreator.create(),
mJsSerialization,
toremovetags = [],
presentNodes,
montageTemplate;
//Creating instance of template creator
montageTemplate = mjsCreator.initWithDocument(template.document);
//Setting up expression for parsing URLs
regexRootUrl = new RegExp(rootUrl.replace(/\//gi, '\\\/'), 'gi');
//Injecting head and body into old document
if (montageTemplate._ownerSerialization.length > 0) {
template.file.content.document.head.innerHTML = montageTemplate._document.head.innerHTML.replace(regexRootUrl, '');
template.file.content.document.body.innerHTML = montageTemplate._document.body.innerHTML.replace(regexRootUrl, '');
//
mJsSerialization = montageTemplate._ownerSerialization;
} else {
template.file.content.document.head.innerHTML = template.head.innerHTML.replace(regexRootUrl, '');
template.file.content.document.body.innerHTML = template.body.innerHTML.replace(regexRootUrl, '');
}
//Removes all attributes from node
function wipeAttributes (node) {
for (var f in node.attributes) {
node.removeAttribute(node.attributes[f].name);
}
}
//Copying attributes to maintain same properties as the
wipeAttributes(template.file.content.document.body);
for (var n in template.body.attributes) {
if (template.body.attributes[n].value) {
template.file.content.document.body.setAttribute(template.body.attributes[n].name, template.body.attributes[n].value);
}
}
//
if(template.template) {
//
// TODO - Need to handle banner and animation templates.
//Copying attributes to maintain same properties as
var ninjaContentTagMem = template.document.getElementsByTagName('ninja-content')[0], ninjaContentTagDoc = template.file.content.document.getElementsByTagName('ninja-content')[0];
if (ninjaContentTagMem && ninjaContentTagMem.getAttribute('data-ninja-style') !== null) {
ninjaContentTagDoc.setAttribute('style', ninjaContentTagMem.getAttribute('data-ninja-style'));
ninjaContentTagDoc.removeAttribute('data-ninja-style');
} else if (ninjaContentTagMem && ninjaContentTagMem.getAttribute('data-ninja-style') === null) {
ninjaContentTagDoc.removeAttribute('style');
ninjaContentTagDoc.removeAttribute('data-ninja-style');
}
// TODO - clean up into single method
ninjaContentTagMem = template.document.getElementsByTagName('ninja-viewport')[0], ninjaContentTagDoc = template.file.content.document.getElementsByTagName('ninja-viewport')[0];
if (ninjaContentTagMem && ninjaContentTagMem.getAttribute('data-ninja-style') !== null) {
ninjaContentTagDoc.setAttribute('style', ninjaContentTagMem.getAttribute('data-ninja-style'));
ninjaContentTagDoc.removeAttribute('data-ninja-style');
} else if (ninjaContentTagMem && ninjaContentTagMem.getAttribute('data-ninja-style') === null) {
ninjaContentTagDoc.removeAttribute('style');
ninjaContentTagDoc.removeAttribute('data-ninja-style');
}
} else {
if (template.body && template.body.getAttribute('data-ninja-style') !== null) {
template.file.content.document.body.setAttribute('style', template.body.getAttribute('data-ninja-style'));
template.file.content.document.body.removeAttribute('data-ninja-style');
} else if (template.body && template.body.getAttribute('data-ninja-style') === null) {
template.file.content.document.body.removeAttribute('style');
template.file.content.document.body.removeAttribute('data-ninja-style');
}
}
wipeAttributes(template.file.content.document.head);
//Copying attributes to maintain same properties as the
for (var m in template.document.head.attributes) {
if (template.document.head.attributes[m].value) {
template.file.content.document.head.setAttribute(template.document.head.attributes[m].name, template.document.head.attributes[m].value);
}
}
//Copying attributes to maintain same properties as the
var htmlTagMem = template.document.getElementsByTagName('html')[0], htmlTagDoc = template.file.content.document.getElementsByTagName('html')[0];
wipeAttributes(htmlTagDoc);
//
for (var m in htmlTagMem.attributes) {
if (htmlTagMem.attributes[m].value) {
if (htmlTagMem.attributes[m].value.replace(/montage-app-bootstrapping/gi, '').length>0) {
htmlTagDoc.setAttribute(htmlTagMem.attributes[m].name, htmlTagMem.attributes[m].value.replace(/ montage-app-bootstrapping/gi, ''));
}
}
}
//
if (htmlTagMem && htmlTagMem.getAttribute('data-ninja-style') !== null) {
htmlTagDoc.setAttribute('style', htmlTagMem.getAttribute('data-ninja-style'));
htmlTagDoc.removeAttribute('data-ninja-style');
} else if (htmlTagMem && htmlTagMem.getAttribute('data-ninja-style') === null) {
htmlTagDoc.removeAttribute('style');
htmlTagDoc.removeAttribute('data-ninja-style');
}
//Getting list of current nodes (Ninja DOM)
presentNodes = template.file.content.document.getElementsByTagName('*');
//Looping through nodes to determine origin and removing if not inserted by Ninja
for (var n in presentNodes) {
//
if (presentNodes[n].getAttribute && presentNodes[n].getAttribute('data-ninja-node') === null) {
toremovetags.push(presentNodes[n]);
} else if (presentNodes[n].getAttribute && presentNodes[n].getAttribute('data-ninja-node') !== null) {
//Removing attribute
presentNodes[n].removeAttribute('data-ninja-node');
}
}
//Getting all CSS (style or link) tags
var styletags = template.file.content.document.getElementsByTagName('style'),
linktags = template.file.content.document.getElementsByTagName('link'),
njtemplatetags = template.file.content.document.querySelectorAll('[data-ninja-template]');
//Adding to tags to be removed form template
for (var f in njtemplatetags) {
if (njtemplatetags[f].getAttribute) toremovetags.push(njtemplatetags[f]);
}
//Getting styles tags to be removed from document
if (styletags.length) {
for (var j = 0; j < styletags.length; j++) {
if (styletags[j].getAttribute) {
if (styletags[j].getAttribute('data-ninja-uri') !== null && !styletags[j].getAttribute('data-ninja-template')) {
toremovetags.push(styletags[j]);
} else if (styletags[j].getAttribute('data-ninja-external-url')) {
toremovetags.push(styletags[j]);
}
}
}
}
//Removing styles tags from document
for (var h = 0; toremovetags[h]; h++) {
try {
//Checking head first
template.file.content.document.head.removeChild(toremovetags[h]);
} catch (e) {
}
try {
//Checking body if not in head
template.file.content.document.body.removeChild(toremovetags[h]);
} catch (e) {
//Error, not found!
}
}
//Removing disabled tags from tags that were not originally disabled by user (Ninja enables all)
for (var l in linktags) {
if (linktags[l].getAttribute && linktags[l].getAttribute('disabled')) {//TODO: Use querySelectorAll
for (var p = 0; toremovetags[p]; p++) {
if (toremovetags[p].getAttribute('href') === linktags[l].getAttribute('href')) {
if (!toremovetags[p].getAttribute('data-ninja-disabled')) {
linktags[l].removeAttribute('disabled');
}
}
}
}
}
//TODO: Make proper CSS method
//Checking for type of save: styles =