Cat/classes/CatProject.js

98 lines
3.7 KiB
JavaScript

var fs = require('fs');
var os = require('os');
var CatAnimation = require('./CatAnimation');
let CatEmitter = require('./CatEmitter');
const {inherits} = require('util');
function CatProject(view) {
CatEmitter.apply(this);
this.path = '';
this.title = '';
this.tab = null;
this.view = view;
this.doc = null; // reference to the view's iframe's contentDocument -- strangely needed as _somehow_ reading "view.queryselector('iframe').contentDocument" may return undefined when called by a separate module *EVEN* if, in the logs, we read out that value in `setup` before that occurs. Must be some weird optimization in Chrome?
this.animations = []; // array of CatAnimations, used for easier access to the underlying CSS animations
this.frameTime = 0;
this.originalHTML = '';
this.hasChanges = false;
this.setup();
}; inherits(CatProject, CatEmitter);
CatProject.prototype.setup = function() {
this.view.addEventListener('loaded', evt => {
console.log('--- load from CatProject ---');
this.setTitle(this.view.getTitle());
// load/cache our keyframe animations
let doc = this.view.querySelector('iframe').contentDocument;
this.doc = doc;
console.log(doc);
for (let i = 0; i < doc.styleSheets.length; i++) {
for (let j = 0; j < doc.styleSheets[i].cssRules.length; j++) {
let rules = doc.styleSheets[i].cssRules[j];
if (rules.type === 7) { // CSSKeyframesRule
this.animations[rules.name] = new CatAnimation(rules);
}
}
}
// load/cache our elements
this.emit('loaded');
});
}
CatProject.prototype.save = function(path, cb) {
//fs.writeFile(path, (new XMLSerializer().serializeToString(this.iframe.contentDocument))+this.iframe.contentDocument.outerHTML, 'utf-8', (err) => {
let iframe = this.view.querySelector('iframe');
// NOTE: this is pretty hackish, but we basically remove the xmlns namespace for HTML fragments and parse each node individually.
// FIXME: This presumes that the HTML fragment has _no_ real head or body.
var serializedData = '';
if (this.isFragment) {
for (var i = 0; i < iframe.contentDocument.body.children.length; i++) {
serializedData += new XMLSerializer().serializeToString(iframe.contentDocument.body.children[i]).replace(new RegExp(' xmlns="[^"]+"', 'i'), '');
}
} else {
serializedData = this.view.getContents();
}
fs.writeFile(path, serializedData, 'utf-8', (err) => {
if (err) throw err;
this.emit('saved');
this.path = path;
cb(err);
});
}
CatProject.prototype.load = function(path, cb) {
if (!path) path = this.path;
this.path = path;
fs.readFile(path, 'utf-8', (err, data) => {
if (err) throw err;
this.originalHTML = data;
this.view.setContents(data);
// FIXME: we just parse this stupid-style to check if it is an html fragment (which are saved differently). Fragments are assumed to simply not have <html> tags, and as such, will strip out any that get added.
if (this.originalHTML.search(new RegExp('<html[^>]+>', 'i')) == -1) {
this.isFragment = true;
}
cb(err);
});
}
CatProject.prototype.setTitle = function(title) {
this.title = title;
}
CatProject.prototype.getTitle = function() {
let title = this.title;
if (title == '') {
title = this.path.split(os.platform() == 'win32' ? '\\' : '/');
title = title[title.length-1];
console.log(title);
}
if (title == '') title = 'New Project';
return title;
}
// DOM access
CatProject.prototype.getBody = function() {
console.log('--- getBody ---');
console.log(this.doc);
return this.doc.querySelector('body');
}
CatProject.prototype.getAnimations = function() {
return this.animations;
}
module.exports = CatProject;