Added sanitizer extension
This commit is contained in:
		
							parent
							
								
									3ccc267028
								
							
						
					
					
						commit
						580fd66b15
					
				| @ -1,225 +1,229 @@ | |||||||
| define([ | define([ | ||||||
|     "underscore", | 	"underscore", | ||||||
|     "crel", | 	"crel", | ||||||
|     "extensions/markdownExtra", | 	"extensions/markdownExtra", | ||||||
|     "classes/Extension", | 	"classes/Extension", | ||||||
|     "text!html/partialRenderingSettingsBlock.html", | 	"text!html/partialRenderingSettingsBlock.html", | ||||||
| ], function(_, crel, markdownExtra, Extension, partialRenderingSettingsBlockHTML) { | ], function(_, crel, markdownExtra, Extension, partialRenderingSettingsBlockHTML) { | ||||||
| 
 | 
 | ||||||
|     var partialRendering = new Extension("partialRendering", "Partial Rendering", true); | 	var partialRendering = new Extension("partialRendering", "Partial Rendering", true); | ||||||
|     partialRendering.settingsBlock = partialRenderingSettingsBlockHTML; | 	partialRendering.settingsBlock = partialRenderingSettingsBlockHTML; | ||||||
| 
 | 
 | ||||||
|     var converter; | 	var converter; | ||||||
|     var doFootnotes = false; | 	var doFootnotes = false; | ||||||
|     var hasFootnotes = false; | 	var hasFootnotes = false; | ||||||
|     var currentSectionList = []; | 	var currentSectionList = []; | ||||||
| 
 | 
 | ||||||
|     var sectionList = []; | 	var sectionList = []; | ||||||
|     var linkDefinition; | 	var linkDefinition; | ||||||
|     var sectionsToRemove = []; | 	var sectionsToRemove = []; | ||||||
|     var modifiedSections = []; | 	var modifiedSections = []; | ||||||
|     var insertBeforeSection; | 	var insertBeforeSection; | ||||||
|     var fileChanged = false; | 	var fileChanged = false; | ||||||
|     function updateSectionList() { |  | ||||||
|         var newSectionList = []; |  | ||||||
|         var newLinkDefinition = '\n'; |  | ||||||
|         hasFootnotes = false; |  | ||||||
|         _.each(currentSectionList, function(section) { |  | ||||||
|             var text = '\n<div class="se-preview-section-delimiter"></div>\n\n' + section.text + '\n\n'; |  | ||||||
| 
 | 
 | ||||||
|             // Strip footnotes
 | 	function updateSectionList() { | ||||||
|             if(doFootnotes) { | 		var newSectionList = []; | ||||||
|                 text = text.replace(/^```.*\n[\s\S]*?\n```|\n[ ]{0,3}\[\^(.+?)\]\:[ \t]*\n?([\s\S]*?)\n{1,2}((?=\n[ ]{0,3}\S)|$)/gm, function(wholeMatch, footnote) { | 		var newLinkDefinition = '\n'; | ||||||
|                     if(footnote) { | 		hasFootnotes = false; | ||||||
|                         hasFootnotes = true; | 		_.each(currentSectionList, function(section) { | ||||||
|                         newLinkDefinition += wholeMatch.replace(/^\s*\n/gm, '') + '\n'; | 			var text = '\n<div class="se-preview-section-delimiter"></div>\n\n' + section.text + '\n\n'; | ||||||
|                         return ""; |  | ||||||
|                     } |  | ||||||
|                     return wholeMatch; |  | ||||||
|                 }); |  | ||||||
|             } |  | ||||||
| 
 | 
 | ||||||
|             // Strip link definitions
 | 			// Strip footnotes
 | ||||||
|             text = text.replace(/^```.*\n[\s\S]*?\n```|^[ ]{0,3}\[(.+)\]:[ \t]*\n?[ \t]*<?(\S+?)>?(?=\s|$)[ \t]*\n?[ \t]*((\n*)["(](.+?)[")][ \t]*)?(?:\n+)/gm, function(wholeMatch, link) { | 			if(doFootnotes) { | ||||||
|                 if(link) { | 				text = text.replace(/^```.*\n[\s\S]*?\n```|\n[ ]{0,3}\[\^(.+?)\]\:[ \t]*\n?([\s\S]*?)\n{1,2}((?=\n[ ]{0,3}\S)|$)/gm, function(wholeMatch, footnote) { | ||||||
|                     newLinkDefinition += wholeMatch.replace(/^\s*\n/gm, '') + '\n'; | 					if(footnote) { | ||||||
|                     return ""; | 						hasFootnotes = true; | ||||||
|                 } | 						newLinkDefinition += wholeMatch.replace(/^\s*\n/gm, '') + '\n'; | ||||||
|                 return wholeMatch; | 						return ""; | ||||||
|             }); | 					} | ||||||
|  | 					return wholeMatch; | ||||||
|  | 				}); | ||||||
|  | 			} | ||||||
| 
 | 
 | ||||||
|             // Add section to the newSectionList
 | 			// Strip link definitions
 | ||||||
|             newSectionList.push({ | 			text = text.replace(/^```.*\n[\s\S]*?\n```|^[ ]{0,3}\[(.+)\]:[ \t]*\n?[ \t]*<?(\S+?)>?(?=\s|$)[ \t]*\n?[ \t]*((\n*)["(](.+?)[")][ \t]*)?(?:\n+)/gm, function(wholeMatch, link) { | ||||||
|                 id: section.id, | 				if(link) { | ||||||
|                 text: text + '\n' | 					newLinkDefinition += wholeMatch.replace(/^\s*\n/gm, '') + '\n'; | ||||||
|             }); | 					return ""; | ||||||
|         }); | 				} | ||||||
|  | 				return wholeMatch; | ||||||
|  | 			}); | ||||||
| 
 | 
 | ||||||
|         modifiedSections = []; | 			// Add section to the newSectionList
 | ||||||
|         sectionsToRemove = []; | 			newSectionList.push({ | ||||||
|         insertBeforeSection = undefined; | 				id: section.id, | ||||||
|  | 				text: text + '\n' | ||||||
|  | 			}); | ||||||
|  | 		}); | ||||||
| 
 | 
 | ||||||
|         // Render everything if file or linkDefinition changed
 | 		modifiedSections = []; | ||||||
|         if(fileChanged === true || linkDefinition != newLinkDefinition) { | 		sectionsToRemove = []; | ||||||
|             fileChanged = false; | 		insertBeforeSection = undefined; | ||||||
|             linkDefinition = newLinkDefinition; |  | ||||||
|             sectionsToRemove = sectionList; |  | ||||||
|             sectionList = newSectionList; |  | ||||||
|             modifiedSections = newSectionList; |  | ||||||
|             return; |  | ||||||
|         } |  | ||||||
| 
 | 
 | ||||||
|         // Find modified section starting from top
 | 		// Render everything if file or linkDefinition changed
 | ||||||
|         var leftIndex = sectionList.length; | 		if(fileChanged === true || linkDefinition != newLinkDefinition) { | ||||||
|         _.some(sectionList, function(section, index) { | 			fileChanged = false; | ||||||
|             if(index >= newSectionList.length || section.text != newSectionList[index].text) { | 			linkDefinition = newLinkDefinition; | ||||||
|                 leftIndex = index; | 			sectionsToRemove = sectionList; | ||||||
|                 return true; | 			sectionList = newSectionList; | ||||||
|             } | 			modifiedSections = newSectionList; | ||||||
|         }); | 			return; | ||||||
|  | 		} | ||||||
| 
 | 
 | ||||||
|         // Find modified section starting from bottom
 | 		// Find modified section starting from top
 | ||||||
|         var rightIndex = -sectionList.length; | 		var leftIndex = sectionList.length; | ||||||
|         _.some(sectionList.slice().reverse(), function(section, index) { | 		_.some(sectionList, function(section, index) { | ||||||
|             if(index >= newSectionList.length || section.text != newSectionList[newSectionList.length - index - 1].text) { | 			if(index >= newSectionList.length || section.text != newSectionList[index].text) { | ||||||
|                 rightIndex = -index; | 				leftIndex = index; | ||||||
|                 return true; | 				return true; | ||||||
|             } | 			} | ||||||
|         }); | 		}); | ||||||
| 
 | 
 | ||||||
|         if(leftIndex - rightIndex > sectionList.length) { | 		// Find modified section starting from bottom
 | ||||||
|             // Prevent overlap
 | 		var rightIndex = -sectionList.length; | ||||||
|             rightIndex = leftIndex - sectionList.length; | 		_.some(sectionList.slice().reverse(), function(section, index) { | ||||||
|         } | 			if(index >= newSectionList.length || section.text != newSectionList[newSectionList.length - index - 1].text) { | ||||||
|  | 				rightIndex = -index; | ||||||
|  | 				return true; | ||||||
|  | 			} | ||||||
|  | 		}); | ||||||
| 
 | 
 | ||||||
|         // Create an array composed of left unmodified, modified, right
 | 		if(leftIndex - rightIndex > sectionList.length) { | ||||||
|         // unmodified sections
 | 			// Prevent overlap
 | ||||||
|         var leftSections = sectionList.slice(0, leftIndex); | 			rightIndex = leftIndex - sectionList.length; | ||||||
|         modifiedSections = newSectionList.slice(leftIndex, newSectionList.length + rightIndex); | 		} | ||||||
|         var rightSections = sectionList.slice(sectionList.length + rightIndex, sectionList.length); |  | ||||||
|         insertBeforeSection = _.first(rightSections); |  | ||||||
|         sectionsToRemove = sectionList.slice(leftIndex, sectionList.length + rightIndex); |  | ||||||
|         sectionList = leftSections.concat(modifiedSections).concat(rightSections); |  | ||||||
|     } |  | ||||||
| 
 | 
 | ||||||
|     var footnoteMap = {}; | 		// Create an array composed of left unmodified, modified, right
 | ||||||
|     // Store one footnote elt in the footnote map
 | 		// unmodified sections
 | ||||||
|     function storeFootnote(footnoteElt) { | 		var leftSections = sectionList.slice(0, leftIndex); | ||||||
|         var id = footnoteElt.id.substring(3); | 		modifiedSections = newSectionList.slice(leftIndex, newSectionList.length + rightIndex); | ||||||
|         footnoteMap[id] = footnoteElt; | 		var rightSections = sectionList.slice(sectionList.length + rightIndex, sectionList.length); | ||||||
|     } | 		insertBeforeSection = _.first(rightSections); | ||||||
|  | 		sectionsToRemove = sectionList.slice(leftIndex, sectionList.length + rightIndex); | ||||||
|  | 		sectionList = leftSections.concat(modifiedSections).concat(rightSections); | ||||||
|  | 	} | ||||||
| 
 | 
 | ||||||
|     var footnoteContainerElt; | 	var footnoteMap = {}; | ||||||
|     var previewContentsElt; | 	// Store one footnote elt in the footnote map
 | ||||||
|     function refreshSections() { | 	function storeFootnote(footnoteElt) { | ||||||
|  | 		var id = footnoteElt.id.substring(3); | ||||||
|  | 		footnoteMap[id] = footnoteElt; | ||||||
|  | 	} | ||||||
| 
 | 
 | ||||||
|         // Remove outdated sections
 | 	var footnoteContainerElt; | ||||||
|         _.each(sectionsToRemove, function(section) { | 	var previewContentsElt; | ||||||
|             var sectionElt = document.getElementById("wmd-preview-section-" + section.id); |  | ||||||
|             previewContentsElt.removeChild(sectionElt); |  | ||||||
|         }); |  | ||||||
| 
 | 
 | ||||||
|         var wmdPreviewElt = document.getElementById("wmd-preview"); | 	function refreshSections() { | ||||||
|         var childNode = wmdPreviewElt.firstChild; |  | ||||||
|         function createSectionElt(section) { |  | ||||||
|             var sectionElt = crel('div', { |  | ||||||
|                 id: 'wmd-preview-section-' + section.id, |  | ||||||
|                 class: 'wmd-preview-section preview-content' |  | ||||||
|             }); |  | ||||||
|             var isNextDelimiter = false; |  | ||||||
|             while (childNode) { |  | ||||||
|                 var nextNode = childNode.nextSibling; |  | ||||||
|                 var isDelimiter = childNode.className == 'se-preview-section-delimiter'; |  | ||||||
|                 if(isNextDelimiter === true && childNode.tagName == 'DIV' && isDelimiter) { |  | ||||||
|                     // Stop when encountered the next delimiter
 |  | ||||||
|                     break; |  | ||||||
|                 } |  | ||||||
|                 isNextDelimiter = true; |  | ||||||
|                 if(childNode.tagName == 'DIV' && childNode.className == 'footnotes') { |  | ||||||
|                     _.each(childNode.querySelectorAll("ol > li"), storeFootnote); |  | ||||||
|                 } |  | ||||||
|                 else { |  | ||||||
|                     isDelimiter || sectionElt.appendChild(childNode); |  | ||||||
|                 } |  | ||||||
|                 childNode = nextNode; |  | ||||||
|             } |  | ||||||
|             return sectionElt; |  | ||||||
|         } |  | ||||||
| 
 | 
 | ||||||
|         var newSectionEltList = document.createDocumentFragment(); | 		// Remove outdated sections
 | ||||||
|         _.each(modifiedSections, function(section) { | 		_.each(sectionsToRemove, function(section) { | ||||||
|             newSectionEltList.appendChild(createSectionElt(section)); | 			var sectionElt = document.getElementById("wmd-preview-section-" + section.id); | ||||||
|         }); | 			previewContentsElt.removeChild(sectionElt); | ||||||
|         wmdPreviewElt.innerHTML = ''; | 		}); | ||||||
|         var insertBeforeElt = footnoteContainerElt; |  | ||||||
|         if(insertBeforeSection !== undefined) { |  | ||||||
|             insertBeforeElt = document.getElementById("wmd-preview-section-" + insertBeforeSection.id); |  | ||||||
|         } |  | ||||||
|         previewContentsElt.insertBefore(newSectionEltList, insertBeforeElt); |  | ||||||
| 
 | 
 | ||||||
|         // Rewrite footnotes in the footer and update footnote numbers
 | 		var wmdPreviewElt = document.getElementById("wmd-preview"); | ||||||
|         footnoteContainerElt.innerHTML = ''; | 		var childNode = wmdPreviewElt.firstChild; | ||||||
|         var usedFootnoteIds = []; |  | ||||||
|         if(hasFootnotes === true) { |  | ||||||
|             var footnoteElts = crel('ol'); |  | ||||||
|             _.each(previewContentsElt.querySelectorAll('a.footnote'), function(elt, index) { |  | ||||||
|                 elt.textContent = index + 1; |  | ||||||
|                 var id = elt.id.substring(6); |  | ||||||
|                 usedFootnoteIds.push(id); |  | ||||||
|                 footnoteElts.appendChild(footnoteMap[id].cloneNode(true)); |  | ||||||
|             }); |  | ||||||
|             if(usedFootnoteIds.length > 0) { |  | ||||||
|                 // Append the whole footnotes at the end of the document
 |  | ||||||
|                 footnoteContainerElt.appendChild(crel('div', { |  | ||||||
|                     class: 'footnotes' |  | ||||||
|                 }, crel('hr'), footnoteElts)); |  | ||||||
|             } |  | ||||||
|             // Keep used footnotes only in our map
 |  | ||||||
|             footnoteMap = _.pick(footnoteMap, usedFootnoteIds); |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
| 
 | 
 | ||||||
|     partialRendering.onSectionsCreated = function(sectionListParam) { | 		function createSectionElt(section) { | ||||||
|         currentSectionList = sectionListParam; | 			var sectionElt = crel('div', { | ||||||
|     }; | 				id: 'wmd-preview-section-' + section.id, | ||||||
|  | 				class: 'wmd-preview-section preview-content' | ||||||
|  | 			}); | ||||||
|  | 			var isNextDelimiter = false; | ||||||
|  | 			while(childNode) { | ||||||
|  | 				var nextNode = childNode.nextSibling; | ||||||
|  | 				var isDelimiter = childNode.className == 'se-preview-section-delimiter'; | ||||||
|  | 				if(isNextDelimiter === true && childNode.tagName == 'DIV' && isDelimiter) { | ||||||
|  | 					// Stop when encountered the next delimiter
 | ||||||
|  | 					break; | ||||||
|  | 				} | ||||||
|  | 				isNextDelimiter = true; | ||||||
|  | 				if(childNode.tagName == 'DIV' && childNode.className == 'footnotes') { | ||||||
|  | 					_.each(childNode.querySelectorAll("ol > li"), storeFootnote); | ||||||
|  | 				} | ||||||
|  | 				else { | ||||||
|  | 					isDelimiter || sectionElt.appendChild(childNode); | ||||||
|  | 				} | ||||||
|  | 				childNode = nextNode; | ||||||
|  | 			} | ||||||
|  | 			return sectionElt; | ||||||
|  | 		} | ||||||
| 
 | 
 | ||||||
|     partialRendering.onPagedownConfigure = function(editor) { | 		var newSectionEltList = document.createDocumentFragment(); | ||||||
|         converter = editor.getConverter(); | 		_.each(modifiedSections, function(section) { | ||||||
|         converter.hooks.chain("preConversion", function() { | 			newSectionEltList.appendChild(createSectionElt(section)); | ||||||
|             updateSectionList(); | 		}); | ||||||
|             var result = _.map(modifiedSections, function(section) { | 		wmdPreviewElt.innerHTML = ''; | ||||||
|                 return section.text; | 		var insertBeforeElt = footnoteContainerElt; | ||||||
|             }); | 		if(insertBeforeSection !== undefined) { | ||||||
|             result.push(linkDefinition + "\n\n"); | 			insertBeforeElt = document.getElementById("wmd-preview-section-" + insertBeforeSection.id); | ||||||
|             return result.join(""); | 		} | ||||||
|         }); | 		previewContentsElt.insertBefore(newSectionEltList, insertBeforeElt); | ||||||
|         editor.hooks.chain("onPreviewRefresh", function() { |  | ||||||
|             refreshSections(); |  | ||||||
|         }); |  | ||||||
|     }; |  | ||||||
| 
 | 
 | ||||||
|     partialRendering.onInit = function() { | 		// Rewrite footnotes in the footer and update footnote numbers
 | ||||||
|         if(markdownExtra.enabled) { | 		footnoteContainerElt.innerHTML = ''; | ||||||
|             if(_.some(markdownExtra.config.extensions, function(extension) { | 		var usedFootnoteIds = []; | ||||||
|                 return extension == "footnotes"; | 		if(hasFootnotes === true) { | ||||||
|             })) { | 			var footnoteElts = crel('ol'); | ||||||
|                 doFootnotes = true; | 			_.each(previewContentsElt.querySelectorAll('a.footnote'), function(elt, index) { | ||||||
|             } | 				elt.textContent = index + 1; | ||||||
|         } | 				var id = elt.id.substring(6); | ||||||
|     }; | 				usedFootnoteIds.push(id); | ||||||
|  | 				var footnoteElt = footnoteMap[id]; | ||||||
|  | 				footnoteElt && footnoteElts.appendChild(footnoteElt.cloneNode(true)); | ||||||
|  | 			}); | ||||||
|  | 			if(usedFootnoteIds.length > 0) { | ||||||
|  | 				// Append the whole footnotes at the end of the document
 | ||||||
|  | 				footnoteContainerElt.appendChild(crel('div', { | ||||||
|  | 					class: 'footnotes' | ||||||
|  | 				}, crel('hr'), footnoteElts)); | ||||||
|  | 			} | ||||||
|  | 			// Keep used footnotes only in our map
 | ||||||
|  | 			footnoteMap = _.pick(footnoteMap, usedFootnoteIds); | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
| 
 | 
 | ||||||
|     partialRendering.onReady = function() { | 	partialRendering.onSectionsCreated = function(sectionListParam) { | ||||||
|         footnoteContainerElt = crel('div', { | 		currentSectionList = sectionListParam; | ||||||
|             id: 'wmd-preview-section-footnotes', | 	}; | ||||||
|             class: 'preview-content' |  | ||||||
|         }); |  | ||||||
|         previewContentsElt = document.getElementById("preview-contents"); |  | ||||||
|         previewContentsElt.appendChild(footnoteContainerElt); |  | ||||||
|     }; |  | ||||||
| 
 | 
 | ||||||
|     partialRendering.onFileSelected = function() { | 	partialRendering.onPagedownConfigure = function(editor) { | ||||||
|         fileChanged = true; | 		converter = editor.getConverter(); | ||||||
|     }; | 		converter.hooks.chain("preConversion", function() { | ||||||
|  | 			updateSectionList(); | ||||||
|  | 			var result = _.map(modifiedSections, function(section) { | ||||||
|  | 				return section.text; | ||||||
|  | 			}); | ||||||
|  | 			result.push(linkDefinition + "\n\n"); | ||||||
|  | 			return result.join(""); | ||||||
|  | 		}); | ||||||
|  | 		editor.hooks.chain("onPreviewRefresh", function() { | ||||||
|  | 			refreshSections(); | ||||||
|  | 		}); | ||||||
|  | 	}; | ||||||
| 
 | 
 | ||||||
|     return partialRendering; | 	partialRendering.onInit = function() { | ||||||
|  | 		if(markdownExtra.enabled) { | ||||||
|  | 			if(_.some(markdownExtra.config.extensions, function(extension) { | ||||||
|  | 				return extension == "footnotes"; | ||||||
|  | 			})) { | ||||||
|  | 				doFootnotes = true; | ||||||
|  | 			} | ||||||
|  | 		} | ||||||
|  | 	}; | ||||||
|  | 
 | ||||||
|  | 	partialRendering.onReady = function() { | ||||||
|  | 		footnoteContainerElt = crel('div', { | ||||||
|  | 			id: 'wmd-preview-section-footnotes', | ||||||
|  | 			class: 'preview-content' | ||||||
|  | 		}); | ||||||
|  | 		previewContentsElt = document.getElementById("preview-contents"); | ||||||
|  | 		previewContentsElt.appendChild(footnoteContainerElt); | ||||||
|  | 	}; | ||||||
|  | 
 | ||||||
|  | 	partialRendering.onFileSelected = function() { | ||||||
|  | 		fileChanged = true; | ||||||
|  | 	}; | ||||||
|  | 
 | ||||||
|  | 	return partialRendering; | ||||||
| }); | }); | ||||||
| @ -10,6 +10,47 @@ define([ | |||||||
| 
 | 
 | ||||||
| 	var utils = {}; | 	var utils = {}; | ||||||
| 
 | 
 | ||||||
|  | 	utils.msie = (function() { | ||||||
|  | 		/** | ||||||
|  | 		 * IE 11 changed the format of the UserAgent string. | ||||||
|  | 		 * See http://msdn.microsoft.com/en-us/library/ms537503.aspx
 | ||||||
|  | 		 */ | ||||||
|  | 		var msie = parseInt((/msie (\d+)/.exec(navigator.userAgent.toLowerCase()) || [])[1], 10); | ||||||
|  | 		if (isNaN(msie)) { | ||||||
|  | 			msie = parseInt((/trident\/.*; rv:(\d+)/.exec(navigator.userAgent.toLowerCase()) || [])[1], 10); | ||||||
|  | 		} | ||||||
|  | 		return msie; | ||||||
|  | 	})(); | ||||||
|  | 
 | ||||||
|  | 	utils.urlResolve = (function() { | ||||||
|  | 		var urlParsingNode = document.createElement("a"); | ||||||
|  | 		return function urlResolve(url) { | ||||||
|  | 			var href = url; | ||||||
|  | 
 | ||||||
|  | 			if (utils.msie) { | ||||||
|  | 				// Normalize before parse.  Refer Implementation Notes on why this is
 | ||||||
|  | 				// done in two steps on IE.
 | ||||||
|  | 				urlParsingNode.setAttribute("href", href); | ||||||
|  | 				href = urlParsingNode.href; | ||||||
|  | 			} | ||||||
|  | 
 | ||||||
|  | 			urlParsingNode.setAttribute('href', href); | ||||||
|  | 
 | ||||||
|  | 			// urlParsingNode provides the UrlUtils interface - http://url.spec.whatwg.org/#urlutils
 | ||||||
|  | 			return { | ||||||
|  | 				href: urlParsingNode.href, | ||||||
|  | 				protocol: urlParsingNode.protocol ? urlParsingNode.protocol.replace(/:$/, '') : '', | ||||||
|  | 				host: urlParsingNode.host, | ||||||
|  | 				search: urlParsingNode.search ? urlParsingNode.search.replace(/^\?/, '') : '', | ||||||
|  | 				hash: urlParsingNode.hash ? urlParsingNode.hash.replace(/^#/, '') : '', | ||||||
|  | 				hostname: urlParsingNode.hostname, | ||||||
|  | 				port: urlParsingNode.port, | ||||||
|  | 				pathname: (urlParsingNode.pathname.charAt(0) === '/') ? | ||||||
|  | 					urlParsingNode.pathname : '/' + urlParsingNode.pathname | ||||||
|  | 			}; | ||||||
|  | 		}; | ||||||
|  | 	})(); | ||||||
|  | 
 | ||||||
| 	// Faster than setTimeout (see http://dbaron.org/log/20100309-faster-timeouts)
 | 	// Faster than setTimeout (see http://dbaron.org/log/20100309-faster-timeouts)
 | ||||||
| 	utils.defer = (function() { | 	utils.defer = (function() { | ||||||
| 		var timeouts = []; | 		var timeouts = []; | ||||||
|  | |||||||
		Loading…
	
		Reference in New Issue
	
	Block a user
	 benweet
						benweet