From f3479e478f3cec1cb00508bedbce8dc5a210931a Mon Sep 17 00:00:00 2001 From: Jose Antonio Marquez Date: Thu, 3 May 2012 15:55:40 -0700 Subject: Clean up, ready for alpha check-in --- js/document/document-html.js | 229 +++---------------------------------------- 1 file changed, 13 insertions(+), 216 deletions(-) diff --git a/js/document/document-html.js b/js/document/document-html.js index ec59c3e2..deca9f83 100755 --- a/js/document/document-html.js +++ b/js/document/document-html.js @@ -28,6 +28,11 @@ exports.HtmlDocument = Montage.create(Component, { loaded: { value: {callback: null, context: null} }, + //////////////////////////////////////////////////////////////////// + // + _observer: { + value: null + }, //////////////////////////////////////////////////////////////////// // _document: { @@ -80,7 +85,7 @@ exports.HtmlDocument = Montage.create(Component, { this.model.views.design.show(); this.model.views.design.iframe.style.opacity = 0; this.model.views.design.content = this.model.file.content; - // + //TODO: Clean up this.model.views.design.render(function () { //TODO: Identify and remove usage of '_document' this._document = this.model.views.design.document; @@ -90,8 +95,9 @@ exports.HtmlDocument = Montage.create(Component, { this._liveNodeList = this.documentRoot.getElementsByTagName('*'); //Initiliazing document model document.application.njUtils.makeElementModel(this.documentRoot, "Body", "body"); - //Adding event to know when template is ready - this.model.views.design.document.head.addEventListener('DOMSubtreeModified', this.handleTemplateReady.bind(this), false); + //Adding observer to know when template is ready + this._observer = new WebKitMutationObserver(this.handleTemplateReady.bind(this)); + this._observer.observe(this.model.views.design.document.head, {childList: true}); }.bind(this)); } else { //TODO: Identify default view (probably code) @@ -102,226 +108,17 @@ exports.HtmlDocument = Montage.create(Component, { // handleTemplateReady: { value: function (e) { - //Removing event listener, a must for this type of event - this.model.views.design.document.head.removeEventListener('DOMSubtreeModified', this.handleTemplateReady.bind(this), false); + //Removing observer, only needed on initial load + this._observer.disconnect(); + this._observer = null; //Making callback after view is loaded this.loaded.callback.call(this.loaded.context, this); //Setting opacity to be viewable after load this.model.views.design.iframe.style.opacity = 1; } - }, + } //////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - handleWebTemplateLoad: { - value: function(event) { - //TODO: Remove, also for prototyping - this.application.ninja.documentController._hackRootFlag = true; - - this._window = this.iframe.contentWindow; - this._document = this.iframe.contentWindow.document; - this.documentRoot = this.iframe.contentWindow.document.body; - - for (var k in this._document.styleSheets) { - if (this._document.styleSheets[k].ownerNode && this._document.styleSheets[k].ownerNode.setAttribute) { - this._document.styleSheets[k].ownerNode.setAttribute('data-ninja-template', 'true'); - } - } - - // Live node list of the current loaded document - this._liveNodeList = this.documentRoot.getElementsByTagName('*'); - - - setTimeout(function () { - - //////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - //////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - //////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - if(this._document.styleSheets.length) { - //Checking all styleSheets in document - for (var i in this._document.styleSheets) { - //If rules are null, assuming cross-origin issue - if(this._document.styleSheets[i].rules === null) { - //TODO: Revisit URLs and URI creation logic, very hack right now - var fileUri, cssUrl, cssData, query, prefixUrl, fileCouldDirUrl, docRootUrl; - // - docRootUrl = this.application.ninja.coreIoApi.rootUrl+escape((this.application.ninja.documentController.documentHackReference.root.split(this.application.ninja.coreIoApi.cloudData.root)[1]).replace(/\/\//gi, '/')); - //TODO: Parse out relative URLs and map them to absolute - if (this._document.styleSheets[i].href.indexOf(this.application.ninja.coreIoApi.rootUrl) !== -1) { - // - cssUrl = this._document.styleSheets[i].href.split(this.application.ninja.coreIoApi.rootUrl)[1]; - fileUri = this.application.ninja.coreIoApi.cloudData.root+cssUrl; - //TODO: Add error handling for reading file - cssData = this.application.ninja.coreIoApi.readFile({uri: fileUri}); - // - var tag = this.iframe.contentWindow.document.createElement('style'); - tag.setAttribute('type', 'text/css'); - tag.setAttribute('data-ninja-uri', fileUri); - tag.setAttribute('data-ninja-file-url', cssUrl); - tag.setAttribute('data-ninja-file-read-only', JSON.parse(this.application.ninja.coreIoApi.isFileWritable({uri: fileUri}).content).readOnly); - tag.setAttribute('data-ninja-file-name', cssUrl.split('/')[cssUrl.split('/').length-1]); - //Copying attributes to maintain same properties as the - for (var n in this._document.styleSheets[i].ownerNode.attributes) { - if (this._document.styleSheets[i].ownerNode.attributes[n].value && this._document.styleSheets[i].ownerNode.attributes[n].name !== 'disabled' && this._document.styleSheets[i].ownerNode.attributes[n].name !== 'disabled') { - if (this._document.styleSheets[i].ownerNode.attributes[n].value.indexOf(docRootUrl) !== -1) { - tag.setAttribute(this._document.styleSheets[i].ownerNode.attributes[n].name, this._document.styleSheets[i].ownerNode.attributes[n].value.split(docRootUrl)[1]); - } else { - tag.setAttribute(this._document.styleSheets[i].ownerNode.attributes[n].name, this._document.styleSheets[i].ownerNode.attributes[n].value); - } - } - } - // - fileCouldDirUrl = this._document.styleSheets[i].href.split(this._document.styleSheets[i].href.split('/')[this._document.styleSheets[i].href.split('/').length-1])[0]; - - //TODO: Make public version of this.application.ninja.ioMediator.getNinjaPropUrlRedirect with dynamic ROOT - tag.innerHTML = cssData.content.replace(/url\(()(.+?)\1\)/g, detectUrl); - - function detectUrl (prop) { - return prop.replace(/[^()\\""\\'']+/g, prefixUrl);; - } - - function prefixUrl (url) { - if (url !== 'url') { - if (!url.match(/(\b(?:(?:https?|ftp|file|[A-Za-z]+):\/\/|www\.|ftp\.)(?:\([-A-Z0-9+&@#\/%=~_|$?!:,.]*\)|[-A-Z0-9+&@#\/%=~_|$?!:,.])*(?:\([-A-Z0-9+&@#\/%=~_|$?!:,.]*\)|[A-Z0-9+&@#\/%=~_|$]))/gi)) { - url = fileCouldDirUrl+url; - } - } - return url; - } - - //Looping through DOM to insert style tag at location of link element - query = this._templateDocument.html.querySelectorAll(['link']); - for (var j in query) { - if (query[j].href === this._document.styleSheets[i].href) { - //Disabling style sheet to reload via inserting in style tag - query[j].setAttribute('disabled', 'true'); - //Inserting tag - this._templateDocument.head.insertBefore(tag, query[j]); - } - } - } else { - console.log('ERROR: Cross-Domain-Stylesheet detected, unable to load in Ninja'); - //None local stylesheet, probably on a CDN (locked) - var tag = this.iframe.contentWindow.document.createElement('style'); - tag.setAttribute('type', 'text/css'); - tag.setAttribute('data-ninja-external-url', this._document.styleSheets[i].href); - tag.setAttribute('data-ninja-file-read-only', "true"); - tag.setAttribute('data-ninja-file-name', this._document.styleSheets[i].href.split('/')[this._document.styleSheets[i].href.split('/').length-1]); - //Copying attributes to maintain same properties as the - for (var n in this._document.styleSheets[i].ownerNode.attributes) { - if (this._document.styleSheets[i].ownerNode.attributes[n].value && this._document.styleSheets[i].ownerNode.attributes[n].name !== 'disabled' && this._document.styleSheets[i].ownerNode.attributes[n].name !== 'disabled') { - if (this._document.styleSheets[i].ownerNode.attributes[n].value.indexOf(docRootUrl) !== -1) { - tag.setAttribute(this._document.styleSheets[i].ownerNode.attributes[n].name, this._document.styleSheets[i].ownerNode.attributes[n].value.split(docRootUrl)[1]); - } else { - tag.setAttribute(this._document.styleSheets[i].ownerNode.attributes[n].name, this._document.styleSheets[i].ownerNode.attributes[n].value); - } - } - } - /* - - //TODO: Figure out cross-domain XHR issue, might need cloud to handle - var xhr = new XMLHttpRequest(); - xhr.open("GET", this._document.styleSheets[i].href, true); - xhr.send(); - // - if (xhr.readyState === 4) { - console.log(xhr); - } - //tag.innerHTML = xhr.responseText //xhr.response; - */ - //Temp rule so it's registered in the array - tag.innerHTML = 'noRULEjustHACK{background: #000}'; - //Disabling external style sheets - query = this._templateDocument.html.querySelectorAll(['link']); - for (var k in query) { - if (query[k].href === this._document.styleSheets[i].href) { - - //TODO: Removed the temp insertion of the stylesheet - //because it wasn't the proper way to do it - //need to be handled via XHR with proxy in Cloud Sim - - //Disabling style sheet to reload via inserting in style tag - //var tempCSS = query[k].cloneNode(true); - //tempCSS.setAttribute('data-ninja-template', 'true'); - query[k].setAttribute('disabled', 'true'); - //this.iframe.contentWindow.document.head.appendChild(tempCSS); - //Inserting tag - this._templateDocument.head.insertBefore(tag, query[k]); - } - } - } - } - } - //////////////////////////////////////////////////////////////////////////// - //////////////////////////////////////////////////////////////////////////// - - //TODO: Check if this is needed - this._stylesheets = this._document.styleSheets; - - //////////////////////////////////////////////////////////////////////////// - //////////////////////////////////////////////////////////////////////////// - - for(i = 0; i < this._stylesheets.length; i++) { - if(this._stylesheets[i].ownerNode.id === "nj-stage-stylesheet") { - this.documentRoot.elementModel.defaultRule = this._stylesheets[i]; - break; - } - } - - //Temporary create properties for each rule we need to save the index of the rule - var len = this.documentRoot.elementModel.defaultRule.cssRules.length; - for(var j = 0; j < len; j++) { - if(this.documentRoot.elementModel.defaultRule.cssRules[j].selectorText === "*") { - this.documentRoot.elementModel.transitionStopRule = this.documentRoot.elementModel.defaultRule.cssRules[j]; - } - } - - } - //////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - //////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - //////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - - - - - - }.bind(this), 1000); - } - } }); //////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////// \ No newline at end of file -- cgit v1.2.3