mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-09 03:15:11 +00:00
Merge inbound to m-c
This commit is contained in:
commit
dbb784a720
2
CLOBBER
2
CLOBBER
@ -18,4 +18,4 @@
|
||||
# Modifying this file will now automatically clobber the buildbot machines \o/
|
||||
#
|
||||
|
||||
Bug 901789 needs a clobber.
|
||||
Bug 921563 needs a clobber due to apparent ipdl regeneration bugs.
|
||||
|
@ -874,26 +874,34 @@ HyperTextAccessible::GetTextBeforeOffset(int32_t aOffset,
|
||||
if (IsDefunct())
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
int32_t offset = ConvertMagicOffset(aOffset);
|
||||
if (offset < 0)
|
||||
if (aBoundaryType == BOUNDARY_CHAR) {
|
||||
GetCharAt(aOffset, eGetBefore, aText, aStartOffset, aEndOffset);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
int32_t adjustedOffset = ConvertMagicOffset(aOffset);
|
||||
if (adjustedOffset < 0)
|
||||
return NS_ERROR_INVALID_ARG;
|
||||
|
||||
if (aOffset == nsIAccessibleText::TEXT_OFFSET_CARET)
|
||||
adjustedOffset = AdjustCaretOffset(adjustedOffset);
|
||||
|
||||
switch (aBoundaryType) {
|
||||
case BOUNDARY_CHAR:
|
||||
GetCharAt(offset, eGetBefore, aText, aStartOffset, aEndOffset);
|
||||
return NS_OK;
|
||||
MOZ_ASSUME_UNREACHABLE("Already handled!");
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
case BOUNDARY_WORD_START: {
|
||||
// If the offset is a word start (except text length offset) then move
|
||||
// backward to find a start offset (end offset is the given offset).
|
||||
// Otherwise move backward twice to find both start and end offsets.
|
||||
if (offset == CharacterCount()) {
|
||||
*aEndOffset = FindWordBoundary(offset, eDirPrevious, eStartWord);
|
||||
if (adjustedOffset == CharacterCount()) {
|
||||
*aEndOffset = FindWordBoundary(adjustedOffset, eDirPrevious, eStartWord);
|
||||
*aStartOffset = FindWordBoundary(*aEndOffset, eDirPrevious, eStartWord);
|
||||
} else {
|
||||
*aStartOffset = FindWordBoundary(offset, eDirPrevious, eStartWord);
|
||||
*aStartOffset = FindWordBoundary(adjustedOffset, eDirPrevious, eStartWord);
|
||||
*aEndOffset = FindWordBoundary(*aStartOffset, eDirNext, eStartWord);
|
||||
if (*aEndOffset != offset) {
|
||||
if (*aEndOffset != adjustedOffset) {
|
||||
*aEndOffset = *aStartOffset;
|
||||
*aStartOffset = FindWordBoundary(*aEndOffset, eDirPrevious, eStartWord);
|
||||
}
|
||||
@ -903,24 +911,18 @@ HyperTextAccessible::GetTextBeforeOffset(int32_t aOffset,
|
||||
|
||||
case BOUNDARY_WORD_END: {
|
||||
// Move word backward twice to find start and end offsets.
|
||||
*aEndOffset = FindWordBoundary(offset, eDirPrevious, eEndWord);
|
||||
*aEndOffset = FindWordBoundary(adjustedOffset, eDirPrevious, eEndWord);
|
||||
*aStartOffset = FindWordBoundary(*aEndOffset, eDirPrevious, eEndWord);
|
||||
return GetText(*aStartOffset, *aEndOffset, aText);
|
||||
}
|
||||
|
||||
case BOUNDARY_LINE_START:
|
||||
if (aOffset == nsIAccessibleText::TEXT_OFFSET_CARET)
|
||||
offset = AdjustCaretOffset(offset);
|
||||
|
||||
*aStartOffset = FindLineBoundary(offset, ePrevLineBegin);
|
||||
*aEndOffset = FindLineBoundary(offset, eThisLineBegin);
|
||||
*aStartOffset = FindLineBoundary(adjustedOffset, ePrevLineBegin);
|
||||
*aEndOffset = FindLineBoundary(adjustedOffset, eThisLineBegin);
|
||||
return GetText(*aStartOffset, *aEndOffset, aText);
|
||||
|
||||
case BOUNDARY_LINE_END: {
|
||||
if (aOffset == nsIAccessibleText::TEXT_OFFSET_CARET)
|
||||
offset = AdjustCaretOffset(offset);
|
||||
|
||||
*aEndOffset = FindLineBoundary(offset, ePrevLineEnd);
|
||||
*aEndOffset = FindLineBoundary(adjustedOffset, ePrevLineEnd);
|
||||
int32_t tmpOffset = *aEndOffset;
|
||||
// Adjust offset if line is wrapped.
|
||||
if (*aEndOffset != 0 && !IsLineEndCharAt(*aEndOffset))
|
||||
@ -944,8 +946,8 @@ HyperTextAccessible::GetTextAtOffset(int32_t aOffset,
|
||||
if (IsDefunct())
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
int32_t offset = ConvertMagicOffset(aOffset);
|
||||
if (offset < 0)
|
||||
int32_t adjustedOffset = ConvertMagicOffset(aOffset);
|
||||
if (adjustedOffset < 0)
|
||||
return NS_ERROR_INVALID_ARG;
|
||||
|
||||
switch (aBoundaryType) {
|
||||
@ -954,7 +956,10 @@ HyperTextAccessible::GetTextAtOffset(int32_t aOffset,
|
||||
NS_OK : NS_ERROR_INVALID_ARG;
|
||||
|
||||
case BOUNDARY_WORD_START:
|
||||
*aEndOffset = FindWordBoundary(offset, eDirNext, eStartWord);
|
||||
if (aOffset == nsIAccessibleText::TEXT_OFFSET_CARET)
|
||||
adjustedOffset = AdjustCaretOffset(adjustedOffset);
|
||||
|
||||
*aEndOffset = FindWordBoundary(adjustedOffset, eDirNext, eStartWord);
|
||||
*aStartOffset = FindWordBoundary(*aEndOffset, eDirPrevious, eStartWord);
|
||||
return GetText(*aStartOffset, *aEndOffset, aText);
|
||||
|
||||
@ -962,25 +967,25 @@ HyperTextAccessible::GetTextAtOffset(int32_t aOffset,
|
||||
// Ignore the spec and follow what WebKitGtk does because Orca expects it,
|
||||
// i.e. return a next word at word end offset of the current word
|
||||
// (WebKitGtk behavior) instead the current word (AKT spec).
|
||||
*aEndOffset = FindWordBoundary(offset, eDirNext, eEndWord);
|
||||
*aEndOffset = FindWordBoundary(adjustedOffset, eDirNext, eEndWord);
|
||||
*aStartOffset = FindWordBoundary(*aEndOffset, eDirPrevious, eEndWord);
|
||||
return GetText(*aStartOffset, *aEndOffset, aText);
|
||||
|
||||
case BOUNDARY_LINE_START:
|
||||
if (aOffset == nsIAccessibleText::TEXT_OFFSET_CARET)
|
||||
offset = AdjustCaretOffset(offset);
|
||||
adjustedOffset = AdjustCaretOffset(adjustedOffset);
|
||||
|
||||
*aStartOffset = FindLineBoundary(offset, eThisLineBegin);
|
||||
*aEndOffset = FindLineBoundary(offset, eNextLineBegin);
|
||||
*aStartOffset = FindLineBoundary(adjustedOffset, eThisLineBegin);
|
||||
*aEndOffset = FindLineBoundary(adjustedOffset, eNextLineBegin);
|
||||
return GetText(*aStartOffset, *aEndOffset, aText);
|
||||
|
||||
case BOUNDARY_LINE_END:
|
||||
if (aOffset == nsIAccessibleText::TEXT_OFFSET_CARET)
|
||||
offset = AdjustCaretOffset(offset);
|
||||
adjustedOffset = AdjustCaretOffset(adjustedOffset);
|
||||
|
||||
// In contrast to word end boundary we follow the spec here.
|
||||
*aStartOffset = FindLineBoundary(offset, ePrevLineEnd);
|
||||
*aEndOffset = FindLineBoundary(offset, eThisLineEnd);
|
||||
*aStartOffset = FindLineBoundary(adjustedOffset, ePrevLineEnd);
|
||||
*aEndOffset = FindLineBoundary(adjustedOffset, eThisLineEnd);
|
||||
return GetText(*aStartOffset, *aEndOffset, aText);
|
||||
|
||||
default:
|
||||
@ -997,18 +1002,26 @@ HyperTextAccessible::GetTextAfterOffset(int32_t aOffset,
|
||||
if (IsDefunct())
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
int32_t offset = ConvertMagicOffset(aOffset);
|
||||
if (offset < 0)
|
||||
if (aBoundaryType == BOUNDARY_CHAR) {
|
||||
GetCharAt(aOffset, eGetAfter, aText, aStartOffset, aEndOffset);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
int32_t adjustedOffset = ConvertMagicOffset(aOffset);
|
||||
if (adjustedOffset < 0)
|
||||
return NS_ERROR_INVALID_ARG;
|
||||
|
||||
if (aOffset == nsIAccessibleText::TEXT_OFFSET_CARET)
|
||||
adjustedOffset = AdjustCaretOffset(adjustedOffset);
|
||||
|
||||
switch (aBoundaryType) {
|
||||
case BOUNDARY_CHAR:
|
||||
GetCharAt(aOffset, eGetAfter, aText, aStartOffset, aEndOffset);
|
||||
return NS_OK;
|
||||
MOZ_ASSUME_UNREACHABLE("Already handled!");
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
case BOUNDARY_WORD_START:
|
||||
// Move word forward twice to find start and end offsets.
|
||||
*aStartOffset = FindWordBoundary(offset, eDirNext, eStartWord);
|
||||
*aStartOffset = FindWordBoundary(adjustedOffset, eDirNext, eStartWord);
|
||||
*aEndOffset = FindWordBoundary(*aStartOffset, eDirNext, eStartWord);
|
||||
return GetText(*aStartOffset, *aEndOffset, aText);
|
||||
|
||||
@ -1016,13 +1029,13 @@ HyperTextAccessible::GetTextAfterOffset(int32_t aOffset,
|
||||
// If the offset is a word end (except 0 offset) then move forward to find
|
||||
// end offset (start offset is the given offset). Otherwise move forward
|
||||
// twice to find both start and end offsets.
|
||||
if (offset == 0) {
|
||||
*aStartOffset = FindWordBoundary(offset, eDirNext, eEndWord);
|
||||
if (adjustedOffset == 0) {
|
||||
*aStartOffset = FindWordBoundary(adjustedOffset, eDirNext, eEndWord);
|
||||
*aEndOffset = FindWordBoundary(*aStartOffset, eDirNext, eEndWord);
|
||||
} else {
|
||||
*aEndOffset = FindWordBoundary(offset, eDirNext, eEndWord);
|
||||
*aEndOffset = FindWordBoundary(adjustedOffset, eDirNext, eEndWord);
|
||||
*aStartOffset = FindWordBoundary(*aEndOffset, eDirPrevious, eEndWord);
|
||||
if (*aStartOffset != offset) {
|
||||
if (*aStartOffset != adjustedOffset) {
|
||||
*aStartOffset = *aEndOffset;
|
||||
*aEndOffset = FindWordBoundary(*aStartOffset, eDirNext, eEndWord);
|
||||
}
|
||||
@ -1030,19 +1043,13 @@ HyperTextAccessible::GetTextAfterOffset(int32_t aOffset,
|
||||
return GetText(*aStartOffset, *aEndOffset, aText);
|
||||
|
||||
case BOUNDARY_LINE_START:
|
||||
if (aOffset == nsIAccessibleText::TEXT_OFFSET_CARET)
|
||||
offset = AdjustCaretOffset(offset);
|
||||
|
||||
*aStartOffset = FindLineBoundary(offset, eNextLineBegin);
|
||||
*aStartOffset = FindLineBoundary(adjustedOffset, eNextLineBegin);
|
||||
*aEndOffset = FindLineBoundary(*aStartOffset, eNextLineBegin);
|
||||
return GetText(*aStartOffset, *aEndOffset, aText);
|
||||
|
||||
case BOUNDARY_LINE_END:
|
||||
if (aOffset == nsIAccessibleText::TEXT_OFFSET_CARET)
|
||||
offset = AdjustCaretOffset(offset);
|
||||
|
||||
*aStartOffset = FindLineBoundary(offset, eThisLineEnd);
|
||||
*aEndOffset = FindLineBoundary(offset, eNextLineEnd);
|
||||
*aStartOffset = FindLineBoundary(adjustedOffset, eThisLineEnd);
|
||||
*aEndOffset = FindLineBoundary(adjustedOffset, eNextLineEnd);
|
||||
return GetText(*aStartOffset, *aEndOffset, aText);
|
||||
|
||||
default:
|
||||
|
@ -32,68 +32,251 @@
|
||||
var baseInvoker = new synthFocus(aID);
|
||||
var baseInvokerID = "move to last line end";
|
||||
|
||||
var wholeText = "";
|
||||
for (var i = 0; i < aLines.length ; i++)
|
||||
wholeText += aLines[i][0] + aLines[i][1];
|
||||
|
||||
for (var i = aLines.length - 1; i >= 0 ; i--) {
|
||||
var [ ppLineText, ppLineEndChar, ppLineStart, ppLineEnd ] =
|
||||
(i - 2 >= 0) ? aLines[i - 2] : [ "", "", 0, 0 ];
|
||||
var [ pLineText, pLineEndChar, pLineStart, pLineEnd ] =
|
||||
(i - 1 >= 0) ? aLines[i - 1] : [ "", "", 0, 0 ];
|
||||
var [ lineText, lineEndChar, lineStart, lineEnd ] = aLines[i];
|
||||
var cLine = new line(wholeText, aLines, i);
|
||||
var pLine = cLine.prevLine;
|
||||
var ppLine = pLine.prevLine;
|
||||
var nLine = cLine.nextLine;
|
||||
var nnLine = nLine.nextLine;
|
||||
|
||||
var [ nLineText, nLineEndChar, nLineStart, nLineEnd ] =
|
||||
(i + 1 < aLines.length) ?
|
||||
aLines[i + 1] :
|
||||
[ "", "", lineEnd + lineEndChar.length, lineEnd + lineEndChar.length ];
|
||||
|
||||
var [ nnLineText, nnLineEndChar, nnLineStart, nnLineEnd ] =
|
||||
(i + 2 < aLines.length) ?
|
||||
aLines[i + 2] :
|
||||
[ "", "", nLineEnd + nLineEndChar.length, nLineEnd + nLineEndChar.length ];
|
||||
|
||||
var tests = [
|
||||
[ testTextBeforeOffset, BOUNDARY_LINE_START,
|
||||
pLineText + pLineEndChar, pLineStart, lineStart],
|
||||
|
||||
[ testTextBeforeOffset, BOUNDARY_LINE_END,
|
||||
ppLineEndChar + pLineText, ppLineEnd, pLineEnd],
|
||||
|
||||
[ testTextAtOffset, BOUNDARY_LINE_START,
|
||||
lineText + lineEndChar, lineStart, nLineStart],
|
||||
|
||||
[ testTextAtOffset, BOUNDARY_LINE_END,
|
||||
pLineEndChar + lineText, pLineEnd, lineEnd],
|
||||
|
||||
[ testTextAfterOffset, BOUNDARY_LINE_START,
|
||||
nLineText + nnLineEndChar, nLineStart, nnLineStart],
|
||||
|
||||
[ testTextAfterOffset, BOUNDARY_LINE_END,
|
||||
lineEndChar + nLineText, lineEnd, nLineEnd],
|
||||
// Shared line tests.
|
||||
var lineTests = [
|
||||
[ testTextBeforeOffset, BOUNDARY_LINE_START, pLine.start, cLine.start],
|
||||
[ testTextBeforeOffset, BOUNDARY_LINE_END, ppLine.end, pLine.end],
|
||||
[ testTextAtOffset, BOUNDARY_LINE_START, cLine.start, nLine.start],
|
||||
[ testTextAtOffset, BOUNDARY_LINE_END, pLine.end, cLine.end],
|
||||
[ testTextAfterOffset, BOUNDARY_LINE_START, nLine.start, nnLine.start],
|
||||
[ testTextAfterOffset, BOUNDARY_LINE_END, cLine.end, nLine.end]
|
||||
];
|
||||
|
||||
aQueue.push(new tmpl_moveTo(aID, baseInvoker, baseInvokerID, tests));
|
||||
// Word tests for "caret at the end of the line".
|
||||
var lastWord = cLine.lastWord;
|
||||
var pLastWord = lastWord.prevWord;
|
||||
var ppLastWord = pLastWord.prevWord;
|
||||
var nLastWord = lastWord.nextWord;
|
||||
var nnLastWord = nLastWord.nextWord;
|
||||
var isAtEnd = (cLine.end == wholeText.length);
|
||||
var isAtWordEnd = (cLine.end = lastWord.end);
|
||||
|
||||
baseInvoker = new moveToLineStart(aID, lineStart);
|
||||
var lineEndWordTests = [
|
||||
[ testTextBeforeOffset, BOUNDARY_WORD_START, pLastWord.start, lastWord.start ],
|
||||
[ testTextBeforeOffset, BOUNDARY_WORD_END, ppLastWord.end, pLastWord.end ],
|
||||
[ testTextAtOffset, BOUNDARY_WORD_START, lastWord.start, nLastWord.start ],
|
||||
[ testTextAtOffset, BOUNDARY_WORD_END,
|
||||
(isAtEnd ? pLastWord : lastWord).end,
|
||||
(isAtEnd ? lastWord : nLastWord).end ],
|
||||
[ testTextAfterOffset, BOUNDARY_WORD_START, nLastWord.start, nnLastWord.start ],
|
||||
[ testTextAfterOffset, BOUNDARY_WORD_END,
|
||||
(isAtWordEnd ? lastWord : nLastWord).end,
|
||||
(isAtWordEnd ? nLastWord : nnLastWord).end ]
|
||||
];
|
||||
|
||||
// Add "caret at the end of the line" tests.
|
||||
aQueue.push(new tmpl_moveTo(aID, baseInvoker, baseInvokerID, wholeText,
|
||||
lineTests.concat(lineEndWordTests),
|
||||
cLine.lineEndFailures));
|
||||
|
||||
// Word tests for "caret at the end of the line".
|
||||
var firstWord = cLine.firstWord;
|
||||
var pFirstWord = firstWord.prevWord;
|
||||
var ppFirstWord = pFirstWord.prevWord;
|
||||
var nFirstWord = firstWord.nextWord;
|
||||
var nnFirstWord = nFirstWord.nextWord;
|
||||
var isAtWordBegin = (cLine.start == firstWord.start);
|
||||
var lineStartWordTests = [
|
||||
[ testTextBeforeOffset, BOUNDARY_WORD_START,
|
||||
(isAtWordBegin ? pFirstWord : ppFirstWord).start,
|
||||
(isAtWordBegin ? firstWord : pFirstWord).start ],
|
||||
[ testTextBeforeOffset, BOUNDARY_WORD_END, ppFirstWord.end, pFirstWord.end ],
|
||||
[ testTextAtOffset, BOUNDARY_WORD_START,
|
||||
(isAtWordBegin ? firstWord : pFirstWord).start,
|
||||
(isAtWordBegin ? nFirstWord : firstWord).start ],
|
||||
[ testTextAtOffset, BOUNDARY_WORD_END, pFirstWord.end, firstWord.end ],
|
||||
[ testTextAfterOffset, BOUNDARY_WORD_START,
|
||||
(isAtWordBegin ? nFirstWord : firstWord).start,
|
||||
(isAtWordBegin ? nnFirstWord : nFirstWord).start ],
|
||||
[ testTextAfterOffset, BOUNDARY_WORD_END, firstWord.end, nFirstWord.end ],
|
||||
];
|
||||
|
||||
baseInvoker = new moveToLineStart(aID, cLine.start);
|
||||
baseInvokerID = "move to " + i + "th line start";
|
||||
|
||||
aQueue.push(new tmpl_moveTo(aID, baseInvoker, baseInvokerID, tests));
|
||||
// Add "caret at the start of the line" tests.
|
||||
aQueue.push(new tmpl_moveTo(aID, baseInvoker, baseInvokerID, wholeText,
|
||||
lineTests.concat(lineStartWordTests),
|
||||
cLine.lineStartFailures));
|
||||
|
||||
baseInvoker = new moveToPrevLineEnd(aID, pLineEnd);
|
||||
// Next loop invoker to move caret at the end of prev line.
|
||||
baseInvoker = new moveToPrevLineEnd(aID, pLine.end);
|
||||
baseInvokerID = "move to " + (i - 1) + "th line end";
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A line object. Allows to navigate by lines and by words.
|
||||
*/
|
||||
function line(aWholeText, aLines, aIndex)
|
||||
{
|
||||
Object.defineProperty(this, "prevLine", { get: function()
|
||||
{
|
||||
return new line(aWholeText, aLines, aIndex - 1);
|
||||
}
|
||||
});
|
||||
Object.defineProperty(this, "nextLine", { get: function()
|
||||
{
|
||||
return new line(aWholeText, aLines, aIndex + 1);
|
||||
}
|
||||
});
|
||||
|
||||
Object.defineProperty(this, "start", { get: function()
|
||||
{
|
||||
if (aIndex < 0)
|
||||
return 0;
|
||||
|
||||
if (aIndex >= aLines.length)
|
||||
return aWholeText.length;
|
||||
|
||||
return aLines[aIndex][2];
|
||||
}
|
||||
});
|
||||
Object.defineProperty(this, "end", { get: function()
|
||||
{
|
||||
if (aIndex < 0)
|
||||
return 0;
|
||||
|
||||
if (aIndex >= aLines.length)
|
||||
return aWholeText.length;
|
||||
|
||||
return aLines[aIndex][3];
|
||||
}
|
||||
});
|
||||
|
||||
Object.defineProperty(this, "lastWord", { get: function()
|
||||
{
|
||||
if (aIndex < 0)
|
||||
return new word(this, [], -1);
|
||||
if (aIndex >= aLines.length)
|
||||
return new word(this, [], 0);
|
||||
|
||||
var words = aLines[aIndex][4].words;
|
||||
return new word(this, words, words.length - 2);
|
||||
}
|
||||
});
|
||||
Object.defineProperty(this, "firstWord", { get: function()
|
||||
{
|
||||
if (aIndex < 0)
|
||||
return new word(this, [], -1);
|
||||
if (aIndex >= aLines.length)
|
||||
return new word(this, [], 0);
|
||||
|
||||
var words = aLines[aIndex][4].words;
|
||||
return new word(this, words, 0);
|
||||
}
|
||||
});
|
||||
|
||||
Object.defineProperty(this, "lineStartFailures", { get: function()
|
||||
{
|
||||
if (aIndex < 0 || aIndex >= aLines.length)
|
||||
return [];
|
||||
|
||||
return aLines[aIndex][4].lsf || [];
|
||||
}
|
||||
});
|
||||
Object.defineProperty(this, "lineEndFailures", { get: function()
|
||||
{
|
||||
if (aIndex < 0 || aIndex >= aLines.length)
|
||||
return [];
|
||||
|
||||
return aLines[aIndex][4].lef || [];
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* A word object. Allows to navigate by words.
|
||||
*/
|
||||
function word(aLine, aWords, aIndex)
|
||||
{
|
||||
Object.defineProperty(this, "prevWord", { get: function()
|
||||
{
|
||||
if (aIndex >= 2)
|
||||
return new word(aLine, aWords, aIndex - 2);
|
||||
|
||||
var prevLineLastWord = aLine.prevLine.lastWord;
|
||||
if (this.start == prevLineLastWord.start && !this.isFakeStartWord())
|
||||
return prevLineLastWord.prevWord;
|
||||
return prevLineLastWord;
|
||||
}
|
||||
});
|
||||
|
||||
Object.defineProperty(this, "nextWord", { get: function()
|
||||
{
|
||||
if (aIndex + 2 < aWords.length)
|
||||
return new word(aLine, aWords, aIndex + 2);
|
||||
|
||||
var nextLineFirstWord = aLine.nextLine.firstWord;
|
||||
if (this.end == nextLineFirstWord.end && !this.isFakeEndWord())
|
||||
return nextLineFirstWord.nextWord;
|
||||
return nextLineFirstWord;
|
||||
}
|
||||
});
|
||||
|
||||
Object.defineProperty(this, "start", { get: function()
|
||||
{
|
||||
if (this.isFakeStartWord())
|
||||
return 0;
|
||||
|
||||
if (this.isFakeEndWord())
|
||||
return aLine.end;
|
||||
return aWords[aIndex];
|
||||
}
|
||||
});
|
||||
Object.defineProperty(this, "end", { get: function()
|
||||
{
|
||||
if (this.isFakeStartWord())
|
||||
return 0;
|
||||
|
||||
return this.isFakeEndWord() ? aLine.end : aWords[aIndex + 1];
|
||||
}
|
||||
});
|
||||
|
||||
this.isFakeStartWord = function() { return aIndex < 0; }
|
||||
this.isFakeEndWord = function() { return aIndex >= aWords.length; }
|
||||
}
|
||||
|
||||
/**
|
||||
* A template invoker to move through the text.
|
||||
*/
|
||||
function tmpl_moveTo(aID, aInvoker, aInvokerID, aTests)
|
||||
function tmpl_moveTo(aID, aInvoker, aInvokerID, aWholeText, aTests,
|
||||
aFailures)
|
||||
{
|
||||
this.__proto__ = aInvoker;
|
||||
|
||||
this.finalCheck = function genericMoveTo_finalCheck()
|
||||
{
|
||||
for (var i = 0; i < aTests.length; i++) {
|
||||
aTests[i][0].call(null, kCaretOffset, aTests[i][1],
|
||||
aTests[i][2], aTests[i][3], aTests[i][4], aID,
|
||||
kOk, kOk, kOk);
|
||||
var func = aTests[i][0];
|
||||
var boundary = aTests[i][1];
|
||||
var startOffset = aTests[i][2];
|
||||
var endOffset = aTests[i][3];
|
||||
var text = aWholeText.substring(startOffset, endOffset);
|
||||
|
||||
var isOk1 = kOk, isOk2 = kOk, isOk3 = kOk;
|
||||
for (var fIdx = 0; fIdx < aFailures.length; fIdx++) {
|
||||
var failure = aFailures[fIdx];
|
||||
if (func.name.indexOf(failure[0]) != -1 && boundary == failure[1]) {
|
||||
isOk1 = failure[2];
|
||||
isOk2 = failure[3];
|
||||
isOk3 = failure[4];
|
||||
}
|
||||
}
|
||||
|
||||
func.call(null, kCaretOffset, boundary, text, startOffset, endOffset,
|
||||
aID, isOk1, isOk2, isOk3);
|
||||
}
|
||||
}
|
||||
|
||||
@ -116,18 +299,32 @@
|
||||
// 10 11 12 13 14 15
|
||||
|
||||
traverseTextByLines(gQueue, "textarea",
|
||||
[ [ "aword", "\n", 0, 5 ],
|
||||
[ "two ", "", 6, 10 ],
|
||||
[ "words", "", 10, 15 ]] );
|
||||
[ [ "aword", "\n", 0, 5, { words: [ 0, 5 ] } ],
|
||||
[ "two ", "", 6, 10, { words: [ 6, 9 ] } ],
|
||||
[ "words", "", 10, 15, { words: [ 10, 15 ] } ]
|
||||
] );
|
||||
|
||||
var line2 = [ // " my "
|
||||
[ "TextBeforeOffset", BOUNDARY_WORD_END, kTodo, kTodo, kTodo ],
|
||||
[ "TextAfterOffset", BOUNDARY_WORD_END, kTodo, kTodo, kTodo ]
|
||||
];
|
||||
var line4 = [ // "riend"
|
||||
[ "TextBeforeOffset", BOUNDARY_WORD_END, kTodo, kTodo, kTodo ],
|
||||
[ "TextAfterOffset", BOUNDARY_WORD_END, kTodo, kTodo, kTodo ]
|
||||
];
|
||||
var line5 = [ // " t "
|
||||
[ "TextBeforeOffset", BOUNDARY_WORD_END, kTodo, kTodo, kTodo ],
|
||||
[ "TextAfterOffset", BOUNDARY_WORD_END, kTodo, kTodo, kTodo ]
|
||||
];
|
||||
traverseTextByLines(gQueue, "ta_wrapped",
|
||||
[ [ "hi ", "", 0, 3 ],
|
||||
[ "hello", "", 3, 8 ],
|
||||
[ " my ", "", 8, 12 ],
|
||||
[ "longf", "", 12, 17 ],
|
||||
[ "riend", "", 17, 22 ],
|
||||
[ " t ", "", 22, 25 ],
|
||||
[ "sq t", "", 25, 29 ]] );
|
||||
[ [ "hi ", "", 0, 3, { words: [ 0, 2 ] } ],
|
||||
[ "hello", "", 3, 8, { words: [ 3, 8 ] } ],
|
||||
[ " my ", "", 8, 12, { words: [ 9, 11 ], lsf: line2 } ],
|
||||
[ "longf", "", 12, 17, { words: [ 12, 17 ] } ],
|
||||
[ "riend", "", 17, 22, { words: [ 17, 22 ], lsf: line4 } ],
|
||||
[ " t ", "", 22, 25, { words: [ 23, 24 ], lsf: line5 } ],
|
||||
[ "sq t", "", 25, 29, { words: [ 25, 27, 28, 29 ] } ]
|
||||
] );
|
||||
|
||||
gQueue.invoke(); // will call SimpleTest.finish();
|
||||
}
|
||||
|
@ -1284,6 +1284,9 @@ pref("pdfjs.firstRun", true);
|
||||
pref("pdfjs.previousHandler.preferredAction", 0);
|
||||
pref("pdfjs.previousHandler.alwaysAskBeforeHandling", false);
|
||||
|
||||
// Shumway component (SWF player) is disabled by default. Also see bug 904346.
|
||||
pref("shumway.disabled", true);
|
||||
|
||||
// The maximum amount of decoded image data we'll willingly keep around (we
|
||||
// might keep around more than this, but we'll try to get down to this value).
|
||||
// (This is intentionally on the high side; see bug 746055.)
|
||||
|
@ -53,6 +53,9 @@ XPCOMUtils.defineLazyModuleGetter(this, "BrowserNewTabPreloader",
|
||||
XPCOMUtils.defineLazyModuleGetter(this, "PdfJs",
|
||||
"resource://pdf.js/PdfJs.jsm");
|
||||
|
||||
XPCOMUtils.defineLazyModuleGetter(this, "ShumwayUtils",
|
||||
"resource://shumway/ShumwayUtils.jsm");
|
||||
|
||||
XPCOMUtils.defineLazyModuleGetter(this, "webrtcUI",
|
||||
"resource:///modules/webrtcUI.jsm");
|
||||
|
||||
@ -467,6 +470,7 @@ BrowserGlue.prototype = {
|
||||
BrowserNewTabPreloader.init();
|
||||
SignInToWebsiteUX.init();
|
||||
PdfJs.init();
|
||||
ShumwayUtils.init();
|
||||
webrtcUI.init();
|
||||
AboutHome.init();
|
||||
|
||||
|
@ -19,13 +19,20 @@ exclude_files = \
|
||||
$(FINAL_TARGET)/chrome/pdfjs.manifest: $(GLOBAL_DEPS)
|
||||
printf "manifest pdfjs/chrome.manifest" > $@
|
||||
|
||||
libs:: $(FINAL_TARGET)/chrome/pdfjs.manifest
|
||||
$(FINAL_TARGET)/chrome/shumway.manifest: $(GLOBAL_DEPS)
|
||||
printf "manifest shumway/chrome.manifest" > $@
|
||||
|
||||
libs:: $(FINAL_TARGET)/chrome/pdfjs.manifest $(FINAL_TARGET)/chrome/shumway.manifest
|
||||
$(PYTHON) $(topsrcdir)/config/nsinstall.py \
|
||||
$(srcdir)/pdfjs \
|
||||
$(foreach exclude,$(exclude_files), -X $(srcdir)/pdfjs/$(exclude)) \
|
||||
$(srcdir)/shumway \
|
||||
$(foreach exclude,$(exclude_files), -X $(srcdir)/shumway/$(exclude)) \
|
||||
$(FINAL_TARGET)/chrome
|
||||
$(PYTHON) $(MOZILLA_DIR)/config/buildlist.py \
|
||||
$(FINAL_TARGET)/chrome.manifest "manifest chrome/pdfjs.manifest"
|
||||
$(PYTHON) $(MOZILLA_DIR)/config/buildlist.py \
|
||||
$(FINAL_TARGET)/chrome.manifest "manifest chrome/shumway.manifest"
|
||||
|
||||
ifdef MOZ_METRO
|
||||
$(DIST)/bin/metro/chrome/pdfjs.manifest: $(GLOBAL_DEPS)
|
||||
|
178
browser/extensions/shumway/LICENSE
Normal file
178
browser/extensions/shumway/LICENSE
Normal file
@ -0,0 +1,178 @@
|
||||
|
||||
Apache License
|
||||
Version 2.0, January 2004
|
||||
http://www.apache.org/licenses/
|
||||
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||
|
||||
1. Definitions.
|
||||
|
||||
"License" shall mean the terms and conditions for use, reproduction,
|
||||
and distribution as defined by Sections 1 through 9 of this document.
|
||||
|
||||
"Licensor" shall mean the copyright owner or entity authorized by
|
||||
the copyright owner that is granting the License.
|
||||
|
||||
"Legal Entity" shall mean the union of the acting entity and all
|
||||
other entities that control, are controlled by, or are under common
|
||||
control with that entity. For the purposes of this definition,
|
||||
"control" means (i) the power, direct or indirect, to cause the
|
||||
direction or management of such entity, whether by contract or
|
||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||
|
||||
"You" (or "Your") shall mean an individual or Legal Entity
|
||||
exercising permissions granted by this License.
|
||||
|
||||
"Source" form shall mean the preferred form for making modifications,
|
||||
including but not limited to software source code, documentation
|
||||
source, and configuration files.
|
||||
|
||||
"Object" form shall mean any form resulting from mechanical
|
||||
transformation or translation of a Source form, including but
|
||||
not limited to compiled object code, generated documentation,
|
||||
and conversions to other media types.
|
||||
|
||||
"Work" shall mean the work of authorship, whether in Source or
|
||||
Object form, made available under the License, as indicated by a
|
||||
copyright notice that is included in or attached to the work
|
||||
(an example is provided in the Appendix below).
|
||||
|
||||
"Derivative Works" shall mean any work, whether in Source or Object
|
||||
form, that is based on (or derived from) the Work and for which the
|
||||
editorial revisions, annotations, elaborations, or other modifications
|
||||
represent, as a whole, an original work of authorship. For the purposes
|
||||
of this License, Derivative Works shall not include works that remain
|
||||
separable from, or merely link (or bind by name) to the interfaces of,
|
||||
the Work and Derivative Works thereof.
|
||||
|
||||
"Contribution" shall mean any work of authorship, including
|
||||
the original version of the Work and any modifications or additions
|
||||
to that Work or Derivative Works thereof, that is intentionally
|
||||
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||
or by an individual or Legal Entity authorized to submit on behalf of
|
||||
the copyright owner. For the purposes of this definition, "submitted"
|
||||
means any form of electronic, verbal, or written communication sent
|
||||
to the Licensor or its representatives, including but not limited to
|
||||
communication on electronic mailing lists, source code control systems,
|
||||
and issue tracking systems that are managed by, or on behalf of, the
|
||||
Licensor for the purpose of discussing and improving the Work, but
|
||||
excluding communication that is conspicuously marked or otherwise
|
||||
designated in writing by the copyright owner as "Not a Contribution."
|
||||
|
||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||
on behalf of whom a Contribution has been received by Licensor and
|
||||
subsequently incorporated within the Work.
|
||||
|
||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
copyright license to reproduce, prepare Derivative Works of,
|
||||
publicly display, publicly perform, sublicense, and distribute the
|
||||
Work and such Derivative Works in Source or Object form.
|
||||
|
||||
3. Grant of Patent License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
(except as stated in this section) patent license to make, have made,
|
||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||
where such license applies only to those patent claims licensable
|
||||
by such Contributor that are necessarily infringed by their
|
||||
Contribution(s) alone or by combination of their Contribution(s)
|
||||
with the Work to which such Contribution(s) was submitted. If You
|
||||
institute patent litigation against any entity (including a
|
||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||
or a Contribution incorporated within the Work constitutes direct
|
||||
or contributory patent infringement, then any patent licenses
|
||||
granted to You under this License for that Work shall terminate
|
||||
as of the date such litigation is filed.
|
||||
|
||||
4. Redistribution. You may reproduce and distribute copies of the
|
||||
Work or Derivative Works thereof in any medium, with or without
|
||||
modifications, and in Source or Object form, provided that You
|
||||
meet the following conditions:
|
||||
|
||||
(a) You must give any other recipients of the Work or
|
||||
Derivative Works a copy of this License; and
|
||||
|
||||
(b) You must cause any modified files to carry prominent notices
|
||||
stating that You changed the files; and
|
||||
|
||||
(c) You must retain, in the Source form of any Derivative Works
|
||||
that You distribute, all copyright, patent, trademark, and
|
||||
attribution notices from the Source form of the Work,
|
||||
excluding those notices that do not pertain to any part of
|
||||
the Derivative Works; and
|
||||
|
||||
(d) If the Work includes a "NOTICE" text file as part of its
|
||||
distribution, then any Derivative Works that You distribute must
|
||||
include a readable copy of the attribution notices contained
|
||||
within such NOTICE file, excluding those notices that do not
|
||||
pertain to any part of the Derivative Works, in at least one
|
||||
of the following places: within a NOTICE text file distributed
|
||||
as part of the Derivative Works; within the Source form or
|
||||
documentation, if provided along with the Derivative Works; or,
|
||||
within a display generated by the Derivative Works, if and
|
||||
wherever such third-party notices normally appear. The contents
|
||||
of the NOTICE file are for informational purposes only and
|
||||
do not modify the License. You may add Your own attribution
|
||||
notices within Derivative Works that You distribute, alongside
|
||||
or as an addendum to the NOTICE text from the Work, provided
|
||||
that such additional attribution notices cannot be construed
|
||||
as modifying the License.
|
||||
|
||||
You may add Your own copyright statement to Your modifications and
|
||||
may provide additional or different license terms and conditions
|
||||
for use, reproduction, or distribution of Your modifications, or
|
||||
for any such Derivative Works as a whole, provided Your use,
|
||||
reproduction, and distribution of the Work otherwise complies with
|
||||
the conditions stated in this License.
|
||||
|
||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||
any Contribution intentionally submitted for inclusion in the Work
|
||||
by You to the Licensor shall be under the terms and conditions of
|
||||
this License, without any additional terms or conditions.
|
||||
Notwithstanding the above, nothing herein shall supersede or modify
|
||||
the terms of any separate license agreement you may have executed
|
||||
with Licensor regarding such Contributions.
|
||||
|
||||
6. Trademarks. This License does not grant permission to use the trade
|
||||
names, trademarks, service marks, or product names of the Licensor,
|
||||
except as required for reasonable and customary use in describing the
|
||||
origin of the Work and reproducing the content of the NOTICE file.
|
||||
|
||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||
agreed to in writing, Licensor provides the Work (and each
|
||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
implied, including, without limitation, any warranties or conditions
|
||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||
appropriateness of using or redistributing the Work and assume any
|
||||
risks associated with Your exercise of permissions under this License.
|
||||
|
||||
8. Limitation of Liability. In no event and under no legal theory,
|
||||
whether in tort (including negligence), contract, or otherwise,
|
||||
unless required by applicable law (such as deliberate and grossly
|
||||
negligent acts) or agreed to in writing, shall any Contributor be
|
||||
liable to You for damages, including any direct, indirect, special,
|
||||
incidental, or consequential damages of any character arising as a
|
||||
result of this License or out of the use or inability to use the
|
||||
Work (including but not limited to damages for loss of goodwill,
|
||||
work stoppage, computer failure or malfunction, or any and all
|
||||
other commercial damages or losses), even if such Contributor
|
||||
has been advised of the possibility of such damages.
|
||||
|
||||
9. Accepting Warranty or Additional Liability. While redistributing
|
||||
the Work or Derivative Works thereof, You may choose to offer,
|
||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||
or other liability obligations and/or rights consistent with this
|
||||
License. However, in accepting such obligations, You may act only
|
||||
on Your own behalf and on Your sole responsibility, not on behalf
|
||||
of any other Contributor, and only if You agree to indemnify,
|
||||
defend, and hold each Contributor harmless for any liability
|
||||
incurred by, or claims asserted against, such Contributor by reason
|
||||
of your accepting any such warranty or additional liability.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
2
browser/extensions/shumway/chrome.manifest
Normal file
2
browser/extensions/shumway/chrome.manifest
Normal file
@ -0,0 +1,2 @@
|
||||
resource shumway content/
|
||||
resource shumway.components components/
|
886
browser/extensions/shumway/components/FlashStreamConverter.js
Normal file
886
browser/extensions/shumway/components/FlashStreamConverter.js
Normal file
@ -0,0 +1,886 @@
|
||||
/* -*- Mode: js; js-indent-level: 2; indent-tabs-mode: nil; tab-width: 2 -*- */
|
||||
/* vim: set shiftwidth=2 tabstop=2 autoindent cindent expandtab: */
|
||||
/*
|
||||
* Copyright 2013 Mozilla Foundation
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
var EXPORTED_SYMBOLS = ['FlashStreamConverter1', 'FlashStreamConverter2'];
|
||||
|
||||
const Cc = Components.classes;
|
||||
const Ci = Components.interfaces;
|
||||
const Cr = Components.results;
|
||||
const Cu = Components.utils;
|
||||
|
||||
// True only if this is the version of pdf.js that is included with firefox.
|
||||
const SHUMWAY_CONTENT_TYPE = 'application/x-shockwave-flash';
|
||||
const EXPECTED_PLAYPREVIEW_URI_PREFIX = 'data:application/x-moz-playpreview;,' +
|
||||
SHUMWAY_CONTENT_TYPE;
|
||||
|
||||
const FIREFOX_ID = '{ec8030f7-c20a-464f-9b0e-13a3a9e97384}';
|
||||
const SEAMONKEY_ID = '{92650c4d-4b8e-4d2a-b7eb-24ecf4f6b63a}';
|
||||
|
||||
const MAX_CLIPBOARD_DATA_SIZE = 8000;
|
||||
|
||||
Cu.import('resource://gre/modules/XPCOMUtils.jsm');
|
||||
Cu.import('resource://gre/modules/Services.jsm');
|
||||
Cu.import('resource://gre/modules/NetUtil.jsm');
|
||||
|
||||
XPCOMUtils.defineLazyModuleGetter(this, 'PrivateBrowsingUtils',
|
||||
'resource://gre/modules/PrivateBrowsingUtils.jsm');
|
||||
|
||||
let appInfo = Cc['@mozilla.org/xre/app-info;1'].getService(Ci.nsIXULAppInfo);
|
||||
let Svc = {};
|
||||
XPCOMUtils.defineLazyServiceGetter(Svc, 'mime',
|
||||
'@mozilla.org/mime;1', 'nsIMIMEService');
|
||||
|
||||
let profiler = Cc["@mozilla.org/tools/profiler;1"].getService(Ci.nsIProfiler);
|
||||
|
||||
function getBoolPref(pref, def) {
|
||||
try {
|
||||
return Services.prefs.getBoolPref(pref);
|
||||
} catch (ex) {
|
||||
return def;
|
||||
}
|
||||
}
|
||||
|
||||
function getStringPref(pref, def) {
|
||||
try {
|
||||
return Services.prefs.getComplexValue(pref, Ci.nsISupportsString).data;
|
||||
} catch (ex) {
|
||||
return def;
|
||||
}
|
||||
}
|
||||
|
||||
function log(aMsg) {
|
||||
let msg = 'FlashStreamConverter.js: ' + (aMsg.join ? aMsg.join('') : aMsg);
|
||||
Services.console.logStringMessage(msg);
|
||||
dump(msg + '\n');
|
||||
}
|
||||
|
||||
function getDOMWindow(aChannel) {
|
||||
var requestor = aChannel.notificationCallbacks;
|
||||
var win = requestor.getInterface(Components.interfaces.nsIDOMWindow);
|
||||
return win;
|
||||
}
|
||||
|
||||
function parseQueryString(qs) {
|
||||
if (!qs)
|
||||
return {};
|
||||
|
||||
if (qs.charAt(0) == '?')
|
||||
qs = qs.slice(1);
|
||||
|
||||
var values = qs.split('&');
|
||||
var obj = {};
|
||||
for (var i = 0; i < values.length; i++) {
|
||||
var kv = values[i].split('=');
|
||||
var key = kv[0], value = kv[1];
|
||||
obj[decodeURIComponent(key)] = decodeURIComponent(value);
|
||||
}
|
||||
|
||||
return obj;
|
||||
}
|
||||
|
||||
function domainMatches(host, pattern) {
|
||||
if (!pattern) return false;
|
||||
if (pattern === '*') return true;
|
||||
host = host.toLowerCase();
|
||||
var parts = pattern.toLowerCase().split('*');
|
||||
if (host.indexOf(parts[0]) !== 0) return false;
|
||||
var p = parts[0].length;
|
||||
for (var i = 1; i < parts.length; i++) {
|
||||
var j = host.indexOf(parts[i], p);
|
||||
if (j === -1) return false;
|
||||
p = j + parts[i].length;
|
||||
}
|
||||
return parts[parts.length - 1] === '' || p === host.length;
|
||||
}
|
||||
|
||||
function fetchPolicyFile(url, cache, callback) {
|
||||
if (url in cache) {
|
||||
return callback(cache[url]);
|
||||
}
|
||||
|
||||
log('Fetching policy file at ' + url);
|
||||
var MAX_POLICY_SIZE = 8192;
|
||||
var xhr = Components.classes["@mozilla.org/xmlextras/xmlhttprequest;1"]
|
||||
.createInstance(Ci.nsIXMLHttpRequest);
|
||||
xhr.open('GET', url, true);
|
||||
xhr.overrideMimeType('text/xml');
|
||||
xhr.onprogress = function (e) {
|
||||
if (e.loaded >= MAX_POLICY_SIZE) {
|
||||
xhr.abort();
|
||||
cache[url] = false;
|
||||
callback(null, 'Max policy size');
|
||||
}
|
||||
};
|
||||
xhr.onreadystatechange = function(event) {
|
||||
if (xhr.readyState === 4) {
|
||||
// TODO disable redirects
|
||||
var doc = xhr.responseXML;
|
||||
if (xhr.status !== 200 || !doc) {
|
||||
cache[url] = false;
|
||||
return callback(null, 'Invalid HTTP status: ' + xhr.statusText);
|
||||
}
|
||||
// parsing params
|
||||
var params = doc.documentElement.childNodes;
|
||||
var policy = { siteControl: null, allowAccessFrom: []};
|
||||
for (var i = 0; i < params.length; i++) {
|
||||
switch (params[i].localName) {
|
||||
case 'site-control':
|
||||
policy.siteControl = params[i].getAttribute('permitted-cross-domain-policies');
|
||||
break;
|
||||
case 'allow-access-from':
|
||||
var access = {
|
||||
domain: params[i].getAttribute('domain'),
|
||||
security: params[i].getAttribute('security') === 'true'
|
||||
};
|
||||
policy.allowAccessFrom.push(access);
|
||||
break;
|
||||
default:
|
||||
// TODO allow-http-request-headers-from and other
|
||||
break;
|
||||
}
|
||||
}
|
||||
callback(cache[url] = policy);
|
||||
}
|
||||
};
|
||||
xhr.send(null);
|
||||
}
|
||||
|
||||
function isShumwayEnabledFor(actions) {
|
||||
// disabled for PrivateBrowsing windows
|
||||
if (PrivateBrowsingUtils.isWindowPrivate(actions.window)) {
|
||||
return false;
|
||||
}
|
||||
// disabled if embed tag specifies shumwaymode (for testing purpose)
|
||||
if (actions.objectParams['shumwaymode'] === 'off') {
|
||||
return false;
|
||||
}
|
||||
|
||||
var url = actions.url;
|
||||
var baseUrl = actions.baseUrl;
|
||||
|
||||
// blacklisting well known sites with issues
|
||||
if (/\.ytimg\.com\//i.test(url) /* youtube movies */ ||
|
||||
/\/vui.swf\b/i.test(url) /* vidyo manager */ ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// All the priviledged actions.
|
||||
function ChromeActions(url, window, document) {
|
||||
this.url = url;
|
||||
this.objectParams = null;
|
||||
this.movieParams = null;
|
||||
this.baseUrl = url;
|
||||
this.isOverlay = false;
|
||||
this.isPausedAtStart = false;
|
||||
this.window = window;
|
||||
this.document = document;
|
||||
this.externalComInitialized = false;
|
||||
this.allowScriptAccess = false;
|
||||
this.crossdomainRequestsCache = Object.create(null);
|
||||
}
|
||||
|
||||
ChromeActions.prototype = {
|
||||
getBoolPref: function (data) {
|
||||
if (!/^shumway\./.test(data.pref)) {
|
||||
return null;
|
||||
}
|
||||
return getBoolPref(data.pref, data.def);
|
||||
},
|
||||
getCompilerSettings: function getCompilerSettings() {
|
||||
return JSON.stringify({
|
||||
appCompiler: getBoolPref('shumway.appCompiler', true),
|
||||
sysCompiler: getBoolPref('shumway.sysCompiler', false),
|
||||
verifier: getBoolPref('shumway.verifier', true)
|
||||
});
|
||||
},
|
||||
addProfilerMarker: function (marker) {
|
||||
profiler.AddMarker(marker);
|
||||
},
|
||||
getPluginParams: function getPluginParams() {
|
||||
return JSON.stringify({
|
||||
url: this.url,
|
||||
baseUrl : this.baseUrl,
|
||||
movieParams: this.movieParams,
|
||||
objectParams: this.objectParams,
|
||||
isOverlay: this.isOverlay,
|
||||
isPausedAtStart: this.isPausedAtStart
|
||||
});
|
||||
},
|
||||
_canDownloadFile: function canDownloadFile(data, callback) {
|
||||
var url = data.url, checkPolicyFile = data.checkPolicyFile;
|
||||
|
||||
// TODO flash cross-origin request
|
||||
if (url === this.url) {
|
||||
// allow downloading for the original file
|
||||
return callback({success: true});
|
||||
}
|
||||
|
||||
// allows downloading from the same origin
|
||||
var urlPrefix = /^(https?):\/\/([A-Za-z0-9\-_\.\[\]]+)/i.exec(url);
|
||||
var basePrefix = /^(https?):\/\/([A-Za-z0-9\-_\.\[\]]+)/i.exec(this.url);
|
||||
if (basePrefix && urlPrefix && basePrefix[0] === urlPrefix[0]) {
|
||||
return callback({success: true});
|
||||
}
|
||||
|
||||
// additionally using internal whitelist
|
||||
var whitelist = getStringPref('shumway.whitelist', '');
|
||||
if (whitelist && urlPrefix) {
|
||||
var whitelisted = whitelist.split(',').some(function (i) {
|
||||
return domainMatches(urlPrefix[2], i);
|
||||
});
|
||||
if (whitelisted) {
|
||||
return callback({success: true});
|
||||
}
|
||||
}
|
||||
|
||||
if (!checkPolicyFile || !urlPrefix || !basePrefix) {
|
||||
return callback({success: false});
|
||||
}
|
||||
|
||||
// we can request crossdomain.xml
|
||||
fetchPolicyFile(urlPrefix[0] + '/crossdomain.xml', this.crossdomainRequestsCache,
|
||||
function (policy, error) {
|
||||
|
||||
if (!policy || policy.siteControl === 'none') {
|
||||
return callback({success: false});
|
||||
}
|
||||
// TODO assuming master-only, there are also 'by-content-type', 'all', etc.
|
||||
|
||||
var allowed = policy.allowAccessFrom.some(function (i) {
|
||||
return domainMatches(basePrefix[2], i.domain) &&
|
||||
(!i.secure || basePrefix[1].toLowerCase() === 'https');
|
||||
});
|
||||
return callback({success: allowed});
|
||||
}.bind(this));
|
||||
},
|
||||
loadFile: function loadFile(data) {
|
||||
var url = data.url;
|
||||
var checkPolicyFile = data.checkPolicyFile;
|
||||
var sessionId = data.sessionId;
|
||||
var limit = data.limit || 0;
|
||||
var method = data.method || "GET";
|
||||
var mimeType = data.mimeType;
|
||||
var postData = data.postData || null;
|
||||
|
||||
var win = this.window;
|
||||
var baseUrl = this.baseUrl;
|
||||
|
||||
var performXHR = function () {
|
||||
var xhr = Components.classes["@mozilla.org/xmlextras/xmlhttprequest;1"]
|
||||
.createInstance(Ci.nsIXMLHttpRequest);
|
||||
xhr.open(method, url, true);
|
||||
xhr.responseType = "moz-chunked-arraybuffer";
|
||||
|
||||
if (baseUrl) {
|
||||
// Setting the referer uri, some site doing checks if swf is embedded
|
||||
// on the original page.
|
||||
xhr.setRequestHeader("Referer", baseUrl);
|
||||
}
|
||||
|
||||
// TODO apply range request headers if limit is specified
|
||||
|
||||
var lastPosition = 0;
|
||||
xhr.onprogress = function (e) {
|
||||
var position = e.loaded;
|
||||
var data = new Uint8Array(xhr.response);
|
||||
win.postMessage({callback:"loadFile", sessionId: sessionId, topic: "progress",
|
||||
array: data, loaded: e.loaded, total: e.total}, "*");
|
||||
lastPosition = position;
|
||||
if (limit && e.total >= limit) {
|
||||
xhr.abort();
|
||||
}
|
||||
};
|
||||
xhr.onreadystatechange = function(event) {
|
||||
if (xhr.readyState === 4) {
|
||||
if (xhr.status !== 200 && xhr.status !== 0) {
|
||||
win.postMessage({callback:"loadFile", sessionId: sessionId, topic: "error",
|
||||
error: xhr.statusText}, "*");
|
||||
}
|
||||
win.postMessage({callback:"loadFile", sessionId: sessionId, topic: "close"}, "*");
|
||||
}
|
||||
};
|
||||
if (mimeType)
|
||||
xhr.setRequestHeader("Content-Type", mimeType);
|
||||
xhr.send(postData);
|
||||
win.postMessage({callback:"loadFile", sessionId: sessionId, topic: "open"}, "*");
|
||||
};
|
||||
|
||||
this._canDownloadFile({url: url, checkPolicyFile: checkPolicyFile}, function (data) {
|
||||
if (data.success) {
|
||||
performXHR();
|
||||
} else {
|
||||
log("data access id prohibited to " + url + " from " + baseUrl);
|
||||
win.postMessage({callback:"loadFile", sessionId: sessionId, topic: "error",
|
||||
error: "only original swf file or file from the same origin loading supported"}, "*");
|
||||
}
|
||||
});
|
||||
},
|
||||
fallback: function() {
|
||||
var obj = this.window.frameElement;
|
||||
var doc = obj.ownerDocument;
|
||||
var e = doc.createEvent("CustomEvent");
|
||||
e.initCustomEvent("MozPlayPlugin", true, true, null);
|
||||
obj.dispatchEvent(e);
|
||||
},
|
||||
setClipboard: function (data) {
|
||||
if (typeof data !== 'string' ||
|
||||
data.length > MAX_CLIPBOARD_DATA_SIZE ||
|
||||
!this.document.hasFocus()) {
|
||||
return;
|
||||
}
|
||||
// TODO other security checks?
|
||||
|
||||
let clipboard = Cc["@mozilla.org/widget/clipboardhelper;1"]
|
||||
.getService(Ci.nsIClipboardHelper);
|
||||
clipboard.copyString(data);
|
||||
},
|
||||
unsafeSetClipboard: function (data) {
|
||||
if (typeof data !== 'string') {
|
||||
return;
|
||||
}
|
||||
let clipboard = Cc["@mozilla.org/widget/clipboardhelper;1"].getService(Ci.nsIClipboardHelper);
|
||||
clipboard.copyString(data);
|
||||
},
|
||||
endActivation: function () {
|
||||
if (ActivationQueue.currentNonActive === this) {
|
||||
ActivationQueue.activateNext();
|
||||
}
|
||||
},
|
||||
externalCom: function (data) {
|
||||
if (!this.allowScriptAccess)
|
||||
return;
|
||||
|
||||
// TODO check security ?
|
||||
var parentWindow = this.window.parent.wrappedJSObject;
|
||||
var embedTag = this.embedTag.wrappedJSObject;
|
||||
switch (data.action) {
|
||||
case 'init':
|
||||
if (this.externalComInitialized)
|
||||
return;
|
||||
|
||||
this.externalComInitialized = true;
|
||||
var eventTarget = this.window.document;
|
||||
initExternalCom(parentWindow, embedTag, eventTarget);
|
||||
return;
|
||||
case 'getId':
|
||||
return embedTag.id;
|
||||
case 'eval':
|
||||
return parentWindow.__flash__eval(data.expression);
|
||||
case 'call':
|
||||
return parentWindow.__flash__call(data.request);
|
||||
case 'register':
|
||||
return embedTag.__flash__registerCallback(data.functionName);
|
||||
case 'unregister':
|
||||
return embedTag.__flash__unregisterCallback(data.functionName);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
// Event listener to trigger chrome privedged code.
|
||||
function RequestListener(actions) {
|
||||
this.actions = actions;
|
||||
}
|
||||
// Receive an event and synchronously or asynchronously responds.
|
||||
RequestListener.prototype.receive = function(event) {
|
||||
var message = event.target;
|
||||
var action = event.detail.action;
|
||||
var data = event.detail.data;
|
||||
var sync = event.detail.sync;
|
||||
var actions = this.actions;
|
||||
if (!(action in actions)) {
|
||||
log('Unknown action: ' + action);
|
||||
return;
|
||||
}
|
||||
if (sync) {
|
||||
var response = actions[action].call(this.actions, data);
|
||||
var detail = event.detail;
|
||||
detail.__exposedProps__ = {response: 'r'};
|
||||
detail.response = response;
|
||||
} else {
|
||||
var response;
|
||||
if (event.detail.callback) {
|
||||
var cookie = event.detail.cookie;
|
||||
response = function sendResponse(response) {
|
||||
var doc = actions.document;
|
||||
try {
|
||||
var listener = doc.createEvent('CustomEvent');
|
||||
listener.initCustomEvent('shumway.response', true, false,
|
||||
{response: response,
|
||||
cookie: cookie,
|
||||
__exposedProps__: {response: 'r', cookie: 'r'}});
|
||||
|
||||
return message.dispatchEvent(listener);
|
||||
} catch (e) {
|
||||
// doc is no longer accessible because the requestor is already
|
||||
// gone. unloaded content cannot receive the response anyway.
|
||||
}
|
||||
};
|
||||
}
|
||||
actions[action].call(this.actions, data, response);
|
||||
}
|
||||
};
|
||||
|
||||
var ActivationQueue = {
|
||||
nonActive: [],
|
||||
initializing: -1,
|
||||
activationTimeout: null,
|
||||
get currentNonActive() {
|
||||
return this.nonActive[this.initializing];
|
||||
},
|
||||
enqueue: function ActivationQueue_enqueue(actions) {
|
||||
this.nonActive.push(actions);
|
||||
if (this.nonActive.length === 1) {
|
||||
this.activateNext();
|
||||
}
|
||||
},
|
||||
activateNext: function ActivationQueue_activateNext() {
|
||||
function weightInstance(actions) {
|
||||
// set of heuristics for find the most important instance to load
|
||||
var weight = 0;
|
||||
// using linear distance to the top-left of the view area
|
||||
if (actions.embedTag) {
|
||||
var window = actions.window;
|
||||
var clientRect = actions.embedTag.getBoundingClientRect();
|
||||
weight -= Math.abs(clientRect.left - window.scrollX) +
|
||||
Math.abs(clientRect.top - window.scrollY);
|
||||
}
|
||||
var doc = actions.document;
|
||||
if (!doc.hidden) {
|
||||
weight += 100000; // might not be that important if hidden
|
||||
}
|
||||
if (actions.embedTag &&
|
||||
actions.embedTag.ownerDocument.hasFocus()) {
|
||||
weight += 10000; // parent document is focused
|
||||
}
|
||||
return weight;
|
||||
}
|
||||
|
||||
if (this.activationTimeout) {
|
||||
this.activationTimeout.cancel();
|
||||
this.activationTimeout = null;
|
||||
}
|
||||
|
||||
if (this.initializing >= 0) {
|
||||
this.nonActive.splice(this.initializing, 1);
|
||||
}
|
||||
var weights = [];
|
||||
for (var i = 0; i < this.nonActive.length; i++) {
|
||||
try {
|
||||
var weight = weightInstance(this.nonActive[i]);
|
||||
weights.push(weight);
|
||||
} catch (ex) {
|
||||
// unable to calc weight the instance, removing
|
||||
log('Shumway instance weight calculation failed: ' + ex);
|
||||
this.nonActive.splice(i, 1);
|
||||
i--;
|
||||
}
|
||||
}
|
||||
|
||||
do {
|
||||
if (this.nonActive.length === 0) {
|
||||
this.initializing = -1;
|
||||
return;
|
||||
}
|
||||
|
||||
var maxWeightIndex = 0;
|
||||
var maxWeight = weights[0];
|
||||
for (var i = 1; i < weights.length; i++) {
|
||||
if (maxWeight < weights[i]) {
|
||||
maxWeight = weights[i];
|
||||
maxWeightIndex = i;
|
||||
}
|
||||
}
|
||||
try {
|
||||
this.initializing = maxWeightIndex;
|
||||
this.nonActive[maxWeightIndex].activationCallback();
|
||||
break;
|
||||
} catch (ex) {
|
||||
// unable to initialize the instance, trying another one
|
||||
log('Shumway instance initialization failed: ' + ex);
|
||||
this.nonActive.splice(maxWeightIndex, 1);
|
||||
weights.splice(maxWeightIndex, 1);
|
||||
}
|
||||
} while (true);
|
||||
|
||||
var ACTIVATION_TIMEOUT = 3000;
|
||||
this.activationTimeout = Cc["@mozilla.org/timer;1"].createInstance(Ci.nsITimer);
|
||||
this.activationTimeout.initWithCallback(function () {
|
||||
log('Timeout during shumway instance initialization');
|
||||
this.activateNext();
|
||||
}.bind(this), ACTIVATION_TIMEOUT, Ci.nsITimer.TYPE_ONE_SHOT);
|
||||
}
|
||||
};
|
||||
|
||||
function activateShumwayScripts(window, preview) {
|
||||
function loadScripts(scripts, callback) {
|
||||
function scriptLoaded() {
|
||||
leftToLoad--;
|
||||
if (leftToLoad === 0) {
|
||||
callback();
|
||||
}
|
||||
}
|
||||
var leftToLoad = scripts.length;
|
||||
var document = window.document.wrappedJSObject;
|
||||
var head = document.getElementsByTagName('head')[0];
|
||||
for (var i = 0; i < scripts.length; i++) {
|
||||
var script = document.createElement('script');
|
||||
script.type = "text/javascript";
|
||||
script.src = scripts[i];
|
||||
script.onload = scriptLoaded;
|
||||
head.appendChild(script);
|
||||
}
|
||||
}
|
||||
|
||||
function initScripts() {
|
||||
if (preview) {
|
||||
loadScripts(['resource://shumway/web/preview.js'], function () {
|
||||
window.wrappedJSObject.runSniffer();
|
||||
});
|
||||
} else {
|
||||
loadScripts(['resource://shumway/shumway.js',
|
||||
'resource://shumway/web/avm-sandbox.js'], function () {
|
||||
window.wrappedJSObject.runViewer();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
window.wrappedJSObject.SHUMWAY_ROOT = "resource://shumway/";
|
||||
|
||||
if (window.document.readyState === "interactive" ||
|
||||
window.document.readyState === "complete") {
|
||||
initScripts();
|
||||
} else {
|
||||
window.document.addEventListener('DOMContentLoaded', initScripts);
|
||||
}
|
||||
}
|
||||
|
||||
function initExternalCom(wrappedWindow, wrappedObject, targetDocument) {
|
||||
if (!wrappedWindow.__flash__initialized) {
|
||||
wrappedWindow.__flash__initialized = true;
|
||||
wrappedWindow.__flash__toXML = function __flash__toXML(obj) {
|
||||
switch (typeof obj) {
|
||||
case 'boolean':
|
||||
return obj ? '<true/>' : '<false/>';
|
||||
case 'number':
|
||||
return '<number>' + obj + '</number>';
|
||||
case 'object':
|
||||
if (obj === null) {
|
||||
return '<null/>';
|
||||
}
|
||||
if ('hasOwnProperty' in obj && obj.hasOwnProperty('length')) {
|
||||
// array
|
||||
var xml = '<array>';
|
||||
for (var i = 0; i < obj.length; i++) {
|
||||
xml += '<property id="' + i + '">' + __flash__toXML(obj[i]) + '</property>';
|
||||
}
|
||||
return xml + '</array>';
|
||||
}
|
||||
var xml = '<object>';
|
||||
for (var i in obj) {
|
||||
xml += '<property id="' + i + '">' + __flash__toXML(obj[i]) + '</property>';
|
||||
}
|
||||
return xml + '</object>';
|
||||
case 'string':
|
||||
return '<string>' + obj.replace(/&/g, '&').replace(/</g, '<').replace(/>/g, '>') + '</string>';
|
||||
case 'undefined':
|
||||
return '<undefined/>';
|
||||
}
|
||||
};
|
||||
var sandbox = new Cu.Sandbox(wrappedWindow, {sandboxPrototype: wrappedWindow});
|
||||
wrappedWindow.__flash__eval = function (evalInSandbox, sandbox, expr) {
|
||||
this.console.log('__flash__eval: ' + expr);
|
||||
return evalInSandbox(expr, sandbox);
|
||||
}.bind(wrappedWindow, Cu.evalInSandbox, sandbox);
|
||||
wrappedWindow.__flash__call = function (expr) {
|
||||
this.console.log('__flash__call (ignored): ' + expr);
|
||||
};
|
||||
}
|
||||
wrappedObject.__flash__registerCallback = function (functionName) {
|
||||
wrappedWindow.console.log('__flash__registerCallback: ' + functionName);
|
||||
this[functionName] = function () {
|
||||
var args = Array.prototype.slice.call(arguments, 0);
|
||||
wrappedWindow.console.log('__flash__callIn: ' + functionName);
|
||||
var e = targetDocument.createEvent('CustomEvent');
|
||||
e.initCustomEvent('shumway.remote', true, false, {
|
||||
functionName: functionName,
|
||||
args: args,
|
||||
__exposedProps__: {args: 'r', functionName: 'r', result: 'rw'}
|
||||
});
|
||||
targetDocument.dispatchEvent(e);
|
||||
return e.detail.result;
|
||||
};
|
||||
};
|
||||
wrappedObject.__flash__unregisterCallback = function (functionName) {
|
||||
wrappedWindow.console.log('__flash__unregisterCallback: ' + functionName);
|
||||
delete this[functionName];
|
||||
};
|
||||
}
|
||||
|
||||
function FlashStreamConverterBase() {
|
||||
}
|
||||
|
||||
FlashStreamConverterBase.prototype = {
|
||||
QueryInterface: XPCOMUtils.generateQI([
|
||||
Ci.nsISupports,
|
||||
Ci.nsIStreamConverter,
|
||||
Ci.nsIStreamListener,
|
||||
Ci.nsIRequestObserver
|
||||
]),
|
||||
|
||||
/*
|
||||
* This component works as such:
|
||||
* 1. asyncConvertData stores the listener
|
||||
* 2. onStartRequest creates a new channel, streams the viewer and cancels
|
||||
* the request so Shumway can do the request
|
||||
* Since the request is cancelled onDataAvailable should not be called. The
|
||||
* onStopRequest does nothing. The convert function just returns the stream,
|
||||
* it's just the synchronous version of asyncConvertData.
|
||||
*/
|
||||
|
||||
// nsIStreamConverter::convert
|
||||
convert: function(aFromStream, aFromType, aToType, aCtxt) {
|
||||
throw Cr.NS_ERROR_NOT_IMPLEMENTED;
|
||||
},
|
||||
|
||||
isValidRequest: function() {
|
||||
return true;
|
||||
},
|
||||
|
||||
getUrlHint: function(requestUrl) {
|
||||
return requestUrl.spec;
|
||||
},
|
||||
|
||||
createChromeActions: function(window, document, urlHint) {
|
||||
var url;
|
||||
var baseUrl;
|
||||
var pageUrl;
|
||||
var element = window.frameElement;
|
||||
var isOverlay = false;
|
||||
var objectParams = {};
|
||||
if (element) {
|
||||
var tagName = element.nodeName;
|
||||
while (tagName != 'EMBED' && tagName != 'OBJECT') {
|
||||
// plugin overlay skipping until the target plugin is found
|
||||
isOverlay = true;
|
||||
element = element.parentNode;
|
||||
if (!element)
|
||||
throw 'Plugin element is not found';
|
||||
tagName = element.nodeName;
|
||||
}
|
||||
|
||||
// TODO: remove hack once bug 920927 is fixed
|
||||
element.style.visibility = 'visible';
|
||||
|
||||
pageUrl = element.ownerDocument.location.href; // proper page url?
|
||||
|
||||
if (tagName == 'EMBED') {
|
||||
for (var i = 0; i < element.attributes.length; ++i) {
|
||||
var paramName = element.attributes[i].localName.toLowerCase();
|
||||
objectParams[paramName] = element.attributes[i].value;
|
||||
}
|
||||
} else {
|
||||
url = element.getAttribute('data');
|
||||
for (var i = 0; i < element.childNodes.length; ++i) {
|
||||
var paramElement = element.childNodes[i];
|
||||
if (paramElement.nodeType != 1 ||
|
||||
paramElement.nodeName != 'PARAM') {
|
||||
continue;
|
||||
}
|
||||
var paramName = paramElement.getAttribute('name').toLowerCase();
|
||||
objectParams[paramName] = paramElement.getAttribute('value');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
url = url || objectParams.src || objectParams.movie;
|
||||
baseUrl = objectParams.base || pageUrl;
|
||||
|
||||
var movieParams = {};
|
||||
if (objectParams.flashvars) {
|
||||
movieParams = parseQueryString(objectParams.flashvars);
|
||||
}
|
||||
var queryStringMatch = /\?([^#]+)/.exec(url);
|
||||
if (queryStringMatch) {
|
||||
var queryStringParams = parseQueryString(queryStringMatch[1]);
|
||||
for (var i in queryStringParams) {
|
||||
if (!(i in movieParams)) {
|
||||
movieParams[i] = queryStringParams[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
url = !url ? urlHint : Services.io.newURI(url, null,
|
||||
baseUrl ? Services.io.newURI(baseUrl, null, null) : null).spec;
|
||||
|
||||
var allowScriptAccess = false;
|
||||
switch (objectParams.allowscriptaccess || 'sameDomain') {
|
||||
case 'always':
|
||||
allowScriptAccess = true;
|
||||
break;
|
||||
case 'never':
|
||||
allowScriptAccess = false;
|
||||
break;
|
||||
default:
|
||||
if (!pageUrl)
|
||||
break;
|
||||
try {
|
||||
// checking if page is in same domain (? same protocol and port)
|
||||
allowScriptAccess =
|
||||
Services.io.newURI('/', null, Services.io.newURI(pageUrl, null, null)).spec ==
|
||||
Services.io.newURI('/', null, Services.io.newURI(url, null, null)).spec;
|
||||
} catch (ex) {}
|
||||
break;
|
||||
}
|
||||
|
||||
var actions = new ChromeActions(url, window, document);
|
||||
actions.objectParams = objectParams;
|
||||
actions.movieParams = movieParams;
|
||||
actions.baseUrl = baseUrl || url;
|
||||
actions.isOverlay = isOverlay;
|
||||
actions.embedTag = element;
|
||||
actions.isPausedAtStart = /\bpaused=true$/.test(urlHint);
|
||||
actions.allowScriptAccess = allowScriptAccess;
|
||||
return actions;
|
||||
},
|
||||
|
||||
// nsIStreamConverter::asyncConvertData
|
||||
asyncConvertData: function(aFromType, aToType, aListener, aCtxt) {
|
||||
if(!this.isValidRequest(aCtxt))
|
||||
throw Cr.NS_ERROR_NOT_IMPLEMENTED;
|
||||
|
||||
// Store the listener passed to us
|
||||
this.listener = aListener;
|
||||
},
|
||||
|
||||
// nsIStreamListener::onDataAvailable
|
||||
onDataAvailable: function(aRequest, aContext, aInputStream, aOffset, aCount) {
|
||||
// Do nothing since all the data loading is handled by the viewer.
|
||||
log('SANITY CHECK: onDataAvailable SHOULD NOT BE CALLED!');
|
||||
},
|
||||
|
||||
// nsIRequestObserver::onStartRequest
|
||||
onStartRequest: function(aRequest, aContext) {
|
||||
// Setup the request so we can use it below.
|
||||
aRequest.QueryInterface(Ci.nsIChannel);
|
||||
// Cancel the request so the viewer can handle it.
|
||||
aRequest.cancel(Cr.NS_BINDING_ABORTED);
|
||||
|
||||
var originalURI = aRequest.URI;
|
||||
|
||||
// checking if the plug-in shall be run in simple mode
|
||||
var isSimpleMode = originalURI.spec === EXPECTED_PLAYPREVIEW_URI_PREFIX &&
|
||||
getBoolPref('shumway.simpleMode', false);
|
||||
|
||||
// Create a new channel that loads the viewer as a resource.
|
||||
var channel = Services.io.newChannel(isSimpleMode ?
|
||||
'resource://shumway/web/simple.html' :
|
||||
'resource://shumway/web/viewer.html', null, null);
|
||||
|
||||
var converter = this;
|
||||
var listener = this.listener;
|
||||
// Proxy all the request observer calls, when it gets to onStopRequest
|
||||
// we can get the dom window.
|
||||
var proxy = {
|
||||
onStartRequest: function() {
|
||||
listener.onStartRequest.apply(listener, arguments);
|
||||
},
|
||||
onDataAvailable: function() {
|
||||
listener.onDataAvailable.apply(listener, arguments);
|
||||
},
|
||||
onStopRequest: function() {
|
||||
var domWindow = getDOMWindow(channel);
|
||||
if (domWindow.document.documentURIObject.equals(channel.originalURI)) {
|
||||
// Double check the url is still the correct one.
|
||||
let actions = converter.createChromeActions(domWindow,
|
||||
domWindow.document,
|
||||
converter.getUrlHint(originalURI));
|
||||
if (!isShumwayEnabledFor(actions)) {
|
||||
actions.fallback();
|
||||
return;
|
||||
}
|
||||
|
||||
actions.activationCallback = function(domWindow, isSimpleMode) {
|
||||
delete this.activationCallback;
|
||||
activateShumwayScripts(domWindow, isSimpleMode);
|
||||
}.bind(actions, domWindow, isSimpleMode);
|
||||
ActivationQueue.enqueue(actions);
|
||||
|
||||
let requestListener = new RequestListener(actions);
|
||||
domWindow.addEventListener('shumway.message', function(event) {
|
||||
requestListener.receive(event);
|
||||
}, false, true);
|
||||
}
|
||||
listener.onStopRequest.apply(listener, arguments);
|
||||
}
|
||||
};
|
||||
|
||||
// XXX? Keep the URL the same so the browser sees it as the same.
|
||||
// channel.originalURI = aRequest.URI;
|
||||
channel.asyncOpen(proxy, aContext);
|
||||
},
|
||||
|
||||
// nsIRequestObserver::onStopRequest
|
||||
onStopRequest: function(aRequest, aContext, aStatusCode) {
|
||||
// Do nothing.
|
||||
}
|
||||
};
|
||||
|
||||
// properties required for XPCOM registration:
|
||||
function copyProperties(obj, template) {
|
||||
for (var prop in template) {
|
||||
obj[prop] = template[prop];
|
||||
}
|
||||
}
|
||||
|
||||
function FlashStreamConverter1() {}
|
||||
FlashStreamConverter1.prototype = new FlashStreamConverterBase();
|
||||
copyProperties(FlashStreamConverter1.prototype, {
|
||||
classID: Components.ID('{4c6030f7-e20a-264f-5b0e-ada3a9e97384}'),
|
||||
classDescription: 'Shumway Content Converter Component',
|
||||
contractID: '@mozilla.org/streamconv;1?from=application/x-shockwave-flash&to=*/*'
|
||||
});
|
||||
|
||||
function FlashStreamConverter2() {}
|
||||
FlashStreamConverter2.prototype = new FlashStreamConverterBase();
|
||||
copyProperties(FlashStreamConverter2.prototype, {
|
||||
classID: Components.ID('{4c6030f7-e20a-264f-5f9b-ada3a9e97384}'),
|
||||
classDescription: 'Shumway PlayPreview Component',
|
||||
contractID: '@mozilla.org/streamconv;1?from=application/x-moz-playpreview&to=*/*'
|
||||
});
|
||||
FlashStreamConverter2.prototype.isValidRequest =
|
||||
(function(aCtxt) {
|
||||
try {
|
||||
var request = aCtxt;
|
||||
request.QueryInterface(Ci.nsIChannel);
|
||||
var spec = request.URI.spec;
|
||||
return spec.indexOf(EXPECTED_PLAYPREVIEW_URI_PREFIX) === 0;
|
||||
} catch (e) {
|
||||
return false;
|
||||
}
|
||||
});
|
||||
FlashStreamConverter2.prototype.getUrlHint = function (requestUrl) {
|
||||
return '';
|
||||
};
|
||||
|
||||
var NSGetFactory1 = XPCOMUtils.generateNSGetFactory([FlashStreamConverter1]);
|
||||
var NSGetFactory2 = XPCOMUtils.generateNSGetFactory([FlashStreamConverter2]);
|
155
browser/extensions/shumway/content/ShumwayUtils.jsm
Normal file
155
browser/extensions/shumway/content/ShumwayUtils.jsm
Normal file
@ -0,0 +1,155 @@
|
||||
/* Copyright 2012 Mozilla Foundation
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
var EXPORTED_SYMBOLS = ["ShumwayUtils"];
|
||||
|
||||
const RESOURCE_NAME = 'shumway';
|
||||
const EXT_PREFIX = 'shumway@research.mozilla.org';
|
||||
const SWF_CONTENT_TYPE = 'application/x-shockwave-flash';
|
||||
const PREF_PREFIX = 'shumway.';
|
||||
const PREF_DISABLED = PREF_PREFIX + 'disabled';
|
||||
const PREF_IGNORE_CTP = PREF_PREFIX + 'ignoreCTP';
|
||||
|
||||
let Cc = Components.classes;
|
||||
let Ci = Components.interfaces;
|
||||
let Cm = Components.manager;
|
||||
let Cu = Components.utils;
|
||||
|
||||
Cu.import('resource://gre/modules/XPCOMUtils.jsm');
|
||||
Cu.import('resource://gre/modules/Services.jsm');
|
||||
Cu.import('resource://shumway.components/FlashStreamConverter.js');
|
||||
|
||||
let Svc = {};
|
||||
XPCOMUtils.defineLazyServiceGetter(Svc, 'mime',
|
||||
'@mozilla.org/mime;1',
|
||||
'nsIMIMEService');
|
||||
XPCOMUtils.defineLazyServiceGetter(Svc, 'pluginHost',
|
||||
'@mozilla.org/plugin/host;1',
|
||||
'nsIPluginHost');
|
||||
|
||||
function getBoolPref(pref, def) {
|
||||
try {
|
||||
return Services.prefs.getBoolPref(pref);
|
||||
} catch (ex) {
|
||||
return def;
|
||||
}
|
||||
}
|
||||
|
||||
function log(str) {
|
||||
dump(str + '\n');
|
||||
}
|
||||
|
||||
// Register/unregister a constructor as a component.
|
||||
function Factory() {}
|
||||
|
||||
Factory.prototype = {
|
||||
QueryInterface: XPCOMUtils.generateQI([Ci.nsIFactory]),
|
||||
_targetConstructor: null,
|
||||
|
||||
register: function register(targetConstructor) {
|
||||
this._targetConstructor = targetConstructor;
|
||||
var proto = targetConstructor.prototype;
|
||||
var registrar = Cm.QueryInterface(Ci.nsIComponentRegistrar);
|
||||
registrar.registerFactory(proto.classID, proto.classDescription,
|
||||
proto.contractID, this);
|
||||
},
|
||||
|
||||
unregister: function unregister() {
|
||||
var proto = this._targetConstructor.prototype;
|
||||
var registrar = Cm.QueryInterface(Ci.nsIComponentRegistrar);
|
||||
registrar.unregisterFactory(proto.classID, this);
|
||||
this._targetConstructor = null;
|
||||
},
|
||||
|
||||
// nsIFactory
|
||||
createInstance: function createInstance(aOuter, iid) {
|
||||
if (aOuter !== null)
|
||||
throw Cr.NS_ERROR_NO_AGGREGATION;
|
||||
return (new (this._targetConstructor)).QueryInterface(iid);
|
||||
},
|
||||
|
||||
// nsIFactory
|
||||
lockFactory: function lockFactory(lock) {
|
||||
// No longer used as of gecko 1.7.
|
||||
throw Cr.NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
};
|
||||
|
||||
let factory1 = new Factory();
|
||||
let factory2 = new Factory();
|
||||
|
||||
let ShumwayUtils = {
|
||||
QueryInterface: XPCOMUtils.generateQI([Ci.nsIObserver]),
|
||||
_registered: false,
|
||||
|
||||
init: function init() {
|
||||
if (this.enabled)
|
||||
this._ensureRegistered();
|
||||
else
|
||||
this._ensureUnregistered();
|
||||
|
||||
// Listen for when shumway is completely disabled.
|
||||
Services.prefs.addObserver(PREF_DISABLED, this, false);
|
||||
},
|
||||
|
||||
// nsIObserver
|
||||
observe: function observe(aSubject, aTopic, aData) {
|
||||
if (this.enabled)
|
||||
this._ensureRegistered();
|
||||
else
|
||||
this._ensureUnregistered();
|
||||
},
|
||||
|
||||
/**
|
||||
* shumway is only enabled if it is both selected as the pdf viewer and if the
|
||||
* global switch enabling it is true.
|
||||
* @return {boolean} Wether or not it's enabled.
|
||||
*/
|
||||
get enabled() {
|
||||
return !getBoolPref(PREF_DISABLED, true);
|
||||
},
|
||||
|
||||
_ensureRegistered: function _ensureRegistered() {
|
||||
if (this._registered)
|
||||
return;
|
||||
|
||||
// Load the component and register it.
|
||||
factory1.register(FlashStreamConverter1);
|
||||
factory2.register(FlashStreamConverter2);
|
||||
|
||||
var ignoreCTP = getBoolPref(PREF_IGNORE_CTP, true);
|
||||
|
||||
Svc.pluginHost.registerPlayPreviewMimeType(SWF_CONTENT_TYPE, ignoreCTP);
|
||||
|
||||
this._registered = true;
|
||||
|
||||
log('Shumway is registered');
|
||||
},
|
||||
|
||||
_ensureUnregistered: function _ensureUnregistered() {
|
||||
if (!this._registered)
|
||||
return;
|
||||
|
||||
// Remove the contract/component.
|
||||
factory1.unregister();
|
||||
factory2.unregister();
|
||||
|
||||
Svc.pluginHost.unregisterPlayPreviewMimeType(SWF_CONTENT_TYPE);
|
||||
|
||||
this._registered = false;
|
||||
|
||||
log('Shumway is unregistered');
|
||||
}
|
||||
};
|
Binary file not shown.
Binary file not shown.
BIN
browser/extensions/shumway/content/flash/playerglobal.abc
Normal file
BIN
browser/extensions/shumway/content/flash/playerglobal.abc
Normal file
Binary file not shown.
6607
browser/extensions/shumway/content/shumway-worker.js
Normal file
6607
browser/extensions/shumway/content/shumway-worker.js
Normal file
File diff suppressed because it is too large
Load Diff
50052
browser/extensions/shumway/content/shumway.js
Normal file
50052
browser/extensions/shumway/content/shumway.js
Normal file
File diff suppressed because one or more lines are too long
1
browser/extensions/shumway/content/version.txt
Normal file
1
browser/extensions/shumway/content/version.txt
Normal file
@ -0,0 +1 @@
|
||||
0.7.351
|
263
browser/extensions/shumway/content/web/avm-sandbox.js
Normal file
263
browser/extensions/shumway/content/web/avm-sandbox.js
Normal file
@ -0,0 +1,263 @@
|
||||
/* -*- Mode: js; js-indent-level: 2; indent-tabs-mode: nil; tab-width: 2 -*- */
|
||||
/* vim: set shiftwidth=2 tabstop=2 autoindent cindent expandtab: */
|
||||
/*
|
||||
* Copyright 2013 Mozilla Foundation
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
// Extension communication object... as it used in pdf.js
|
||||
var FirefoxCom = (function FirefoxComClosure() {
|
||||
return {
|
||||
/**
|
||||
* Creates an event that the extension is listening for and will
|
||||
* synchronously respond to.
|
||||
* NOTE: It is reccomended to use request() instead since one day we may not
|
||||
* be able to synchronously reply.
|
||||
* @param {String} action The action to trigger.
|
||||
* @param {String} data Optional data to send.
|
||||
* @return {*} The response.
|
||||
*/
|
||||
requestSync: function(action, data) {
|
||||
var e = document.createEvent('CustomEvent');
|
||||
e.initCustomEvent('shumway.message', true, false,
|
||||
{action: action, data: data, sync: true});
|
||||
document.dispatchEvent(e);
|
||||
return e.detail.response;
|
||||
},
|
||||
/**
|
||||
* Creates an event that the extension is listening for and will
|
||||
* asynchronously respond by calling the callback.
|
||||
* @param {String} action The action to trigger.
|
||||
* @param {String} data Optional data to send.
|
||||
* @param {Function} callback Optional response callback that will be called
|
||||
* with one data argument.
|
||||
*/
|
||||
request: function(action, data, callback) {
|
||||
var e = document.createEvent('CustomEvent');
|
||||
e.initCustomEvent('shumway.message', true, false,
|
||||
{action: action, data: data, sync: false});
|
||||
if (callback) {
|
||||
if ('nextId' in FirefoxCom.request) {
|
||||
FirefoxCom.request.nextId = 1;
|
||||
}
|
||||
var cookie = "requestId" + (FirefoxCom.request.nextId++);
|
||||
e.detail.cookie = cookie;
|
||||
e.detail.callback = true;
|
||||
|
||||
document.addEventListener('shumway.response', function listener(event) {
|
||||
if (cookie !== event.detail.cookie)
|
||||
return;
|
||||
|
||||
document.removeEventListener('shumway.response', listener, false);
|
||||
|
||||
var response = event.detail.response;
|
||||
return callback(response);
|
||||
}, false);
|
||||
}
|
||||
return document.dispatchEvent(e);
|
||||
},
|
||||
initJS: function (callback) {
|
||||
FirefoxCom.request('externalCom', {action: 'init'});
|
||||
document.addEventListener('shumway.remote', function (e) {
|
||||
e.detail.result = callback(e.detail.functionName, e.detail.args);
|
||||
}, false);
|
||||
}
|
||||
};
|
||||
})();
|
||||
|
||||
function fallback() {
|
||||
FirefoxCom.requestSync('fallback', null)
|
||||
}
|
||||
|
||||
function runViewer() {
|
||||
var flashParams = JSON.parse(FirefoxCom.requestSync('getPluginParams', null));
|
||||
FileLoadingService.setBaseUrl(flashParams.baseUrl);
|
||||
|
||||
movieUrl = flashParams.url;
|
||||
if (!movieUrl) {
|
||||
console.log("no movie url provided -- stopping here");
|
||||
FirefoxCom.request('endActivation', null);
|
||||
return;
|
||||
}
|
||||
|
||||
movieParams = flashParams.movieParams;
|
||||
objectParams = flashParams.objectParams;
|
||||
var isOverlay = flashParams.isOverlay;
|
||||
pauseExecution = flashParams.isPausedAtStart;
|
||||
|
||||
console.log("url=" + movieUrl + ";params=" + uneval(movieParams));
|
||||
if (movieParams.fmt_list && movieParams.url_encoded_fmt_stream_map) {
|
||||
// HACK removing FLVs from the fmt_list
|
||||
movieParams.fmt_list = movieParams.fmt_list.split(',').filter(function (s) {
|
||||
var fid = s.split('/')[0];
|
||||
return fid !== '5' && fid !== '34' && fid !== '35'; // more?
|
||||
}).join(',');
|
||||
}
|
||||
|
||||
parseSwf(movieUrl, movieParams, objectParams);
|
||||
|
||||
if (isOverlay) {
|
||||
var fallbackDiv = document.getElementById('fallback');
|
||||
fallbackDiv.className = 'enabled';
|
||||
fallbackDiv.addEventListener('click', function(e) {
|
||||
fallback();
|
||||
e.preventDefault();
|
||||
});
|
||||
var fallbackMenu = document.getElementById('fallbackMenu');
|
||||
fallbackMenu.removeAttribute('hidden');
|
||||
fallbackMenu.addEventListener('click', fallback);
|
||||
}
|
||||
var showURLMenu = document.getElementById('showURLMenu');
|
||||
showURLMenu.addEventListener('click', showURL);
|
||||
|
||||
document.getElementById('copyProfileMenu').addEventListener('click', copyProfile);
|
||||
}
|
||||
|
||||
function showURL() {
|
||||
var flashParams = JSON.parse(FirefoxCom.requestSync('getPluginParams', null));
|
||||
window.prompt("Copy to clipboard", flashParams.url);
|
||||
}
|
||||
|
||||
function copyProfile() {
|
||||
function toArray(v) {
|
||||
var array = [];
|
||||
for (var i = 0; i < v.length; i++) {
|
||||
array.push(v[i]);
|
||||
}
|
||||
return array;
|
||||
}
|
||||
var profile = {
|
||||
loops: {counts: toArray($L), lines: $LL},
|
||||
functions: {counts: toArray($F), lines: $FL},
|
||||
allocations: {counts: toArray($A), lines: $AL}
|
||||
};
|
||||
FirefoxCom.request('unsafeSetClipboard', JSON.stringify(profile));
|
||||
}
|
||||
|
||||
var movieUrl, movieParams, objectParams;
|
||||
|
||||
window.addEventListener("message", function handlerMessage(e) {
|
||||
var args = e.data;
|
||||
switch (args.callback) {
|
||||
case "loadFile":
|
||||
var session = FileLoadingService.sessions[args.sessionId];
|
||||
if (session) {
|
||||
session.notify(args);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}, true);
|
||||
|
||||
var FileLoadingService = {
|
||||
get baseUrl() { return movieUrl; },
|
||||
nextSessionId: 1, // 0 - is reserved
|
||||
sessions: [],
|
||||
createSession: function () {
|
||||
var sessionId = this.nextSessionId++;
|
||||
return this.sessions[sessionId] = {
|
||||
open: function (request) {
|
||||
var self = this;
|
||||
var path = FileLoadingService.resolveUrl(request.url);
|
||||
console.log('Session #' + sessionId +': loading ' + path);
|
||||
FirefoxCom.requestSync('loadFile', {url: path, method: request.method,
|
||||
mimeType: request.mimeType, postData: request.data,
|
||||
checkPolicyFile: request.checkPolicyFile, sessionId: sessionId});
|
||||
},
|
||||
notify: function (args) {
|
||||
switch (args.topic) {
|
||||
case "open": this.onopen(); break;
|
||||
case "close":
|
||||
this.onclose();
|
||||
delete FileLoadingService.sessions[sessionId];
|
||||
console.log('Session #' + sessionId +': closed');
|
||||
break;
|
||||
case "error":
|
||||
this.onerror && this.onerror(args.error);
|
||||
break;
|
||||
case "progress":
|
||||
console.log('Session #' + sessionId + ': loaded ' + args.loaded + '/' + args.total);
|
||||
this.onprogress && this.onprogress(args.array, {bytesLoaded: args.loaded, bytesTotal: args.total});
|
||||
break;
|
||||
}
|
||||
}
|
||||
};
|
||||
},
|
||||
setBaseUrl: function (url) {
|
||||
var a = document.createElement('a');
|
||||
a.href = url || '#';
|
||||
a.setAttribute('style', 'display: none;');
|
||||
document.body.appendChild(a);
|
||||
FileLoadingService.baseUrl = a.href;
|
||||
document.body.removeChild(a);
|
||||
},
|
||||
resolveUrl: function (url) {
|
||||
if (url.indexOf('://') >= 0) return url;
|
||||
|
||||
var base = FileLoadingService.baseUrl;
|
||||
base = base.lastIndexOf('/') >= 0 ? base.substring(0, base.lastIndexOf('/') + 1) : '';
|
||||
if (url.indexOf('/') === 0) {
|
||||
var m = /^[^:]+:\/\/[^\/]+/.exec(base);
|
||||
if (m) base = m[0];
|
||||
}
|
||||
return base + url;
|
||||
}
|
||||
};
|
||||
|
||||
function parseSwf(url, movieParams, objectParams) {
|
||||
var compilerSettings = JSON.parse(
|
||||
FirefoxCom.requestSync('getCompilerSettings', null));
|
||||
enableVerifier.value = compilerSettings.verifier;
|
||||
|
||||
console.log("Compiler settings: " + JSON.stringify(compilerSettings));
|
||||
console.log("Parsing " + url + "...");
|
||||
function loaded() {
|
||||
FirefoxCom.request('endActivation', null);
|
||||
}
|
||||
|
||||
createAVM2(builtinPath, playerGlobalPath, avm1Path,
|
||||
compilerSettings.sysCompiler ? EXECUTION_MODE.COMPILE : EXECUTION_MODE.INTERPRET,
|
||||
compilerSettings.appCompiler ? EXECUTION_MODE.COMPILE : EXECUTION_MODE.INTERPRET,
|
||||
function (avm2) {
|
||||
console.time("Initialize Renderer");
|
||||
SWF.embed(url, document, document.getElementById("viewer"), {
|
||||
url: url,
|
||||
movieParams: movieParams,
|
||||
objectParams: objectParams,
|
||||
onComplete: loaded,
|
||||
onBeforeFrame: frame
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
var pauseExecution = false;
|
||||
var initializeFrameControl = true;
|
||||
function frame(e) {
|
||||
if (initializeFrameControl) {
|
||||
// marking that movie is started
|
||||
document.body.classList.add("started");
|
||||
|
||||
// skipping frame 0
|
||||
initializeFrameControl = false;
|
||||
return;
|
||||
}
|
||||
if (pauseExecution) {
|
||||
e.cancel = true;
|
||||
}
|
||||
}
|
||||
|
||||
document.addEventListener('keydown', function (e) {
|
||||
if (e.keyCode == 119 && e.ctrlKey) { // Ctrl+F8
|
||||
pauseExecution = !pauseExecution;
|
||||
}
|
||||
}, false);
|
219
browser/extensions/shumway/content/web/preview.js
Normal file
219
browser/extensions/shumway/content/web/preview.js
Normal file
@ -0,0 +1,219 @@
|
||||
/* -*- Mode: js; js-indent-level: 2; indent-tabs-mode: nil; tab-width: 2 -*- */
|
||||
/* vim: set shiftwidth=2 tabstop=2 autoindent cindent expandtab: */
|
||||
/*
|
||||
* Copyright 2013 Mozilla Foundation
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
|
||||
// Extenstion communication object... as it used in pdf.js
|
||||
var FirefoxCom = (function FirefoxComClosure() {
|
||||
return {
|
||||
/**
|
||||
* Creates an event that the extension is listening for and will
|
||||
* synchronously respond to.
|
||||
* NOTE: It is reccomended to use request() instead since one day we may not
|
||||
* be able to synchronously reply.
|
||||
* @param {String} action The action to trigger.
|
||||
* @param {String} data Optional data to send.
|
||||
* @return {*} The response.
|
||||
*/
|
||||
requestSync: function(action, data) {
|
||||
var request = document.createTextNode('');
|
||||
document.documentElement.appendChild(request);
|
||||
|
||||
var sender = document.createEvent('CustomEvent');
|
||||
sender.initCustomEvent('shumway.message', true, false,
|
||||
{action: action, data: data, sync: true});
|
||||
request.dispatchEvent(sender);
|
||||
var response = sender.detail.response;
|
||||
document.documentElement.removeChild(request);
|
||||
return response;
|
||||
},
|
||||
/**
|
||||
* Creates an event that the extension is listening for and will
|
||||
* asynchronously respond by calling the callback.
|
||||
* @param {String} action The action to trigger.
|
||||
* @param {String} data Optional data to send.
|
||||
* @param {Function} callback Optional response callback that will be called
|
||||
* with one data argument.
|
||||
*/
|
||||
request: function(action, data, callback) {
|
||||
var request = document.createTextNode('');
|
||||
request.setUserData('action', action, null);
|
||||
request.setUserData('data', data, null);
|
||||
request.setUserData('sync', false, null);
|
||||
if (callback) {
|
||||
request.setUserData('callback', callback, null);
|
||||
|
||||
document.addEventListener('shumway.response', function listener(event) {
|
||||
var node = event.target,
|
||||
response = event.detail.response;
|
||||
|
||||
document.documentElement.removeChild(node);
|
||||
|
||||
document.removeEventListener('shumway.response', listener, false);
|
||||
return callback(response);
|
||||
}, false);
|
||||
}
|
||||
document.documentElement.appendChild(request);
|
||||
|
||||
var sender = document.createEvent('CustomEvent');
|
||||
sender.initCustomEvent('shumway.message', true, false,
|
||||
{action: action, data: data, sync: false});
|
||||
return request.dispatchEvent(sender);
|
||||
}
|
||||
};
|
||||
})();
|
||||
|
||||
function fallback() {
|
||||
FirefoxCom.requestSync('fallback', null)
|
||||
}
|
||||
|
||||
var BYTES_TO_LOAD = 32768;
|
||||
var BYTES_TO_PARSE = 32768;
|
||||
|
||||
function runSniffer() {
|
||||
var flashParams = JSON.parse(FirefoxCom.requestSync('getPluginParams', null));
|
||||
document.head.getElementsByTagName('base')[0].href = flashParams.baseUrl;
|
||||
movieUrl = flashParams.url;
|
||||
document.getElementById('playbutton').addEventListener('click', function() {
|
||||
switchToFullMode();
|
||||
});
|
||||
document.getElementById('fullmode').addEventListener('click', function() {
|
||||
switchToFullMode();
|
||||
return false;
|
||||
});
|
||||
document.getElementById('fallback').addEventListener('click', function() {
|
||||
fallback();
|
||||
return false;
|
||||
});
|
||||
FirefoxCom.requestSync('loadFile', {url: movieUrl, sessionId: 0, limit: BYTES_TO_LOAD});
|
||||
}
|
||||
|
||||
var subscription, movieUrl, buffers = [];;
|
||||
|
||||
addEventListener("message", function handlerMessage(e) {
|
||||
var args = e.data;
|
||||
switch (args.callback) {
|
||||
case "loadFile":
|
||||
if (args.sessionId != 0) {
|
||||
return;
|
||||
}
|
||||
switch (args.topic) {
|
||||
case "progress":
|
||||
buffers.push(args.array);
|
||||
break;
|
||||
case "error":
|
||||
console.error('Unable to download ' + movieUrl + ': ' + args.error);
|
||||
break;
|
||||
case "close":
|
||||
parseSwf();
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}, true);
|
||||
|
||||
function inflateData(bytes, outputLength) {
|
||||
verifyDeflateHeader(bytes);
|
||||
var stream = new Stream(bytes, 2);
|
||||
var output = {
|
||||
data: new Uint8Array(outputLength),
|
||||
available: 0,
|
||||
completed: false
|
||||
};
|
||||
var state = {};
|
||||
// inflate while we can
|
||||
try {
|
||||
do {
|
||||
inflateBlock(stream, output, state);
|
||||
} while (!output.completed && stream.pos < stream.end
|
||||
&& output.available < outputLength);
|
||||
} catch (e) {
|
||||
console.log('inflate aborted: ' + e);
|
||||
}
|
||||
return new Stream(output.data, 0, Math.min(output.available, outputLength));
|
||||
}
|
||||
|
||||
function parseSwf() {
|
||||
var sum = 0;
|
||||
for (var i = 0; i < buffers.length; i++)
|
||||
sum += buffers[i].length;
|
||||
var data = new Uint8Array(sum), j = 0;
|
||||
for (var i = 0; i < buffers.length; i++) {
|
||||
data.set(buffers[i], j); j += buffers[i].length;
|
||||
}
|
||||
|
||||
var backgroundColor;
|
||||
try {
|
||||
var magic1 = data[0];
|
||||
var magic2 = data[1];
|
||||
var magic3 = data[2];
|
||||
if ((magic1 !== 70 && magic1 !== 67) || magic2 !== 87 || magic3 !== 83)
|
||||
throw new Error('unsupported file format');
|
||||
|
||||
var compressed = magic1 === 67;
|
||||
var stream = compressed ? inflateData(data.subarray(8), BYTES_TO_PARSE) :
|
||||
new Stream(data, 8, data.length - 8);
|
||||
var bytes = stream.bytes;
|
||||
|
||||
var SWF_TAG_CODE_SET_BACKGROUND_COLOR = 9;
|
||||
var PREFETCH_SIZE = 17 /* RECT */ +
|
||||
4 /* Frames rate and count */;;
|
||||
stream.ensure(PREFETCH_SIZE);
|
||||
var rectFieldSize = bytes[stream.pos] >> 3;
|
||||
stream.pos += ((5 + 4 * rectFieldSize + 7) >> 3) + 4; // skipping other header fields
|
||||
|
||||
// for now just sniffing background color
|
||||
while (stream.pos < stream.end &&
|
||||
!backgroundColor) {
|
||||
stream.ensure(2);
|
||||
var tagCodeAndLength = stream.getUint16(stream.pos, true);
|
||||
stream.pos += 2;
|
||||
var tagCode = tagCodeAndLength >> 6;
|
||||
var length = tagCodeAndLength & 0x3F;
|
||||
if (length == 0x3F) {
|
||||
stream.ensure(4);
|
||||
length = stream.getInt32(stream.pos, true);
|
||||
stream.pos += 4;
|
||||
if (length < 0) throw new Error('invalid length');
|
||||
}
|
||||
stream.ensure(length);
|
||||
switch (tagCode) {
|
||||
case SWF_TAG_CODE_SET_BACKGROUND_COLOR:
|
||||
backgroundColor = 'rgb(' + bytes[stream.pos] + ', ' +
|
||||
bytes[stream.pos + 1] + ', ' +
|
||||
bytes[stream.pos + 2] + ')';
|
||||
break;
|
||||
}
|
||||
stream.pos += length;
|
||||
}
|
||||
} catch (e) {
|
||||
console.log('parsing aborted: ' + e);
|
||||
}
|
||||
if (backgroundColor) {
|
||||
document.body.style.backgroundColor = backgroundColor;
|
||||
}
|
||||
}
|
||||
|
||||
document.addEventListener('keydown', function (e) {
|
||||
if (e.keyCode == 119 && e.ctrlKey) { // Ctrl+F8
|
||||
window.location.replace("data:application/x-moz-playpreview;,application/x-shockwave-flash,full,paused=true");
|
||||
}
|
||||
}, false);
|
||||
|
||||
function switchToFullMode() {
|
||||
window.location.replace("data:application/x-moz-playpreview;,application/x-shockwave-flash,full");
|
||||
}
|
130
browser/extensions/shumway/content/web/simple.html
Normal file
130
browser/extensions/shumway/content/web/simple.html
Normal file
@ -0,0 +1,130 @@
|
||||
<!DOCTYPE html>
|
||||
<!--
|
||||
Copyright 2013 Mozilla Foundation
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
-->
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
|
||||
<base href=""/>
|
||||
|
||||
<script src="../lib/DataView.js/DataView.js"></script>
|
||||
|
||||
<!-- Load SWF Dependencies -->
|
||||
<script src="../swf/util.js"></script>
|
||||
<script src="../swf/inflate.js"></script>
|
||||
<script src="../swf/stream.js"></script>
|
||||
|
||||
<style>
|
||||
body {
|
||||
margin: 0;
|
||||
overflow: hidden;
|
||||
background-color: rgba(128, 128, 128, 0.5);
|
||||
font-family: sans-serif;
|
||||
}
|
||||
#screen {
|
||||
position: fixed;
|
||||
top: 0; left: 0; right: 0; bottom: 0;
|
||||
}
|
||||
#container {
|
||||
position: fixed;
|
||||
top: 50%; left: 0; right: 0; bottom: 50%;
|
||||
}
|
||||
#content {
|
||||
margin-top: -64px;
|
||||
text-align: center;
|
||||
}
|
||||
#playbutton {
|
||||
background-color: transparent;
|
||||
background-image: url(chrome://global/skin/media/videoClickToPlayButton.svg);
|
||||
border: none 0px;
|
||||
width: 64px;
|
||||
height: 64px;
|
||||
display: block;
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
cursor: pointer;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
#playbutton > span {
|
||||
overflow: hidden;
|
||||
width: 0px; height: 0px;
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
@media screen and (max-width: 160px) , screen and (max-height: 160px) {
|
||||
#playbutton {
|
||||
display: none;
|
||||
}
|
||||
#content {
|
||||
margin-top: -6px;
|
||||
}
|
||||
}
|
||||
|
||||
#screen {
|
||||
transition: opacity 0.5s linear;
|
||||
-webkit-transition: opacity 0.5s linear;
|
||||
opacity: 0.1;
|
||||
}
|
||||
|
||||
#screen:hover {
|
||||
opacity: 1.0;
|
||||
}
|
||||
|
||||
.shumwayButton {
|
||||
background:-webkit-gradient( linear, left top, left bottom, color-stop(0.05, #f9f9f9), color-stop(1, #e9e9e9) );
|
||||
background:-moz-linear-gradient( center top, #f9f9f9 5%, #e9e9e9 100% );
|
||||
background-color:#f9f9f9;
|
||||
-moz-border-radius:4px;
|
||||
-webkit-border-radius:4px;
|
||||
border-radius:4px;
|
||||
border:1px solid #a0a0a0;
|
||||
display:inline-block;
|
||||
color:#666666;
|
||||
font-family:arial;
|
||||
font-size:11px;
|
||||
font-weight:bold;
|
||||
padding:6px 11px;
|
||||
text-decoration:none;
|
||||
text-shadow:1px 1px 0px #ffffff;
|
||||
width: 70px;
|
||||
cursor: pointer;
|
||||
}
|
||||
.shumwayButton:hover {
|
||||
background:-webkit-gradient( linear, left top, left bottom, color-stop(0.05, #e9e9e9), color-stop(1, #f9f9f9) );
|
||||
background:-moz-linear-gradient( center top, #e9e9e9 5%, #f9f9f9 100% );
|
||||
background-color:#e9e9e9;
|
||||
}
|
||||
.shumwayButton:active {
|
||||
position:relative;
|
||||
top:1px;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<div id='screen'>
|
||||
<div id='container'>
|
||||
<div id='content'>
|
||||
<button id='playbutton'><span>Play</span></button>
|
||||
<div id='toolbar'>
|
||||
<a class="shumwayButton" id="fullmode">Shumway</a>
|
||||
<a class="shumwayButton" id="fallback">Flash</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
90
browser/extensions/shumway/content/web/viewer.html
Normal file
90
browser/extensions/shumway/content/web/viewer.html
Normal file
@ -0,0 +1,90 @@
|
||||
<!DOCTYPE html>
|
||||
<!--
|
||||
Copyright 2013 Mozilla Foundation
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
-->
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
|
||||
<base href=""/>
|
||||
<title>Shumway viewer</title>
|
||||
|
||||
<style>
|
||||
body {
|
||||
margin: 0;
|
||||
overflow: hidden;
|
||||
background-color: rgba(0, 0, 0, 0.78);
|
||||
}
|
||||
|
||||
body.started {
|
||||
background-color: transparent;
|
||||
}
|
||||
|
||||
#viewer {
|
||||
position:fixed !important;
|
||||
left:0;top:0;bottom:0;right:0;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
#fallback {
|
||||
display: none;
|
||||
}
|
||||
|
||||
#fallback.enabled {
|
||||
display: block;
|
||||
position:fixed;
|
||||
color: white;
|
||||
right: 0px; bottom: 0px; width: 70px; height: 16px;
|
||||
padding: 4px;
|
||||
padding-top: 8px;
|
||||
background-color: rgba(0, 0, 0, 0.62);
|
||||
font: bold 10px sans-serif;
|
||||
text-align: center;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
#fallback .icon {
|
||||
display: none;
|
||||
color: white;
|
||||
}
|
||||
|
||||
#fallback.enabled:hover .icon {
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
#fallback:hover {
|
||||
background-color: rgb(0, 0, 0);
|
||||
}
|
||||
|
||||
@media screen and (max-width: 100px), screen and (max-height: 40px) {
|
||||
body.started #fallback {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
|
||||
<body contextmenu="shumwayMenu">
|
||||
<div id="viewer"></div>
|
||||
<section>
|
||||
<a id="fallback" href="#">Shumway <span class="icon">×</span></a>
|
||||
<menu type="context" id="shumwayMenu">
|
||||
<menuitem label="Show URL" id="showURLMenu"></menuitem>
|
||||
<menuitem label="Copy Profile" id="copyProfileMenu"></menuitem>
|
||||
<menuitem label="Fallback to Flash" id="fallbackMenu" hidden></menuitem>
|
||||
</menu>
|
||||
</section>
|
||||
</body>
|
||||
</html>
|
@ -593,6 +593,8 @@
|
||||
@BINPATH@/browser/chrome/browser.manifest
|
||||
@BINPATH@/browser/chrome/pdfjs.manifest
|
||||
@BINPATH@/browser/chrome/pdfjs/*
|
||||
@BINPATH@/browser/chrome/shumway.manifest
|
||||
@BINPATH@/browser/chrome/shumway/*
|
||||
@BINPATH@/browser/extensions/{972ce4c6-7e08-4474-a285-3208198ce6fd}/install.rdf
|
||||
@BINPATH@/browser/extensions/{972ce4c6-7e08-4474-a285-3208198ce6fd}/icon.png
|
||||
@BINPATH@/chrome/toolkit@JAREXT@
|
||||
|
@ -504,13 +504,13 @@ class Variables(object):
|
||||
|
||||
return (None, None, None)
|
||||
|
||||
def set(self, name, flavor, source, value):
|
||||
def set(self, name, flavor, source, value, force=False):
|
||||
assert flavor in (self.FLAVOR_RECURSIVE, self.FLAVOR_SIMPLE)
|
||||
assert source in (self.SOURCE_OVERRIDE, self.SOURCE_COMMANDLINE, self.SOURCE_MAKEFILE, self.SOURCE_ENVIRONMENT, self.SOURCE_AUTOMATIC, self.SOURCE_IMPLICIT)
|
||||
assert isinstance(value, str_type), "expected str, got %s" % type(value)
|
||||
|
||||
prevflavor, prevsource, prevvalue = self.get(name)
|
||||
if prevsource is not None and source > prevsource:
|
||||
if prevsource is not None and source > prevsource and not force:
|
||||
# TODO: give a location for this warning
|
||||
_log.info("not setting variable '%s', set by higher-priority source to value '%s'" % (name, prevvalue))
|
||||
return
|
||||
|
@ -649,7 +649,11 @@ class ForEachFunction(Function):
|
||||
else:
|
||||
fd.write(' ')
|
||||
|
||||
v.set(vname, data.Variables.FLAVOR_SIMPLE, data.Variables.SOURCE_AUTOMATIC, w)
|
||||
# The $(origin) of the local variable must be "automatic" to
|
||||
# conform with GNU make. However, automatic variables have low
|
||||
# priority. So, we must force its assignment to occur.
|
||||
v.set(vname, data.Variables.FLAVOR_SIMPLE,
|
||||
data.Variables.SOURCE_AUTOMATIC, w, force=True)
|
||||
e.resolve(makefile, v, fd, setting)
|
||||
|
||||
class CallFunction(Function):
|
||||
|
8
build/pymake/tests/foreach-local-variable.mk
Normal file
8
build/pymake/tests/foreach-local-variable.mk
Normal file
@ -0,0 +1,8 @@
|
||||
# This test ensures that a local variable in a $(foreach) is bound to
|
||||
# the local value, not a global value.
|
||||
i := dummy
|
||||
|
||||
all:
|
||||
test "$(foreach i,foo bar,found:$(i))" = "found:foo found:bar"
|
||||
test "$(i)" = "dummy"
|
||||
@echo TEST-PASS
|
@ -227,6 +227,7 @@ interface nsIScriptSecurityManager : nsIXPCSecurityManager
|
||||
|
||||
const unsigned long NO_APP_ID = 0;
|
||||
const unsigned long UNKNOWN_APP_ID = 4294967295; // UINT32_MAX
|
||||
const unsigned long SAFEBROWSING_APP_ID = 4294967294; // UINT32_MAX - 1
|
||||
|
||||
/**
|
||||
* Returns the jar prefix for the app.
|
||||
|
@ -109,6 +109,7 @@ NS_CP_ContentTypeName(uint32_t contentType)
|
||||
CASE_RETURN( TYPE_MEDIA );
|
||||
CASE_RETURN( TYPE_WEBSOCKET );
|
||||
CASE_RETURN( TYPE_CSP_REPORT );
|
||||
CASE_RETURN( TYPE_XSLT );
|
||||
default:
|
||||
return "<Unknown Type>";
|
||||
}
|
||||
|
@ -140,8 +140,13 @@ interface nsIContentPolicy : nsISupports
|
||||
*/
|
||||
const nsContentPolicyType TYPE_CSP_REPORT = 17;
|
||||
|
||||
/**
|
||||
* Indicates a style sheet transformation.
|
||||
*/
|
||||
const nsContentPolicyType TYPE_XSLT = 18;
|
||||
|
||||
/* When adding new content types, please update nsContentBlocker,
|
||||
* NS_CP_ContentTypeName, contentScurityPolicy.js, all nsIContentPolicy
|
||||
* NS_CP_ContentTypeName, contentSecurityPolicy.js, all nsIContentPolicy
|
||||
* implementations, and other things that are not listed here that are
|
||||
* related to nsIContentPolicy. */
|
||||
|
||||
|
@ -289,7 +289,7 @@ interface nsIMessageBroadcaster : nsIMessageListenerManager
|
||||
nsIMessageListenerManager getChildAt(in unsigned long aIndex);
|
||||
};
|
||||
|
||||
[scriptable, builtinclass, uuid(83be5862-2996-4685-ae7d-ae25bd795d50)]
|
||||
[scriptable, builtinclass, uuid(79eeb70f-58e3-4d32-b46f-106f42ada12b)]
|
||||
interface nsISyncMessageSender : nsIMessageSender
|
||||
{
|
||||
/**
|
||||
@ -301,6 +301,20 @@ interface nsISyncMessageSender : nsIMessageSender
|
||||
jsval sendSyncMessage([optional] in AString messageName,
|
||||
[optional] in jsval obj,
|
||||
[optional] in jsval objects);
|
||||
|
||||
/**
|
||||
* Like |sendSyncMessage()|, except re-entrant. New RPC messages may be
|
||||
* issued even if, earlier on the call stack, we are waiting for a reply
|
||||
* to an earlier sendRpcMessage() call.
|
||||
*
|
||||
* Both sendSyncMessage and sendRpcMessage will block until a reply is
|
||||
* received, but they may be temporarily interrupted to process an urgent
|
||||
* incoming message (such as a CPOW request).
|
||||
*/
|
||||
[implicit_jscontext, optional_argc]
|
||||
jsval sendRpcMessage([optional] in AString messageName,
|
||||
[optional] in jsval obj,
|
||||
[optional] in jsval objects);
|
||||
};
|
||||
|
||||
[scriptable, builtinclass, uuid(894ff2d4-39a3-4df8-9d76-8ee329975488)]
|
||||
|
@ -88,6 +88,7 @@ function ContentSecurityPolicy() {
|
||||
csp._MAPPINGS[cp.TYPE_SUBDOCUMENT] = cspr_sd_new.FRAME_SRC;
|
||||
csp._MAPPINGS[cp.TYPE_MEDIA] = cspr_sd_new.MEDIA_SRC;
|
||||
csp._MAPPINGS[cp.TYPE_FONT] = cspr_sd_new.FONT_SRC;
|
||||
csp._MAPPINGS[cp.TYPE_XSLT] = cspr_sd_new.SCRIPT_SRC;
|
||||
|
||||
/* Our original CSP implementation's mappings for XHR and websocket
|
||||
* These should be changed to be = cspr_sd.CONNECT_SRC when we remove
|
||||
@ -620,8 +621,6 @@ ContentSecurityPolicy.prototype = {
|
||||
CSPdebug("shouldLoad location = " + aContentLocation.asciiSpec);
|
||||
CSPdebug("shouldLoad content type = " + aContentType);
|
||||
#endif
|
||||
// interpret the context, and then pass off to the decision structure
|
||||
var cspContext = ContentSecurityPolicy._MAPPINGS[aContentType];
|
||||
|
||||
// The mapping for XHR and websockets is different between our original
|
||||
// implementation and the 1.0 spec, we handle this here.
|
||||
|
@ -122,7 +122,8 @@ nsDataDocumentContentPolicy::ShouldLoad(uint32_t aContentType,
|
||||
if (aContentType == nsIContentPolicy::TYPE_OBJECT ||
|
||||
aContentType == nsIContentPolicy::TYPE_DOCUMENT ||
|
||||
aContentType == nsIContentPolicy::TYPE_SUBDOCUMENT ||
|
||||
aContentType == nsIContentPolicy::TYPE_SCRIPT) {
|
||||
aContentType == nsIContentPolicy::TYPE_SCRIPT ||
|
||||
aContentType == nsIContentPolicy::TYPE_XSLT) {
|
||||
*aDecision = nsIContentPolicy::REJECT_TYPE;
|
||||
}
|
||||
|
||||
|
@ -41,6 +41,9 @@
|
||||
#endif
|
||||
#ifdef XP_WIN
|
||||
#include <windows.h>
|
||||
# if defined(SendMessage)
|
||||
# undef SendMessage
|
||||
# endif
|
||||
#endif
|
||||
|
||||
using namespace mozilla;
|
||||
@ -439,6 +442,8 @@ GetParamsForMessage(JSContext* aCx,
|
||||
|
||||
// nsISyncMessageSender
|
||||
|
||||
static bool sSendingSyncMessage = false;
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsFrameMessageManager::SendSyncMessage(const nsAString& aMessageName,
|
||||
const JS::Value& aJSON,
|
||||
@ -446,6 +451,29 @@ nsFrameMessageManager::SendSyncMessage(const nsAString& aMessageName,
|
||||
JSContext* aCx,
|
||||
uint8_t aArgc,
|
||||
JS::Value* aRetval)
|
||||
{
|
||||
return SendMessage(aMessageName, aJSON, aObjects, aCx, aArgc, aRetval, true);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsFrameMessageManager::SendRpcMessage(const nsAString& aMessageName,
|
||||
const JS::Value& aJSON,
|
||||
const JS::Value& aObjects,
|
||||
JSContext* aCx,
|
||||
uint8_t aArgc,
|
||||
JS::Value* aRetval)
|
||||
{
|
||||
return SendMessage(aMessageName, aJSON, aObjects, aCx, aArgc, aRetval, false);
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsFrameMessageManager::SendMessage(const nsAString& aMessageName,
|
||||
const JS::Value& aJSON,
|
||||
const JS::Value& aObjects,
|
||||
JSContext* aCx,
|
||||
uint8_t aArgc,
|
||||
JS::Value* aRetval,
|
||||
bool aIsSync)
|
||||
{
|
||||
NS_ASSERTION(!IsGlobal(), "Should not call SendSyncMessage in chrome");
|
||||
NS_ASSERTION(!IsWindowLevel(), "Should not call SendSyncMessage in chrome");
|
||||
@ -454,6 +482,11 @@ nsFrameMessageManager::SendSyncMessage(const nsAString& aMessageName,
|
||||
*aRetval = JSVAL_VOID;
|
||||
NS_ENSURE_TRUE(mCallback, NS_ERROR_NOT_INITIALIZED);
|
||||
|
||||
if (sSendingSyncMessage && aIsSync) {
|
||||
// No kind of blocking send should be issued on top of a sync message.
|
||||
return NS_ERROR_UNEXPECTED;
|
||||
}
|
||||
|
||||
StructuredCloneData data;
|
||||
JSAutoStructuredCloneBuffer buffer;
|
||||
if (aArgc >= 2 &&
|
||||
@ -469,27 +502,36 @@ nsFrameMessageManager::SendSyncMessage(const nsAString& aMessageName,
|
||||
}
|
||||
|
||||
InfallibleTArray<nsString> retval;
|
||||
if (mCallback->DoSendSyncMessage(aCx, aMessageName, data, objects, &retval)) {
|
||||
uint32_t len = retval.Length();
|
||||
JS::Rooted<JSObject*> dataArray(aCx, JS_NewArrayObject(aCx, len, nullptr));
|
||||
NS_ENSURE_TRUE(dataArray, NS_ERROR_OUT_OF_MEMORY);
|
||||
|
||||
for (uint32_t i = 0; i < len; ++i) {
|
||||
if (retval[i].IsEmpty()) {
|
||||
continue;
|
||||
}
|
||||
sSendingSyncMessage |= aIsSync;
|
||||
bool rv = mCallback->DoSendBlockingMessage(aCx, aMessageName, data, objects, &retval, aIsSync);
|
||||
if (aIsSync) {
|
||||
sSendingSyncMessage = false;
|
||||
}
|
||||
|
||||
JS::Rooted<JS::Value> ret(aCx);
|
||||
if (!JS_ParseJSON(aCx, static_cast<const jschar*>(retval[i].get()),
|
||||
retval[i].Length(), &ret)) {
|
||||
return NS_ERROR_UNEXPECTED;
|
||||
}
|
||||
NS_ENSURE_TRUE(JS_SetElement(aCx, dataArray, i, &ret),
|
||||
NS_ERROR_OUT_OF_MEMORY);
|
||||
if (!rv) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
uint32_t len = retval.Length();
|
||||
JS::Rooted<JSObject*> dataArray(aCx, JS_NewArrayObject(aCx, len, nullptr));
|
||||
NS_ENSURE_TRUE(dataArray, NS_ERROR_OUT_OF_MEMORY);
|
||||
|
||||
for (uint32_t i = 0; i < len; ++i) {
|
||||
if (retval[i].IsEmpty()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
*aRetval = OBJECT_TO_JSVAL(dataArray);
|
||||
JS::Rooted<JS::Value> ret(aCx);
|
||||
if (!JS_ParseJSON(aCx, static_cast<const jschar*>(retval[i].get()),
|
||||
retval[i].Length(), &ret)) {
|
||||
return NS_ERROR_UNEXPECTED;
|
||||
}
|
||||
NS_ENSURE_TRUE(JS_SetElement(aCx, dataArray, i, &ret),
|
||||
NS_ERROR_OUT_OF_MEMORY);
|
||||
}
|
||||
|
||||
*aRetval = OBJECT_TO_JSVAL(dataArray);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
@ -744,7 +786,7 @@ public:
|
||||
nsresult
|
||||
nsFrameMessageManager::ReceiveMessage(nsISupports* aTarget,
|
||||
const nsAString& aMessage,
|
||||
bool aSync,
|
||||
bool aIsSync,
|
||||
const StructuredCloneData* aCloneData,
|
||||
CpowHolder* aCpows,
|
||||
InfallibleTArray<nsString>* aJSONRetVal)
|
||||
@ -824,7 +866,7 @@ nsFrameMessageManager::ReceiveMessage(nsISupports* aTarget,
|
||||
JS_DefineProperty(ctx, param, "name",
|
||||
STRING_TO_JSVAL(jsMessage), nullptr, nullptr, JSPROP_ENUMERATE);
|
||||
JS_DefineProperty(ctx, param, "sync",
|
||||
BOOLEAN_TO_JSVAL(aSync), nullptr, nullptr, JSPROP_ENUMERATE);
|
||||
BOOLEAN_TO_JSVAL(aIsSync), nullptr, nullptr, JSPROP_ENUMERATE);
|
||||
JS_DefineProperty(ctx, param, "json", json, nullptr, nullptr, JSPROP_ENUMERATE); // deprecated
|
||||
JS_DefineProperty(ctx, param, "data", json, nullptr, nullptr, JSPROP_ENUMERATE);
|
||||
JS_DefineProperty(ctx, param, "objects", cpowsv, nullptr, nullptr, JSPROP_ENUMERATE);
|
||||
@ -865,8 +907,9 @@ nsFrameMessageManager::ReceiveMessage(nsISupports* aTarget,
|
||||
JS::Rooted<JSObject*> thisObject(ctx, thisValue.toObjectOrNull());
|
||||
|
||||
JSAutoCompartment tac(ctx, thisObject);
|
||||
if (!JS_WrapValue(ctx, argv.address()))
|
||||
if (!JS_WrapValue(ctx, argv.address())) {
|
||||
return NS_ERROR_UNEXPECTED;
|
||||
}
|
||||
|
||||
JS_CallFunctionValue(ctx, thisObject,
|
||||
funval, 1, argv.address(), rval.address());
|
||||
@ -883,7 +926,7 @@ nsFrameMessageManager::ReceiveMessage(nsISupports* aTarget,
|
||||
}
|
||||
nsRefPtr<nsFrameMessageManager> kungfuDeathGrip = mParentManager;
|
||||
return mParentManager ? mParentManager->ReceiveMessage(aTarget, aMessage,
|
||||
aSync, aCloneData,
|
||||
aIsSync, aCloneData,
|
||||
aCpows,
|
||||
aJSONRetVal) : NS_OK;
|
||||
}
|
||||
@ -1281,11 +1324,12 @@ public:
|
||||
MOZ_COUNT_DTOR(ChildProcessMessageManagerCallback);
|
||||
}
|
||||
|
||||
virtual bool DoSendSyncMessage(JSContext* aCx,
|
||||
const nsAString& aMessage,
|
||||
const mozilla::dom::StructuredCloneData& aData,
|
||||
JS::Handle<JSObject *> aCpows,
|
||||
InfallibleTArray<nsString>* aJSONRetVal)
|
||||
virtual bool DoSendBlockingMessage(JSContext* aCx,
|
||||
const nsAString& aMessage,
|
||||
const mozilla::dom::StructuredCloneData& aData,
|
||||
JS::Handle<JSObject *> aCpows,
|
||||
InfallibleTArray<nsString>* aJSONRetVal,
|
||||
bool aIsSync) MOZ_OVERRIDE
|
||||
{
|
||||
mozilla::dom::ContentChild* cc =
|
||||
mozilla::dom::ContentChild::GetSingleton();
|
||||
@ -1300,13 +1344,16 @@ public:
|
||||
if (!cc->GetCPOWManager()->Wrap(aCx, aCpows, &cpows)) {
|
||||
return false;
|
||||
}
|
||||
return cc->SendSyncMessage(nsString(aMessage), data, cpows, aJSONRetVal);
|
||||
if (aIsSync) {
|
||||
return cc->SendSyncMessage(nsString(aMessage), data, cpows, aJSONRetVal);
|
||||
}
|
||||
return cc->CallRpcMessage(nsString(aMessage), data, cpows, aJSONRetVal);
|
||||
}
|
||||
|
||||
virtual bool DoSendAsyncMessage(JSContext* aCx,
|
||||
const nsAString& aMessage,
|
||||
const mozilla::dom::StructuredCloneData& aData,
|
||||
JS::Handle<JSObject *> aCpows)
|
||||
JS::Handle<JSObject *> aCpows) MOZ_OVERRIDE
|
||||
{
|
||||
mozilla::dom::ContentChild* cc =
|
||||
mozilla::dom::ContentChild::GetSingleton();
|
||||
@ -1396,11 +1443,12 @@ public:
|
||||
MOZ_COUNT_DTOR(SameChildProcessMessageManagerCallback);
|
||||
}
|
||||
|
||||
virtual bool DoSendSyncMessage(JSContext* aCx,
|
||||
const nsAString& aMessage,
|
||||
const mozilla::dom::StructuredCloneData& aData,
|
||||
JS::Handle<JSObject *> aCpows,
|
||||
InfallibleTArray<nsString>* aJSONRetVal)
|
||||
virtual bool DoSendBlockingMessage(JSContext* aCx,
|
||||
const nsAString& aMessage,
|
||||
const mozilla::dom::StructuredCloneData& aData,
|
||||
JS::Handle<JSObject *> aCpows,
|
||||
InfallibleTArray<nsString>* aJSONRetVal,
|
||||
bool aIsSync) MOZ_OVERRIDE
|
||||
{
|
||||
nsTArray<nsCOMPtr<nsIRunnable> > asyncMessages;
|
||||
if (nsFrameMessageManager::sPendingSameProcessAsyncMessages) {
|
||||
|
@ -54,11 +54,12 @@ public:
|
||||
return true;
|
||||
}
|
||||
|
||||
virtual bool DoSendSyncMessage(JSContext* aCx,
|
||||
const nsAString& aMessage,
|
||||
const mozilla::dom::StructuredCloneData& aData,
|
||||
JS::Handle<JSObject *> aCpows,
|
||||
InfallibleTArray<nsString>* aJSONRetVal)
|
||||
virtual bool DoSendBlockingMessage(JSContext* aCx,
|
||||
const nsAString& aMessage,
|
||||
const mozilla::dom::StructuredCloneData& aData,
|
||||
JS::Handle<JSObject *> aCpows,
|
||||
InfallibleTArray<nsString>* aJSONRetVal,
|
||||
bool aIsSync)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
@ -208,7 +209,7 @@ public:
|
||||
NewProcessMessageManager(mozilla::dom::ContentParent* aProcess);
|
||||
|
||||
nsresult ReceiveMessage(nsISupports* aTarget, const nsAString& aMessage,
|
||||
bool aSync, const StructuredCloneData* aCloneData,
|
||||
bool aIsSync, const StructuredCloneData* aCloneData,
|
||||
CpowHolder* aCpows,
|
||||
InfallibleTArray<nsString>* aJSONRetVal);
|
||||
|
||||
@ -255,6 +256,14 @@ public:
|
||||
{
|
||||
return sChildProcessManager;
|
||||
}
|
||||
private:
|
||||
nsresult SendMessage(const nsAString& aMessageName,
|
||||
const JS::Value& aJSON,
|
||||
const JS::Value& aObjects,
|
||||
JSContext* aCx,
|
||||
uint8_t aArgc,
|
||||
JS::Value* aRetval,
|
||||
bool aIsSync);
|
||||
protected:
|
||||
friend class MMListenerRemover;
|
||||
nsTArray<nsMessageListenerInfo> mListeners;
|
||||
|
@ -26,11 +26,12 @@ using mozilla::dom::StructuredCloneData;
|
||||
using mozilla::dom::StructuredCloneClosure;
|
||||
|
||||
bool
|
||||
nsInProcessTabChildGlobal::DoSendSyncMessage(JSContext* aCx,
|
||||
const nsAString& aMessage,
|
||||
const mozilla::dom::StructuredCloneData& aData,
|
||||
JS::Handle<JSObject *> aCpows,
|
||||
InfallibleTArray<nsString>* aJSONRetVal)
|
||||
nsInProcessTabChildGlobal::DoSendBlockingMessage(JSContext* aCx,
|
||||
const nsAString& aMessage,
|
||||
const mozilla::dom::StructuredCloneData& aData,
|
||||
JS::Handle<JSObject *> aCpows,
|
||||
InfallibleTArray<nsString>* aJSONRetVal,
|
||||
bool aIsSync)
|
||||
{
|
||||
nsTArray<nsCOMPtr<nsIRunnable> > asyncMessages;
|
||||
asyncMessages.SwapElements(mASyncMessages);
|
||||
|
@ -51,6 +51,17 @@ public:
|
||||
? mMessageManager->SendSyncMessage(aMessageName, aObject, aRemote, aCx, aArgc, aRetval)
|
||||
: NS_ERROR_NULL_POINTER;
|
||||
}
|
||||
NS_IMETHOD SendRpcMessage(const nsAString& aMessageName,
|
||||
const JS::Value& aObject,
|
||||
const JS::Value& aRemote,
|
||||
JSContext* aCx,
|
||||
uint8_t aArgc,
|
||||
JS::Value* aRetval)
|
||||
{
|
||||
return mMessageManager
|
||||
? mMessageManager->SendRpcMessage(aMessageName, aObject, aRemote, aCx, aArgc, aRetval)
|
||||
: NS_ERROR_NULL_POINTER;
|
||||
}
|
||||
NS_IMETHOD GetContent(nsIDOMWindow** aContent) MOZ_OVERRIDE;
|
||||
NS_IMETHOD GetDocShell(nsIDocShell** aDocShell) MOZ_OVERRIDE;
|
||||
NS_IMETHOD Dump(const nsAString& aStr) MOZ_OVERRIDE
|
||||
@ -68,11 +79,12 @@ public:
|
||||
/**
|
||||
* MessageManagerCallback methods that we override.
|
||||
*/
|
||||
virtual bool DoSendSyncMessage(JSContext* aCx,
|
||||
const nsAString& aMessage,
|
||||
const mozilla::dom::StructuredCloneData& aData,
|
||||
JS::Handle<JSObject *> aCpows,
|
||||
InfallibleTArray<nsString>* aJSONRetVal) MOZ_OVERRIDE;
|
||||
virtual bool DoSendBlockingMessage(JSContext* aCx,
|
||||
const nsAString& aMessage,
|
||||
const mozilla::dom::StructuredCloneData& aData,
|
||||
JS::Handle<JSObject *> aCpows,
|
||||
InfallibleTArray<nsString>* aJSONRetVal,
|
||||
bool aIsSync) MOZ_OVERRIDE;
|
||||
virtual bool DoSendAsyncMessage(JSContext* aCx,
|
||||
const nsAString& aMessage,
|
||||
const mozilla::dom::StructuredCloneData& aData,
|
||||
|
@ -300,6 +300,7 @@ nsMixedContentBlocker::ShouldLoad(uint32_t aContentType,
|
||||
case TYPE_SUBDOCUMENT:
|
||||
case TYPE_XBL:
|
||||
case TYPE_XMLHTTPREQUEST:
|
||||
case TYPE_XSLT:
|
||||
case TYPE_OTHER:
|
||||
break;
|
||||
|
||||
|
@ -31,6 +31,12 @@ class nsFrameLoader;
|
||||
class nsXULElement;
|
||||
class nsPluginInstanceOwner;
|
||||
|
||||
namespace mozilla {
|
||||
namespace dom {
|
||||
template<typename T> class Sequence;
|
||||
}
|
||||
}
|
||||
|
||||
class nsObjectLoadingContent : public nsImageLoadingContent
|
||||
, public nsIStreamListener
|
||||
, public nsIFrameLoaderOwner
|
||||
|
@ -5,6 +5,8 @@ content.document.title = "Hello, Kitty";
|
||||
(function start() {
|
||||
sync_test();
|
||||
async_test();
|
||||
rpc_test();
|
||||
nested_sync_test();
|
||||
// The sync-ness of this call is important, because otherwise
|
||||
// we tear down the child's document while we are
|
||||
// still in the async test in the parent.
|
||||
@ -72,3 +74,35 @@ function async_test()
|
||||
async_obj);
|
||||
}
|
||||
|
||||
function rpc_test()
|
||||
{
|
||||
dump('beginning cpow rpc test\n');
|
||||
rpc_obj = make_object();
|
||||
rpc_obj.data.reenter = function () {
|
||||
sendRpcMessage("cpows:reenter", { }, { data: { valid: true } });
|
||||
return "ok";
|
||||
}
|
||||
sendRpcMessage("cpows:rpc",
|
||||
make_json(),
|
||||
rpc_obj);
|
||||
}
|
||||
|
||||
function nested_sync_test()
|
||||
{
|
||||
dump('beginning cpow nested sync test\n');
|
||||
sync_obj = make_object();
|
||||
sync_obj.data.reenter = function () {
|
||||
let caught = false;
|
||||
try {
|
||||
sendSyncMessage("cpows:reenter_sync", { }, { });
|
||||
} catch (e) {
|
||||
caught = true;
|
||||
}
|
||||
if (!ok(caught, "should not allow nested sync"))
|
||||
return "fail";
|
||||
return "ok";
|
||||
}
|
||||
sendSyncMessage("cpows:nested_sync",
|
||||
make_json(),
|
||||
rpc_obj);
|
||||
}
|
||||
|
@ -12,6 +12,7 @@
|
||||
<script type="application/javascript"><![CDATA[
|
||||
var test_state = "remote";
|
||||
var test_node = null;
|
||||
var reentered = false;
|
||||
|
||||
function ok(condition, message) {
|
||||
return opener.wrappedJSObject.ok(condition, message);
|
||||
@ -102,6 +103,34 @@
|
||||
testCpowMessage(message);
|
||||
}
|
||||
|
||||
function recvRpcMessage(message) {
|
||||
ok(message.json.check == "ok", "correct json");
|
||||
|
||||
let data = message.objects.data;
|
||||
|
||||
// Sanity check.
|
||||
ok(data.i === 5, "integer property");
|
||||
|
||||
// Check that we re-enter.
|
||||
reentered = false;
|
||||
let result = data.reenter();
|
||||
ok(reentered, "re-entered rpc");
|
||||
ok(result == "ok", "got correct result");
|
||||
}
|
||||
|
||||
function recvReenterMessage(message) {
|
||||
ok(message.objects.data.valid === true, "cpows work");
|
||||
reentered = true;
|
||||
}
|
||||
|
||||
function recvNestedSyncMessage(message) {
|
||||
message.objects.data.reenter();
|
||||
}
|
||||
|
||||
function recvReenterSyncMessage(message) {
|
||||
ok(false, "should not have received re-entered sync message");
|
||||
}
|
||||
|
||||
function recvFailMessage(message) {
|
||||
ok(false, message.json.message);
|
||||
}
|
||||
@ -125,6 +154,11 @@
|
||||
var mm = node.messageManager;
|
||||
mm.addMessageListener("cpows:async", recvAsyncMessage);
|
||||
mm.addMessageListener("cpows:sync", recvSyncMessage);
|
||||
mm.addMessageListener("cpows:rpc", recvRpcMessage);
|
||||
mm.addMessageListener("cpows:reenter", recvReenterMessage);
|
||||
mm.addMessageListener("cpows:reenter", recvReenterMessage);
|
||||
mm.addMessageListener("cpows:nested_sync", recvNestedSyncMessage);
|
||||
mm.addMessageListener("cpows:reenter_sync", recvReenterSyncMessage);
|
||||
mm.addMessageListener("cpows:done", recvDoneMessage);
|
||||
mm.addMessageListener("cpows:fail", recvFailMessage);
|
||||
mm.loadFrameScript("chrome://mochitests/content/chrome/content/base/test/chrome/cpows_child.js", true);
|
||||
|
52
content/base/test/csp/file_CSP_bug910139.sjs
Normal file
52
content/base/test/csp/file_CSP_bug910139.sjs
Normal file
@ -0,0 +1,52 @@
|
||||
// Server side js file for bug 910139, see file test_CSP_bug910139.html for details.
|
||||
|
||||
Components.utils.import("resource://gre/modules/NetUtil.jsm");
|
||||
|
||||
function loadResponseFromFile(path) {
|
||||
var testHTMLFile =
|
||||
Components.classes["@mozilla.org/file/directory_service;1"].
|
||||
getService(Components.interfaces.nsIProperties).
|
||||
get("CurWorkD", Components.interfaces.nsILocalFile);
|
||||
var dirs = path.split("/");
|
||||
for (var i = 0; i < dirs.length; i++) {
|
||||
testHTMLFile.append(dirs[i]);
|
||||
}
|
||||
var testHTMLFileStream =
|
||||
Components.classes["@mozilla.org/network/file-input-stream;1"].
|
||||
createInstance(Components.interfaces.nsIFileInputStream);
|
||||
testHTMLFileStream.init(testHTMLFile, -1, 0, 0);
|
||||
var testHTML = NetUtil.readInputStreamToString(testHTMLFileStream, testHTMLFileStream.available());
|
||||
return testHTML;
|
||||
}
|
||||
|
||||
var policies = [
|
||||
"default-src 'self'; script-src 'self'", // CSP for checkAllowed
|
||||
"default-src 'self'; script-src *.example.com" // CSP for checkBlocked
|
||||
]
|
||||
|
||||
function getPolicy() {
|
||||
var index;
|
||||
// setState only accepts strings as arguments
|
||||
if (!getState("counter")) {
|
||||
index = 0;
|
||||
setState("counter", index.toString());
|
||||
}
|
||||
else {
|
||||
index = parseInt(getState("counter"));
|
||||
++index;
|
||||
setState("counter", index.toString());
|
||||
}
|
||||
return policies[index];
|
||||
}
|
||||
|
||||
function handleRequest(request, response)
|
||||
{
|
||||
// avoid confusing cache behaviors
|
||||
response.setHeader("Cache-Control", "no-cache", false);
|
||||
|
||||
// set the required CSP
|
||||
response.setHeader("Content-Security-Policy", getPolicy(), false);
|
||||
|
||||
// return the requested XML file.
|
||||
response.write(loadResponseFromFile("tests/content/base/test/csp/file_CSP_bug910139.xml"));
|
||||
}
|
28
content/base/test/csp/file_CSP_bug910139.xml
Normal file
28
content/base/test/csp/file_CSP_bug910139.xml
Normal file
@ -0,0 +1,28 @@
|
||||
<?xml version="1.0" encoding="ISO-8859-1"?>
|
||||
<?xml-stylesheet type="text/xsl" href="file_CSP_bug910139.xsl"?>
|
||||
<catalog>
|
||||
<cd>
|
||||
<title>Empire Burlesque</title>
|
||||
<artist>Bob Dylan</artist>
|
||||
<country>USA</country>
|
||||
<company>Columbia</company>
|
||||
<price>10.90</price>
|
||||
<year>1985</year>
|
||||
</cd>
|
||||
<cd>
|
||||
<title>Hide your heart</title>
|
||||
<artist>Bonnie Tyler</artist>
|
||||
<country>UK</country>
|
||||
<company>CBS Records</company>
|
||||
<price>9.90</price>
|
||||
<year>1988</year>
|
||||
</cd>
|
||||
<cd>
|
||||
<title>Greatest Hits</title>
|
||||
<artist>Dolly Parton</artist>
|
||||
<country>USA</country>
|
||||
<company>RCA</company>
|
||||
<price>9.90</price>
|
||||
<year>1982</year>
|
||||
</cd>
|
||||
</catalog>
|
27
content/base/test/csp/file_CSP_bug910139.xsl
Normal file
27
content/base/test/csp/file_CSP_bug910139.xsl
Normal file
@ -0,0 +1,27 @@
|
||||
<?xml version="1.0" encoding="ISO-8859-1"?>
|
||||
<!-- Edited by XMLSpy® -->
|
||||
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
|
||||
|
||||
<xsl:template match="/">
|
||||
<html>
|
||||
<body>
|
||||
<h2 id="xsltheader">this xml file should be formatted using an xsl file(lower iframe should contain xml dump)!</h2>
|
||||
<table border="1">
|
||||
<tr bgcolor="#990099">
|
||||
<th>Title</th>
|
||||
<th>Artist</th>
|
||||
<th>Price</th>
|
||||
</tr>
|
||||
<xsl:for-each select="catalog/cd">
|
||||
<tr>
|
||||
<td><xsl:value-of select="title"/></td>
|
||||
<td><xsl:value-of select="artist"/></td>
|
||||
<td><xsl:value-of select="price"/></td>
|
||||
</tr>
|
||||
</xsl:for-each>
|
||||
</table>
|
||||
</body>
|
||||
</html>
|
||||
</xsl:template>
|
||||
</xsl:stylesheet>
|
||||
|
@ -75,6 +75,9 @@ support-files =
|
||||
file_csp_redirects_main.html
|
||||
file_csp_redirects_page.sjs
|
||||
file_csp_redirects_resource.sjs
|
||||
file_CSP_bug910139.sjs
|
||||
file_CSP_bug910139.xml
|
||||
file_CSP_bug910139.xsl
|
||||
|
||||
[test_CSP.html]
|
||||
[test_CSP_bug663567.html]
|
||||
@ -90,3 +93,4 @@ support-files =
|
||||
[test_bothCSPheaders.html]
|
||||
[test_bug836922_npolicies.html]
|
||||
[test_csp_redirects.html]
|
||||
[test_CSP_bug910139.html]
|
||||
|
71
content/base/test/csp/test_CSP_bug910139.html
Normal file
71
content/base/test/csp/test_CSP_bug910139.html
Normal file
@ -0,0 +1,71 @@
|
||||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<head>
|
||||
<title>CSP should block XSLT as script, not as style</title>
|
||||
<!-- Including SimpleTest.js so we can use waitForExplicitFinish !-->
|
||||
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
|
||||
</head>
|
||||
<body>
|
||||
<p id="display"></p>
|
||||
<div id="content" style="display: none"></div>
|
||||
<iframe style="width:100%;" id='xsltframe'></iframe>
|
||||
<iframe style="width:100%;" id='xsltframe2'></iframe>
|
||||
|
||||
<script class="testbody" type="text/javascript">
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
|
||||
// define the expected output of this test
|
||||
var header = "this xml file should be formatted using an xsl file(lower iframe should contain xml dump)!";
|
||||
|
||||
function checkAllowed () {
|
||||
/* The policy for this test is:
|
||||
* Content-Security-Policy: default-src 'self'; script-src 'self'
|
||||
*
|
||||
* we load the xsl file using:
|
||||
* <?xml-stylesheet type="text/xsl" href="file_CSP_bug910139.xsl"?>
|
||||
*/
|
||||
try {
|
||||
var cspframe = document.getElementById('xsltframe');
|
||||
var xsltAllowedHeader = cspframe.contentWindow.document.getElementById('xsltheader').innerHTML;
|
||||
is(xsltAllowedHeader, header, "XSLT loaded from 'self' should be allowed!");
|
||||
}
|
||||
catch (e) {
|
||||
ok(false, "Error: could not access content in xsltframe!")
|
||||
}
|
||||
|
||||
// continue with the next test
|
||||
document.getElementById('xsltframe2').addEventListener('load', checkBlocked, false);
|
||||
document.getElementById('xsltframe2').src = 'file_CSP_bug910139.sjs';
|
||||
}
|
||||
|
||||
function checkBlocked () {
|
||||
/* The policy for this test is:
|
||||
* Content-Security-Policy: default-src 'self'; script-src *.example.com
|
||||
*
|
||||
* we load the xsl file using:
|
||||
* <?xml-stylesheet type="text/xsl" href="file_CSP_bug910139.xsl"?>
|
||||
*/
|
||||
try {
|
||||
var cspframe = document.getElementById('xsltframe2');
|
||||
var xsltBlockedHeader = cspframe.contentWindow.document.getElementById('xsltheader');
|
||||
is(xsltBlockedHeader, null, "XSLT loaded from different host should be blocked!");
|
||||
}
|
||||
catch (e) {
|
||||
ok(false, "Error: could not access content in xsltframe2!")
|
||||
}
|
||||
SimpleTest.finish();
|
||||
}
|
||||
|
||||
SpecialPowers.pushPrefEnv(
|
||||
{'set':[["security.csp.speccompliant", true]]},
|
||||
function () {
|
||||
document.getElementById('xsltframe').addEventListener('load', checkAllowed, false);
|
||||
document.getElementById('xsltframe').src = 'file_CSP_bug910139.sjs';
|
||||
}
|
||||
);
|
||||
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
@ -7,7 +7,7 @@
|
||||
#define nsICanvasElementExternal_h___
|
||||
|
||||
#include "nsISupports.h"
|
||||
#include "gfxPattern.h"
|
||||
#include "GraphicsFilter.h"
|
||||
|
||||
class gfxContext;
|
||||
class nsIFrame;
|
||||
@ -49,7 +49,7 @@ public:
|
||||
* to the given gfxContext at the origin of its coordinate space.
|
||||
*/
|
||||
NS_IMETHOD RenderContextsExternal(gfxContext *ctx,
|
||||
gfxPattern::GraphicsFilter aFilter,
|
||||
GraphicsFilter aFilter,
|
||||
uint32_t aFlags = RenderFlagPremultAlpha) = 0;
|
||||
};
|
||||
|
||||
|
@ -10,7 +10,7 @@
|
||||
#include "nsIInputStream.h"
|
||||
#include "nsIDocShell.h"
|
||||
#include "mozilla/dom/HTMLCanvasElement.h"
|
||||
#include "gfxPattern.h"
|
||||
#include "GraphicsFilter.h"
|
||||
#include "mozilla/RefPtr.h"
|
||||
|
||||
#define NS_ICANVASRENDERINGCONTEXTINTERNAL_IID \
|
||||
@ -68,7 +68,7 @@ public:
|
||||
|
||||
// Render the canvas at the origin of the given gfxContext
|
||||
NS_IMETHOD Render(gfxContext *ctx,
|
||||
gfxPattern::GraphicsFilter aFilter,
|
||||
GraphicsFilter aFilter,
|
||||
uint32_t aFlags = RenderFlagPremultAlpha) = 0;
|
||||
|
||||
// Gives you a stream containing the image represented by this context.
|
||||
|
@ -1006,7 +1006,7 @@ CanvasRenderingContext2D::SetIsIPC(bool isIPC)
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
CanvasRenderingContext2D::Render(gfxContext *ctx, gfxPattern::GraphicsFilter aFilter, uint32_t aFlags)
|
||||
CanvasRenderingContext2D::Render(gfxContext *ctx, GraphicsFilter aFilter, uint32_t aFlags)
|
||||
{
|
||||
nsresult rv = NS_OK;
|
||||
|
||||
|
@ -380,7 +380,7 @@ public:
|
||||
NS_IMETHOD InitializeWithSurface(nsIDocShell *shell, gfxASurface *surface, int32_t width, int32_t height) MOZ_OVERRIDE;
|
||||
|
||||
NS_IMETHOD Render(gfxContext *ctx,
|
||||
gfxPattern::GraphicsFilter aFilter,
|
||||
GraphicsFilter aFilter,
|
||||
uint32_t aFlags = RenderFlagPremultAlpha) MOZ_OVERRIDE;
|
||||
NS_IMETHOD GetInputStream(const char* aMimeType,
|
||||
const PRUnichar* aEncoderOptions,
|
||||
|
@ -609,7 +609,7 @@ WebGLContext::SetDimensions(int32_t width, int32_t height)
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
WebGLContext::Render(gfxContext *ctx, gfxPattern::GraphicsFilter f, uint32_t aFlags)
|
||||
WebGLContext::Render(gfxContext *ctx, GraphicsFilter f, uint32_t aFlags)
|
||||
{
|
||||
if (!gl)
|
||||
return NS_OK;
|
||||
@ -752,7 +752,7 @@ WebGLContext::GetInputStream(const char* aMimeType,
|
||||
nsRefPtr<gfxContext> tmpcx = new gfxContext(surf);
|
||||
// Use Render() to make sure that appropriate y-flip gets applied
|
||||
uint32_t flags = mOptions.premultipliedAlpha ? RenderFlagPremultAlpha : 0;
|
||||
nsresult rv = Render(tmpcx, gfxPattern::FILTER_NEAREST, flags);
|
||||
nsresult rv = Render(tmpcx, GraphicsFilter::FILTER_NEAREST, flags);
|
||||
if (NS_FAILED(rv))
|
||||
return rv;
|
||||
|
||||
@ -1329,6 +1329,12 @@ WebGLContext::ForceRestoreContext()
|
||||
void
|
||||
WebGLContext::MakeContextCurrent() const { gl->MakeCurrent(); }
|
||||
|
||||
mozilla::TemporaryRef<mozilla::gfx::SourceSurface>
|
||||
WebGLContext::GetSurfaceSnapshot()
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
//
|
||||
// XPCOM goop
|
||||
//
|
||||
|
@ -80,6 +80,10 @@ struct WebGLContextAttributesInitializer;
|
||||
template<typename> struct Nullable;
|
||||
}
|
||||
|
||||
namespace gfx {
|
||||
class SourceSurface;
|
||||
}
|
||||
|
||||
using WebGLTexelConversions::WebGLTexelFormat;
|
||||
|
||||
WebGLTexelFormat GetWebGLTexelFormat(GLenum format, GLenum type);
|
||||
@ -163,14 +167,13 @@ public:
|
||||
NS_IMETHOD Reset() MOZ_OVERRIDE
|
||||
{ /* (InitializeWithSurface) */ return NS_ERROR_NOT_IMPLEMENTED; }
|
||||
NS_IMETHOD Render(gfxContext *ctx,
|
||||
gfxPattern::GraphicsFilter f,
|
||||
GraphicsFilter f,
|
||||
uint32_t aFlags = RenderFlagPremultAlpha) MOZ_OVERRIDE;
|
||||
NS_IMETHOD GetInputStream(const char* aMimeType,
|
||||
const PRUnichar* aEncoderOptions,
|
||||
nsIInputStream **aStream) MOZ_OVERRIDE;
|
||||
NS_IMETHOD GetThebesSurface(gfxASurface **surface) MOZ_OVERRIDE;
|
||||
mozilla::TemporaryRef<mozilla::gfx::SourceSurface> GetSurfaceSnapshot() MOZ_OVERRIDE
|
||||
{ return nullptr; }
|
||||
mozilla::TemporaryRef<mozilla::gfx::SourceSurface> GetSurfaceSnapshot() MOZ_OVERRIDE;
|
||||
|
||||
NS_IMETHOD SetIsOpaque(bool b) MOZ_OVERRIDE { return NS_OK; };
|
||||
NS_IMETHOD SetContextOptions(JSContext* aCx,
|
||||
|
@ -169,7 +169,7 @@ public:
|
||||
*/
|
||||
NS_IMETHOD_(nsIntSize) GetSizeExternal() MOZ_OVERRIDE;
|
||||
NS_IMETHOD RenderContextsExternal(gfxContext *aContext,
|
||||
gfxPattern::GraphicsFilter aFilter,
|
||||
GraphicsFilter aFilter,
|
||||
uint32_t aFlags = RenderFlagPremultAlpha) MOZ_OVERRIDE;
|
||||
|
||||
virtual bool ParseAttribute(int32_t aNamespaceID,
|
||||
|
@ -1054,7 +1054,7 @@ HTMLCanvasElement::GetSizeExternal()
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
HTMLCanvasElement::RenderContextsExternal(gfxContext *aContext, gfxPattern::GraphicsFilter aFilter, uint32_t aFlags)
|
||||
HTMLCanvasElement::RenderContextsExternal(gfxContext *aContext, GraphicsFilter aFilter, uint32_t aFlags)
|
||||
{
|
||||
if (!mCurrentContext)
|
||||
return NS_OK;
|
||||
|
@ -34,7 +34,7 @@
|
||||
#include "nsIURL.h"
|
||||
#include "nsNetUtil.h"
|
||||
#include "nsEscape.h"
|
||||
#include "nsIFrame.h"
|
||||
#include "nsIFrameInlines.h"
|
||||
#include "nsIScrollableFrame.h"
|
||||
#include "nsView.h"
|
||||
#include "nsViewManager.h"
|
||||
@ -100,6 +100,7 @@
|
||||
#include "nsDOMTouchEvent.h"
|
||||
#include "nsGlobalWindow.h"
|
||||
#include "mozilla/dom/HTMLBodyElement.h"
|
||||
#include "imgIContainer.h"
|
||||
|
||||
using namespace mozilla;
|
||||
using namespace mozilla::dom;
|
||||
|
@ -5,6 +5,7 @@
|
||||
|
||||
#include "mozilla/dom/SVGFECompositeElement.h"
|
||||
#include "mozilla/dom/SVGFECompositeElementBinding.h"
|
||||
#include "gfxContext.h"
|
||||
|
||||
NS_IMPL_NS_NEW_NAMESPACED_SVG_ELEMENT(FEComposite)
|
||||
|
||||
|
@ -5,6 +5,7 @@
|
||||
|
||||
#include "mozilla/dom/SVGFEFloodElement.h"
|
||||
#include "mozilla/dom/SVGFEFloodElementBinding.h"
|
||||
#include "gfxContext.h"
|
||||
|
||||
NS_IMPL_NS_NEW_NAMESPACED_SVG_ELEMENT(FEFlood)
|
||||
|
||||
|
@ -11,6 +11,7 @@
|
||||
#include "nsLayoutUtils.h"
|
||||
#include "nsSVGUtils.h"
|
||||
#include "nsNetUtil.h"
|
||||
#include "imgIContainer.h"
|
||||
|
||||
NS_IMPL_NS_NEW_NAMESPACED_SVG_ELEMENT(FEImage)
|
||||
|
||||
|
@ -6,6 +6,7 @@
|
||||
#include "mozilla/dom/SVGFEMergeElement.h"
|
||||
#include "mozilla/dom/SVGFEMergeElementBinding.h"
|
||||
#include "mozilla/dom/SVGFEMergeNodeElement.h"
|
||||
#include "gfxContext.h"
|
||||
|
||||
NS_IMPL_NS_NEW_NAMESPACED_SVG_ELEMENT(FEMerge)
|
||||
|
||||
|
@ -6,6 +6,7 @@
|
||||
#include "mozilla/dom/SVGFEOffsetElement.h"
|
||||
#include "mozilla/dom/SVGFEOffsetElementBinding.h"
|
||||
#include "nsSVGFilterInstance.h"
|
||||
#include "gfxContext.h"
|
||||
|
||||
NS_IMPL_NS_NEW_NAMESPACED_SVG_ELEMENT(FEOffset)
|
||||
|
||||
|
@ -722,7 +722,7 @@ nsXMLContentSink::ProcessStyleLink(nsIContent* aElement,
|
||||
|
||||
// Do content policy check
|
||||
int16_t decision = nsIContentPolicy::ACCEPT;
|
||||
rv = NS_CheckContentLoadPolicy(nsIContentPolicy::TYPE_STYLESHEET,
|
||||
rv = NS_CheckContentLoadPolicy(nsIContentPolicy::TYPE_XSLT,
|
||||
url,
|
||||
mDocument->NodePrincipal(),
|
||||
aElement,
|
||||
|
@ -8,7 +8,7 @@
|
||||
|
||||
namespace mozilla {
|
||||
|
||||
NS_IMPL_ISUPPORTS1(LoadContext, nsILoadContext)
|
||||
NS_IMPL_ISUPPORTS2(LoadContext, nsILoadContext, nsIInterfaceRequestor)
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// LoadContext::nsILoadContext
|
||||
@ -111,4 +111,22 @@ LoadContext::GetAppId(uint32_t* aAppId)
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// LoadContext::nsIInterfaceRequestor
|
||||
//-----------------------------------------------------------------------------
|
||||
NS_IMETHODIMP
|
||||
LoadContext::GetInterface(const nsIID &aIID, void **aResult)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(aResult);
|
||||
*aResult = nullptr;
|
||||
|
||||
if (aIID.Equals(NS_GET_IID(nsILoadContext))) {
|
||||
*aResult = static_cast<nsILoadContext*>(this);
|
||||
NS_ADDREF_THIS();
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
return NS_NOINTERFACE;
|
||||
}
|
||||
|
||||
} // namespace mozilla
|
||||
|
@ -11,6 +11,7 @@
|
||||
#include "mozilla/Attributes.h"
|
||||
#include "nsIWeakReferenceUtils.h"
|
||||
#include "mozilla/dom/Element.h"
|
||||
#include "nsIInterfaceRequestor.h"
|
||||
|
||||
class mozIApplication;
|
||||
|
||||
@ -24,13 +25,18 @@ namespace mozilla {
|
||||
* typically provided by nsDocShell. This is only used when the original
|
||||
* docshell is in a different process and we need to copy certain values from
|
||||
* it.
|
||||
*
|
||||
* Note: we also generate a new nsILoadContext using LoadContext(uint32_t aAppId)
|
||||
* to separate the safebrowsing cookie.
|
||||
*/
|
||||
|
||||
class LoadContext MOZ_FINAL : public nsILoadContext
|
||||
class LoadContext MOZ_FINAL : public nsILoadContext,
|
||||
public nsIInterfaceRequestor
|
||||
{
|
||||
public:
|
||||
NS_DECL_ISUPPORTS
|
||||
NS_DECL_NSILOADCONTEXT
|
||||
NS_DECL_NSIINTERFACEREQUESTOR
|
||||
|
||||
// AppId/inBrowser arguments override those in SerializedLoadContext provided
|
||||
// by child process.
|
||||
@ -47,6 +53,18 @@ public:
|
||||
#endif
|
||||
{}
|
||||
|
||||
// Constructor taking reserved appId for the safebrowsing cookie.
|
||||
LoadContext(uint32_t aAppId)
|
||||
: mTopFrameElement(nullptr)
|
||||
, mAppId(aAppId)
|
||||
, mIsContent(false)
|
||||
, mUsePrivateBrowsing(false)
|
||||
, mIsInBrowserElement(false)
|
||||
#ifdef DEBUG
|
||||
, mIsNotNull(true)
|
||||
#endif
|
||||
{}
|
||||
|
||||
private:
|
||||
nsWeakPtr mTopFrameElement;
|
||||
uint32_t mAppId;
|
||||
|
@ -137,6 +137,18 @@ interface nsIMarkupDocumentViewer : nsISupports
|
||||
*/
|
||||
void changeMaxLineBoxWidth(in int32_t maxLineBoxWidth);
|
||||
|
||||
/**
|
||||
* Instruct the refresh driver to discontinue painting until further
|
||||
* notice.
|
||||
*/
|
||||
void pausePainting();
|
||||
|
||||
/**
|
||||
* Instruct the refresh driver to resume painting after a previous call to
|
||||
* pausePainting().
|
||||
*/
|
||||
void resumePainting();
|
||||
|
||||
/*
|
||||
* Render the document as if being viewed on a device with the specified
|
||||
* media type. This will cause a reflow.
|
||||
|
@ -5,6 +5,7 @@
|
||||
|
||||
#include "mozilla/Hal.h"
|
||||
#include "nsScreen.h"
|
||||
#include "nsIDocument.h"
|
||||
#include "nsIDocShell.h"
|
||||
#include "nsIDocument.h"
|
||||
#include "nsPresContext.h"
|
||||
|
@ -15,14 +15,6 @@ Cu.import("resource://gre/modules/XPCOMUtils.jsm");
|
||||
Cu.import("resource://gre/modules/Services.jsm");
|
||||
Cu.import("resource://gre/modules/DOMRequestHelper.jsm");
|
||||
|
||||
XPCOMUtils.defineLazyGetter(Services, "DOMRequest", function() {
|
||||
return Cc["@mozilla.org/dom/dom-request-service;1"].getService(Ci.nsIDOMRequestService);
|
||||
});
|
||||
|
||||
XPCOMUtils.defineLazyServiceGetter(this, "pm",
|
||||
"@mozilla.org/permissionmanager;1",
|
||||
"nsIPermissionManager");
|
||||
|
||||
XPCOMUtils.defineLazyServiceGetter(this, "cpmm",
|
||||
"@mozilla.org/childprocessmessagemanager;1",
|
||||
"nsIMessageSender");
|
||||
@ -732,7 +724,7 @@ ContactManager.prototype = {
|
||||
// Shortcut for ALLOW_ACTION so we avoid a parent roundtrip
|
||||
let type = "contacts-" + access;
|
||||
let permValue =
|
||||
pm.testExactPermissionFromPrincipal(this._window.document.nodePrincipal, type);
|
||||
Services.perms.testExactPermissionFromPrincipal(this._window.document.nodePrincipal, type);
|
||||
if (permValue == Ci.nsIPermissionManager.ALLOW_ACTION) {
|
||||
aAllowCallback();
|
||||
return;
|
||||
|
@ -2946,6 +2946,22 @@ ContentParent::RecvSyncMessage(const nsString& aMsg,
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
ContentParent::AnswerRpcMessage(const nsString& aMsg,
|
||||
const ClonedMessageData& aData,
|
||||
const InfallibleTArray<CpowEntry>& aCpows,
|
||||
InfallibleTArray<nsString>* aRetvals)
|
||||
{
|
||||
nsRefPtr<nsFrameMessageManager> ppm = mMessageManager;
|
||||
if (ppm) {
|
||||
StructuredCloneData cloneData = ipc::UnpackClonedMessageDataForParent(aData);
|
||||
CpowIdHolder cpows(GetCPOWManager(), aCpows);
|
||||
ppm->ReceiveMessage(static_cast<nsIContentFrameMessageManager*>(ppm.get()),
|
||||
aMsg, true, &cloneData, &cpows, aRetvals);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
ContentParent::RecvAsyncMessage(const nsString& aMsg,
|
||||
const ClonedMessageData& aData,
|
||||
|
@ -422,6 +422,10 @@ private:
|
||||
const ClonedMessageData& aData,
|
||||
const InfallibleTArray<CpowEntry>& aCpows,
|
||||
InfallibleTArray<nsString>* aRetvals);
|
||||
virtual bool AnswerRpcMessage(const nsString& aMsg,
|
||||
const ClonedMessageData& aData,
|
||||
const InfallibleTArray<CpowEntry>& aCpows,
|
||||
InfallibleTArray<nsString>* aRetvals);
|
||||
virtual bool RecvAsyncMessage(const nsString& aMsg,
|
||||
const ClonedMessageData& aData,
|
||||
const InfallibleTArray<CpowEntry>& aCpows);
|
||||
|
@ -84,6 +84,9 @@ parent:
|
||||
sync SyncMessage(nsString aMessage, ClonedMessageData aData, CpowEntry[] aCpows)
|
||||
returns (nsString[] retval);
|
||||
|
||||
rpc RpcMessage(nsString aMessage, ClonedMessageData aData, CpowEntry[] aCpows)
|
||||
returns (nsString[] retval);
|
||||
|
||||
/**
|
||||
* The IME sequence number (seqno) parameter is used to make sure
|
||||
* that a notification is discarded if it arrives at the chrome process
|
||||
|
@ -389,6 +389,9 @@ parent:
|
||||
sync SyncMessage(nsString aMessage, ClonedMessageData aData, CpowEntry[] aCpows)
|
||||
returns (nsString[] retval);
|
||||
|
||||
rpc RpcMessage(nsString aMessage, ClonedMessageData aData, CpowEntry[] aCpows)
|
||||
returns (nsString[] retval);
|
||||
|
||||
ShowAlertNotification(nsString imageUrl,
|
||||
nsString title,
|
||||
nsString text,
|
||||
|
@ -2382,11 +2382,12 @@ TabChild::DeallocPIndexedDBChild(PIndexedDBChild* aActor)
|
||||
}
|
||||
|
||||
bool
|
||||
TabChild::DoSendSyncMessage(JSContext* aCx,
|
||||
const nsAString& aMessage,
|
||||
const StructuredCloneData& aData,
|
||||
JS::Handle<JSObject *> aCpows,
|
||||
InfallibleTArray<nsString>* aJSONRetVal)
|
||||
TabChild::DoSendBlockingMessage(JSContext* aCx,
|
||||
const nsAString& aMessage,
|
||||
const StructuredCloneData& aData,
|
||||
JS::Handle<JSObject *> aCpows,
|
||||
InfallibleTArray<nsString>* aJSONRetVal,
|
||||
bool aIsSync)
|
||||
{
|
||||
ContentChild* cc = Manager();
|
||||
ClonedMessageData data;
|
||||
@ -2399,7 +2400,9 @@ TabChild::DoSendSyncMessage(JSContext* aCx,
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return SendSyncMessage(nsString(aMessage), data, cpows, aJSONRetVal);
|
||||
if (aIsSync)
|
||||
return SendSyncMessage(nsString(aMessage), data, cpows, aJSONRetVal);
|
||||
return CallRpcMessage(nsString(aMessage), data, cpows, aJSONRetVal);
|
||||
}
|
||||
|
||||
bool
|
||||
|
@ -78,6 +78,17 @@ public:
|
||||
? mMessageManager->SendSyncMessage(aMessageName, aObject, aRemote, aCx, aArgc, aRetval)
|
||||
: NS_ERROR_NULL_POINTER;
|
||||
}
|
||||
NS_IMETHOD SendRpcMessage(const nsAString& aMessageName,
|
||||
const JS::Value& aObject,
|
||||
const JS::Value& aRemote,
|
||||
JSContext* aCx,
|
||||
uint8_t aArgc,
|
||||
JS::Value* aRetval)
|
||||
{
|
||||
return mMessageManager
|
||||
? mMessageManager->SendRpcMessage(aMessageName, aObject, aRemote, aCx, aArgc, aRetval)
|
||||
: NS_ERROR_NULL_POINTER;
|
||||
}
|
||||
NS_IMETHOD GetContent(nsIDOMWindow** aContent) MOZ_OVERRIDE;
|
||||
NS_IMETHOD GetDocShell(nsIDocShell** aDocShell) MOZ_OVERRIDE;
|
||||
NS_IMETHOD Dump(const nsAString& aStr) MOZ_OVERRIDE
|
||||
@ -186,15 +197,16 @@ public:
|
||||
/**
|
||||
* MessageManagerCallback methods that we override.
|
||||
*/
|
||||
virtual bool DoSendSyncMessage(JSContext* aCx,
|
||||
const nsAString& aMessage,
|
||||
const mozilla::dom::StructuredCloneData& aData,
|
||||
JS::Handle<JSObject *> aCpows,
|
||||
InfallibleTArray<nsString>* aJSONRetVal);
|
||||
virtual bool DoSendBlockingMessage(JSContext* aCx,
|
||||
const nsAString& aMessage,
|
||||
const mozilla::dom::StructuredCloneData& aData,
|
||||
JS::Handle<JSObject *> aCpows,
|
||||
InfallibleTArray<nsString>* aJSONRetVal,
|
||||
bool aIsSync) MOZ_OVERRIDE;
|
||||
virtual bool DoSendAsyncMessage(JSContext* aCx,
|
||||
const nsAString& aMessage,
|
||||
const mozilla::dom::StructuredCloneData& aData,
|
||||
JS::Handle<JSObject *> aCpows);
|
||||
JS::Handle<JSObject *> aCpows) MOZ_OVERRIDE;
|
||||
|
||||
virtual bool RecvLoadURL(const nsCString& uri);
|
||||
virtual bool RecvCacheFileDescriptor(const nsString& aPath,
|
||||
|
@ -766,6 +766,17 @@ TabParent::RecvSyncMessage(const nsString& aMessage,
|
||||
return ReceiveMessage(aMessage, true, &cloneData, &cpows, aJSONRetVal);
|
||||
}
|
||||
|
||||
bool
|
||||
TabParent::AnswerRpcMessage(const nsString& aMessage,
|
||||
const ClonedMessageData& aData,
|
||||
const InfallibleTArray<CpowEntry>& aCpows,
|
||||
InfallibleTArray<nsString>* aJSONRetVal)
|
||||
{
|
||||
StructuredCloneData cloneData = ipc::UnpackClonedMessageDataForParent(aData);
|
||||
CpowIdHolder cpows(static_cast<ContentParent*>(Manager())->GetCPOWManager(), aCpows);
|
||||
return ReceiveMessage(aMessage, true, &cloneData, &cpows, aJSONRetVal);
|
||||
}
|
||||
|
||||
bool
|
||||
TabParent::RecvAsyncMessage(const nsString& aMessage,
|
||||
const ClonedMessageData& aData,
|
||||
|
@ -120,6 +120,10 @@ public:
|
||||
const ClonedMessageData& aData,
|
||||
const InfallibleTArray<CpowEntry>& aCpows,
|
||||
InfallibleTArray<nsString>* aJSONRetVal);
|
||||
virtual bool AnswerRpcMessage(const nsString& aMessage,
|
||||
const ClonedMessageData& aData,
|
||||
const InfallibleTArray<CpowEntry>& aCpows,
|
||||
InfallibleTArray<nsString>* aJSONRetVal);
|
||||
virtual bool RecvAsyncMessage(const nsString& aMessage,
|
||||
const ClonedMessageData& aData,
|
||||
const InfallibleTArray<CpowEntry>& aCpows);
|
||||
|
@ -45,8 +45,6 @@ XPCOMUtils.defineLazyServiceGetter(this, "permissionPromptService",
|
||||
"@mozilla.org/permission-prompt-service;1",
|
||||
"nsIPermissionPromptService");
|
||||
|
||||
let permissionManager = Cc["@mozilla.org/permissionmanager;1"].getService(Ci.nsIPermissionManager);
|
||||
let secMan = Cc["@mozilla.org/scriptsecuritymanager;1"].getService(Ci.nsIScriptSecurityManager);
|
||||
let appsService = Cc["@mozilla.org/AppsService;1"].getService(Ci.nsIAppsService);
|
||||
|
||||
this.PermissionPromptHelper = {
|
||||
@ -66,10 +64,10 @@ this.PermissionPromptHelper = {
|
||||
|
||||
let uri = Services.io.newURI(msg.origin, null, null);
|
||||
let principal =
|
||||
secMan.getAppCodebasePrincipal(uri, msg.appID, msg.browserFlag);
|
||||
Services.scriptSecurityManager.getAppCodebasePrincipal(uri, msg.appID, msg.browserFlag);
|
||||
|
||||
let permValue =
|
||||
permissionManager.testExactPermissionFromPrincipal(principal, access);
|
||||
Services.perms.testExactPermissionFromPrincipal(principal, access);
|
||||
|
||||
if (permValue == Ci.nsIPermissionManager.DENY_ACTION ||
|
||||
permValue == Ci.nsIPermissionManager.UNKNOWN_ACTION) {
|
||||
|
@ -29,6 +29,7 @@ class gfxXlibSurface;
|
||||
#include "mozilla/unused.h"
|
||||
|
||||
class gfxASurface;
|
||||
class gfxContext;
|
||||
|
||||
namespace mozilla {
|
||||
namespace layers {
|
||||
|
@ -7,6 +7,7 @@
|
||||
|
||||
#include "nsFind.h"
|
||||
#include "nsContentCID.h"
|
||||
#include "nsIContent.h"
|
||||
#include "nsIDOMNode.h"
|
||||
#include "nsIDOMNodeList.h"
|
||||
#include "nsISelection.h"
|
||||
|
@ -36,8 +36,9 @@ static const char *kTypeString[] = {"other",
|
||||
"dtd",
|
||||
"font",
|
||||
"media",
|
||||
"websocket"
|
||||
"csp_report"};
|
||||
"websocket",
|
||||
"csp_report",
|
||||
"xslt"};
|
||||
|
||||
#define NUMBER_OF_TYPES NS_ARRAY_LENGTH(kTypeString)
|
||||
uint8_t nsContentBlocker::mBehaviorPref[NUMBER_OF_TYPES];
|
||||
|
@ -1268,15 +1268,15 @@ GLContext::CreateTextureImage(const nsIntSize& aSize,
|
||||
aFlags, aImageFormat);
|
||||
}
|
||||
|
||||
void GLContext::ApplyFilterToBoundTexture(gfxPattern::GraphicsFilter aFilter)
|
||||
void GLContext::ApplyFilterToBoundTexture(GraphicsFilter aFilter)
|
||||
{
|
||||
ApplyFilterToBoundTexture(LOCAL_GL_TEXTURE_2D, aFilter);
|
||||
}
|
||||
|
||||
void GLContext::ApplyFilterToBoundTexture(GLuint aTarget,
|
||||
gfxPattern::GraphicsFilter aFilter)
|
||||
GraphicsFilter aFilter)
|
||||
{
|
||||
if (aFilter == gfxPattern::FILTER_NEAREST) {
|
||||
if (aFilter == GraphicsFilter::FILTER_NEAREST) {
|
||||
fTexParameteri(aTarget, LOCAL_GL_TEXTURE_MIN_FILTER, LOCAL_GL_NEAREST);
|
||||
fTexParameteri(aTarget, LOCAL_GL_TEXTURE_MAG_FILTER, LOCAL_GL_NEAREST);
|
||||
} else {
|
||||
|
@ -2401,13 +2401,13 @@ public:
|
||||
/**
|
||||
* Applies aFilter to the texture currently bound to GL_TEXTURE_2D.
|
||||
*/
|
||||
void ApplyFilterToBoundTexture(gfxPattern::GraphicsFilter aFilter);
|
||||
void ApplyFilterToBoundTexture(GraphicsFilter aFilter);
|
||||
|
||||
/**
|
||||
* Applies aFilter to the texture currently bound to aTarget.
|
||||
*/
|
||||
void ApplyFilterToBoundTexture(GLuint aTarget,
|
||||
gfxPattern::GraphicsFilter aFilter);
|
||||
GraphicsFilter aFilter);
|
||||
|
||||
virtual bool BindExternalBuffer(GLuint texture, void* buffer) { return false; }
|
||||
virtual bool UnbindExternalBuffer(GLuint texture) { return false; }
|
||||
|
@ -242,7 +242,7 @@ TextureImage::TextureImage(const gfx::IntSize& aSize,
|
||||
: mSize(ThebesIntSize(aSize))
|
||||
, mWrapMode(aWrapMode)
|
||||
, mContentType(aContentType)
|
||||
, mFilter(gfxPattern::FILTER_GOOD)
|
||||
, mFilter(GraphicsFilter::FILTER_GOOD)
|
||||
, mFlags(aFlags)
|
||||
{}
|
||||
|
||||
|
@ -11,7 +11,7 @@
|
||||
#include "nsTArray.h"
|
||||
#include "gfxTypes.h"
|
||||
#include "GLContextTypes.h"
|
||||
#include "gfxPattern.h"
|
||||
#include "GraphicsFilter.h"
|
||||
#include "mozilla/gfx/Rect.h"
|
||||
|
||||
class gfxASurface;
|
||||
@ -245,7 +245,7 @@ public:
|
||||
virtual bool InUpdate() const = 0;
|
||||
GLenum GetWrapMode() const { return mWrapMode; }
|
||||
|
||||
void SetFilter(gfxPattern::GraphicsFilter aFilter) { mFilter = aFilter; }
|
||||
void SetFilter(GraphicsFilter aFilter) { mFilter = aFilter; }
|
||||
|
||||
/**
|
||||
* Applies this TextureImage's filter, assuming that its texture is
|
||||
@ -270,7 +270,7 @@ protected:
|
||||
, mWrapMode(aWrapMode)
|
||||
, mContentType(aContentType)
|
||||
, mImageFormat(aImageFormat)
|
||||
, mFilter(gfxPattern::FILTER_GOOD)
|
||||
, mFilter(GraphicsFilter::FILTER_GOOD)
|
||||
, mFlags(aFlags)
|
||||
{}
|
||||
|
||||
@ -286,7 +286,7 @@ protected:
|
||||
ContentType mContentType;
|
||||
ImageFormat mImageFormat;
|
||||
gfx::SurfaceFormat mTextureFormat;
|
||||
gfxPattern::GraphicsFilter mFilter;
|
||||
GraphicsFilter mFilter;
|
||||
Flags mFlags;
|
||||
};
|
||||
|
||||
|
@ -7,6 +7,7 @@
|
||||
#include "GLContext.h"
|
||||
#include "gfxImageSurface.h"
|
||||
#include "mozilla/gfx/MacIOSurface.h"
|
||||
#include "mozilla/DebugOnly.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace gl {
|
||||
|
@ -12,13 +12,12 @@
|
||||
#include "ipc/IPCMessageUtils.h"
|
||||
|
||||
#include "mozilla/Util.h"
|
||||
#include "mozilla/gfx/2D.h"
|
||||
#include <stdint.h>
|
||||
|
||||
#include "gfx3DMatrix.h"
|
||||
#include "gfxColor.h"
|
||||
#include "gfxMatrix.h"
|
||||
#include "gfxPattern.h"
|
||||
#include "GraphicsFilter.h"
|
||||
#include "gfxPoint.h"
|
||||
#include "gfxRect.h"
|
||||
#include "nsRect.h"
|
||||
@ -35,7 +34,13 @@
|
||||
namespace mozilla {
|
||||
|
||||
typedef gfxImageFormat PixelFormat;
|
||||
typedef gfxPattern::GraphicsFilter GraphicsFilterType;
|
||||
#if defined(MOZ_HAVE_CXX11_STRONG_ENUMS)
|
||||
typedef ::GraphicsFilter GraphicsFilterType;
|
||||
#else
|
||||
// If we don't have support for enum classes, then we need to use the actual
|
||||
// enum type here instead of the simulated enum class.
|
||||
typedef GraphicsFilter::Enum GraphicsFilterType;
|
||||
#endif
|
||||
|
||||
} // namespace mozilla
|
||||
|
||||
@ -200,8 +205,8 @@ struct ParamTraits<gfxSurfaceType>
|
||||
template <>
|
||||
struct ParamTraits<mozilla::GraphicsFilterType>
|
||||
: public EnumSerializer<mozilla::GraphicsFilterType,
|
||||
gfxPattern::FILTER_FAST,
|
||||
gfxPattern::FILTER_SENTINEL>
|
||||
GraphicsFilter::FILTER_FAST,
|
||||
GraphicsFilter::FILTER_SENTINEL>
|
||||
{};
|
||||
|
||||
template <>
|
||||
|
@ -14,7 +14,7 @@ namespace mozilla {
|
||||
namespace layers {
|
||||
|
||||
ImageLayer::ImageLayer(LayerManager* aManager, void* aImplData)
|
||||
: Layer(aManager, aImplData), mFilter(gfxPattern::FILTER_GOOD)
|
||||
: Layer(aManager, aImplData), mFilter(GraphicsFilter::FILTER_GOOD)
|
||||
, mScaleMode(SCALE_NONE), mDisallowBigImage(false)
|
||||
{}
|
||||
|
||||
|
@ -7,7 +7,7 @@
|
||||
#define GFX_IMAGELAYER_H
|
||||
|
||||
#include "Layers.h" // for Layer, etc
|
||||
#include "gfxPattern.h" // for gfxPattern, etc
|
||||
#include "GraphicsFilter.h" // for GraphicsFilter
|
||||
#include "gfxPoint.h" // for gfxIntSize
|
||||
#include "mozilla/gfx/BaseSize.h" // for BaseSize
|
||||
#include "mozilla/layers/LayersTypes.h"
|
||||
@ -37,7 +37,7 @@ public:
|
||||
* CONSTRUCTION PHASE ONLY
|
||||
* Set the filter used to resample this image if necessary.
|
||||
*/
|
||||
void SetFilter(gfxPattern::GraphicsFilter aFilter)
|
||||
void SetFilter(GraphicsFilter aFilter)
|
||||
{
|
||||
if (mFilter != aFilter) {
|
||||
MOZ_LAYERS_LOG_IF_SHADOWABLE(this, ("Layer::Mutated(%p) Filter", this));
|
||||
@ -61,7 +61,7 @@ public:
|
||||
|
||||
|
||||
ImageContainer* GetContainer() { return mContainer; }
|
||||
gfxPattern::GraphicsFilter GetFilter() { return mFilter; }
|
||||
GraphicsFilter GetFilter() { return mFilter; }
|
||||
const gfxIntSize& GetScaleToSize() { return mScaleToSize; }
|
||||
ScaleMode GetScaleMode() { return mScaleMode; }
|
||||
|
||||
@ -88,7 +88,7 @@ protected:
|
||||
|
||||
|
||||
nsRefPtr<ImageContainer> mContainer;
|
||||
gfxPattern::GraphicsFilter mFilter;
|
||||
GraphicsFilter mFilter;
|
||||
gfxIntSize mScaleToSize;
|
||||
ScaleMode mScaleMode;
|
||||
bool mDisallowBigImage;
|
||||
|
@ -10,7 +10,7 @@
|
||||
#include "Layers.h" // for Layer, ContainerLayer, etc
|
||||
#include "gfx3DMatrix.h" // for gfx3DMatrix
|
||||
#include "gfxColor.h" // for gfxRGBA
|
||||
#include "gfxPattern.h" // for gfxPattern, etc
|
||||
#include "GraphicsFilter.h" // for GraphicsFilter
|
||||
#include "gfxPoint.h" // for gfxIntSize
|
||||
#include "gfxPoint3D.h" // for gfxPoint3D
|
||||
#include "gfxRect.h" // for gfxRect
|
||||
@ -350,7 +350,7 @@ struct ImageLayerProperties : public LayerPropertiesBase
|
||||
|
||||
nsIntRegion mVisibleRegion;
|
||||
nsRefPtr<ImageContainer> mContainer;
|
||||
gfxPattern::GraphicsFilter mFilter;
|
||||
GraphicsFilter mFilter;
|
||||
gfxIntSize mScaleToSize;
|
||||
ScaleMode mScaleMode;
|
||||
};
|
||||
|
@ -1352,7 +1352,7 @@ nsACString&
|
||||
CanvasLayer::PrintInfo(nsACString& aTo, const char* aPrefix)
|
||||
{
|
||||
Layer::PrintInfo(aTo, aPrefix);
|
||||
if (mFilter != gfxPattern::FILTER_GOOD) {
|
||||
if (mFilter != GraphicsFilter::FILTER_GOOD) {
|
||||
AppendToString(aTo, mFilter, " [filter=", "]");
|
||||
}
|
||||
return aTo;
|
||||
@ -1362,7 +1362,7 @@ nsACString&
|
||||
ImageLayer::PrintInfo(nsACString& aTo, const char* aPrefix)
|
||||
{
|
||||
Layer::PrintInfo(aTo, aPrefix);
|
||||
if (mFilter != gfxPattern::FILTER_GOOD) {
|
||||
if (mFilter != GraphicsFilter::FILTER_GOOD) {
|
||||
AppendToString(aTo, mFilter, " [filter=", "]");
|
||||
}
|
||||
return aTo;
|
||||
|
@ -16,7 +16,7 @@
|
||||
#include "gfxTypes.h"
|
||||
#include "gfxColor.h" // for gfxRGBA
|
||||
#include "gfxMatrix.h" // for gfxMatrix
|
||||
#include "gfxPattern.h" // for gfxPattern, etc
|
||||
#include "GraphicsFilter.h" // for GraphicsFilter
|
||||
#include "gfxPoint.h" // for gfxPoint, gfxIntSize
|
||||
#include "gfxRect.h" // for gfxRect
|
||||
#include "mozilla/Assertions.h" // for MOZ_ASSERT_HELPER2, etc
|
||||
@ -1797,7 +1797,7 @@ public:
|
||||
* CONSTRUCTION PHASE ONLY
|
||||
* Set the filter used to resample this image (if necessary).
|
||||
*/
|
||||
void SetFilter(gfxPattern::GraphicsFilter aFilter)
|
||||
void SetFilter(GraphicsFilter aFilter)
|
||||
{
|
||||
if (mFilter != aFilter) {
|
||||
MOZ_LAYERS_LOG_IF_SHADOWABLE(this, ("Layer::Mutated(%p) Filter", this));
|
||||
@ -1805,7 +1805,7 @@ public:
|
||||
Mutated();
|
||||
}
|
||||
}
|
||||
gfxPattern::GraphicsFilter GetFilter() const { return mFilter; }
|
||||
GraphicsFilter GetFilter() const { return mFilter; }
|
||||
|
||||
MOZ_LAYER_DECL_NAME("CanvasLayer", TYPE_CANVAS)
|
||||
|
||||
@ -1829,7 +1829,7 @@ protected:
|
||||
, mPreTransCallbackData(nullptr)
|
||||
, mPostTransCallback(nullptr)
|
||||
, mPostTransCallbackData(nullptr)
|
||||
, mFilter(gfxPattern::FILTER_GOOD)
|
||||
, mFilter(GraphicsFilter::FILTER_GOOD)
|
||||
, mDirty(false)
|
||||
{}
|
||||
|
||||
@ -1850,7 +1850,7 @@ protected:
|
||||
void* mPreTransCallbackData;
|
||||
DidTransactionCallback mPostTransCallback;
|
||||
void* mPostTransCallbackData;
|
||||
gfxPattern::GraphicsFilter mFilter;
|
||||
GraphicsFilter mFilter;
|
||||
|
||||
private:
|
||||
/**
|
||||
|
@ -31,17 +31,17 @@ AppendToString(nsACString& s, const void* p,
|
||||
}
|
||||
|
||||
nsACString&
|
||||
AppendToString(nsACString& s, const gfxPattern::GraphicsFilter& f,
|
||||
AppendToString(nsACString& s, const GraphicsFilter& f,
|
||||
const char* pfx, const char* sfx)
|
||||
{
|
||||
s += pfx;
|
||||
switch (f) {
|
||||
case gfxPattern::FILTER_FAST: s += "fast"; break;
|
||||
case gfxPattern::FILTER_GOOD: s += "good"; break;
|
||||
case gfxPattern::FILTER_BEST: s += "best"; break;
|
||||
case gfxPattern::FILTER_NEAREST: s += "nearest"; break;
|
||||
case gfxPattern::FILTER_BILINEAR: s += "bilinear"; break;
|
||||
case gfxPattern::FILTER_GAUSSIAN: s += "gaussian"; break;
|
||||
case GraphicsFilter::FILTER_FAST: s += "fast"; break;
|
||||
case GraphicsFilter::FILTER_GOOD: s += "good"; break;
|
||||
case GraphicsFilter::FILTER_BEST: s += "best"; break;
|
||||
case GraphicsFilter::FILTER_NEAREST: s += "nearest"; break;
|
||||
case GraphicsFilter::FILTER_BILINEAR: s += "bilinear"; break;
|
||||
case GraphicsFilter::FILTER_GAUSSIAN: s += "gaussian"; break;
|
||||
default:
|
||||
NS_ERROR("unknown filter type");
|
||||
s += "???";
|
||||
|
@ -7,7 +7,7 @@
|
||||
#define GFX_LAYERSLOGGING_H
|
||||
|
||||
#include "FrameMetrics.h" // for FrameMetrics, etc
|
||||
#include "gfxPattern.h" // for gfxPattern, etc
|
||||
#include "GraphicsFilter.h" // for GraphicsFilter
|
||||
#include "mozilla/gfx/Point.h" // for IntSize, etc
|
||||
#include "mozilla/gfx/Types.h" // for Filter, SurfaceFormat
|
||||
#include "mozilla/layers/CompositorTypes.h" // for TextureFlags
|
||||
@ -35,7 +35,7 @@ AppendToString(nsACString& s, const void* p,
|
||||
const char* pfx="", const char* sfx="");
|
||||
|
||||
nsACString&
|
||||
AppendToString(nsACString& s, const gfxPattern::GraphicsFilter& f,
|
||||
AppendToString(nsACString& s, const GraphicsFilter& f,
|
||||
const char* pfx="", const char* sfx="");
|
||||
|
||||
nsACString&
|
||||
|
@ -107,7 +107,7 @@ RotatedBuffer::DrawBufferQuadrant(gfxContext* aTarget,
|
||||
nsRefPtr<gfxPattern> pattern = new gfxPattern(source);
|
||||
|
||||
#ifdef MOZ_GFX_OPTIMIZE_MOBILE
|
||||
gfxPattern::GraphicsFilter filter = gfxPattern::FILTER_NEAREST;
|
||||
GraphicsFilter filter = GraphicsFilter::FILTER_NEAREST;
|
||||
pattern->SetFilter(filter);
|
||||
#endif
|
||||
|
||||
|
@ -7,7 +7,7 @@
|
||||
#include "composite/CompositableHost.h" // for CompositableHost
|
||||
#include "gfx2DGlue.h" // for ToFilter, ToMatrix4x4
|
||||
#include "gfxImageSurface.h" // for gfxImageSurface
|
||||
#include "gfxPattern.h" // for gfxPattern, etc
|
||||
#include "GraphicsFilter.h" // for GraphicsFilter
|
||||
#include "gfxUtils.h" // for gfxUtils, etc
|
||||
#include "mozilla/gfx/Matrix.h" // for Matrix4x4
|
||||
#include "mozilla/gfx/Point.h" // for Point
|
||||
@ -77,7 +77,7 @@ CanvasLayerComposite::RenderLayer(const nsIntPoint& aOffset,
|
||||
}
|
||||
#endif
|
||||
|
||||
gfxPattern::GraphicsFilter filter = mFilter;
|
||||
GraphicsFilter filter = mFilter;
|
||||
#ifdef ANDROID
|
||||
// Bug 691354
|
||||
// Using the LINEAR filter we get unexplained artifacts.
|
||||
@ -85,7 +85,7 @@ CanvasLayerComposite::RenderLayer(const nsIntPoint& aOffset,
|
||||
gfxMatrix matrix;
|
||||
bool is2D = GetEffectiveTransform().Is2D(&matrix);
|
||||
if (is2D && !matrix.HasNonTranslationOrFlip()) {
|
||||
filter = gfxPattern::FILTER_NEAREST;
|
||||
filter = GraphicsFilter::FILTER_NEAREST;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -240,7 +240,7 @@ CanvasLayerD3D10::RenderLayer()
|
||||
shaderFlags |= mDataIsPremultiplied
|
||||
? SHADER_PREMUL : SHADER_NON_PREMUL | SHADER_RGBA;
|
||||
shaderFlags |= mHasAlpha ? SHADER_RGBA : SHADER_RGB;
|
||||
shaderFlags |= mFilter == gfxPattern::FILTER_NEAREST
|
||||
shaderFlags |= mFilter == GraphicsFilter::FILTER_NEAREST
|
||||
? SHADER_POINT : SHADER_LINEAR;
|
||||
ID3D10EffectTechnique* technique = SelectShader(shaderFlags);
|
||||
|
||||
|
@ -228,7 +228,7 @@ ImageLayerD3D10::RenderLayer()
|
||||
shaderFlags |= LoadMaskTexture();
|
||||
shaderFlags |= hasAlpha
|
||||
? SHADER_RGBA : SHADER_RGB;
|
||||
shaderFlags |= mFilter == gfxPattern::FILTER_NEAREST
|
||||
shaderFlags |= mFilter == GraphicsFilter::FILTER_NEAREST
|
||||
? SHADER_POINT : SHADER_LINEAR;
|
||||
technique = SelectShader(shaderFlags);
|
||||
|
||||
|
@ -210,7 +210,7 @@ CanvasLayerD3D9::RenderLayer()
|
||||
mD3DManager->SetShaderMode(DeviceManagerD3D9::RGBLAYER, GetMaskLayer());
|
||||
}
|
||||
|
||||
if (mFilter == gfxPattern::FILTER_NEAREST) {
|
||||
if (mFilter == GraphicsFilter::FILTER_NEAREST) {
|
||||
device()->SetSamplerState(0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
|
||||
device()->SetSamplerState(0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
|
||||
}
|
||||
@ -224,7 +224,7 @@ CanvasLayerD3D9::RenderLayer()
|
||||
device()->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_ONE);
|
||||
device()->SetRenderState(D3DRS_SEPARATEALPHABLENDENABLE, FALSE);
|
||||
}
|
||||
if (mFilter == gfxPattern::FILTER_NEAREST) {
|
||||
if (mFilter == GraphicsFilter::FILTER_NEAREST) {
|
||||
device()->SetSamplerState(0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR);
|
||||
device()->SetSamplerState(0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR);
|
||||
}
|
||||
|
@ -430,7 +430,7 @@ ImageLayerD3D9::RenderLayer()
|
||||
mD3DManager->SetShaderMode(DeviceManagerD3D9::RGBLAYER, GetMaskLayer());
|
||||
}
|
||||
|
||||
if (mFilter == gfxPattern::FILTER_NEAREST) {
|
||||
if (mFilter == GraphicsFilter::FILTER_NEAREST) {
|
||||
device()->SetSamplerState(0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
|
||||
device()->SetSamplerState(0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
|
||||
}
|
||||
@ -440,7 +440,7 @@ ImageLayerD3D9::RenderLayer()
|
||||
autoLock.Unlock();
|
||||
|
||||
device()->DrawPrimitive(D3DPT_TRIANGLESTRIP, 0, 2);
|
||||
if (mFilter == gfxPattern::FILTER_NEAREST) {
|
||||
if (mFilter == GraphicsFilter::FILTER_NEAREST) {
|
||||
device()->SetSamplerState(0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR);
|
||||
device()->SetSamplerState(0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR);
|
||||
}
|
||||
|
@ -18,7 +18,7 @@
|
||||
#include "gfxCrashReporterUtils.h" // for ScopedGfxFeatureReporter
|
||||
#include "gfxImageSurface.h" // for gfxImageSurface
|
||||
#include "gfxMatrix.h" // for gfxMatrix
|
||||
#include "gfxPattern.h" // for gfxPattern, etc
|
||||
#include "GraphicsFilter.h" // for GraphicsFilter
|
||||
#include "gfxPlatform.h" // for gfxPlatform
|
||||
#include "gfxRect.h" // for gfxRect
|
||||
#include "gfxUtils.h" // for NextPowerOfTwo, gfxUtils, etc
|
||||
@ -1125,7 +1125,7 @@ CompositorOGL::DrawQuad(const Rect& aRect, const Rect& aClipRect,
|
||||
return;
|
||||
}
|
||||
|
||||
gfxPattern::GraphicsFilter filter = ThebesFilter(effectYCbCr->mFilter);
|
||||
GraphicsFilter filter = ThebesFilter(effectYCbCr->mFilter);
|
||||
|
||||
AutoBindTexture bindY(sourceY, LOCAL_GL_TEXTURE0);
|
||||
mGLContext->ApplyFilterToBoundTexture(filter);
|
||||
|
@ -318,7 +318,7 @@ ThebesLayerBufferOGL::RenderTo(const nsIntPoint& aOffset,
|
||||
gfxMatrix matrix;
|
||||
bool is2D = mLayer->GetEffectiveTransform().Is2D(&matrix);
|
||||
if (is2D && !matrix.HasNonTranslationOrFlip()) {
|
||||
gl()->ApplyFilterToBoundTexture(gfxPattern::FILTER_NEAREST);
|
||||
gl()->ApplyFilterToBoundTexture(GraphicsFilter::FILTER_NEAREST);
|
||||
} else {
|
||||
mTexImage->ApplyFilter();
|
||||
}
|
||||
|
@ -318,7 +318,7 @@ nsFontMetrics::DrawString(const char *aString, uint32_t aLength,
|
||||
if (mTextRunRTL) {
|
||||
pt.x += textRun->GetAdvanceWidth(0, aLength, &provider);
|
||||
}
|
||||
textRun->Draw(aContext->ThebesContext(), pt, gfxFont::GLYPH_FILL, 0, aLength,
|
||||
textRun->Draw(aContext->ThebesContext(), pt, DrawMode::GLYPH_FILL, 0, aLength,
|
||||
&provider, nullptr, nullptr);
|
||||
}
|
||||
|
||||
@ -340,7 +340,7 @@ nsFontMetrics::DrawString(const PRUnichar* aString, uint32_t aLength,
|
||||
if (mTextRunRTL) {
|
||||
pt.x += textRun->GetAdvanceWidth(0, aLength, &provider);
|
||||
}
|
||||
textRun->Draw(aContext->ThebesContext(), pt, gfxFont::GLYPH_FILL, 0, aLength,
|
||||
textRun->Draw(aContext->ThebesContext(), pt, DrawMode::GLYPH_FILL, 0, aLength,
|
||||
&provider, nullptr, nullptr);
|
||||
}
|
||||
|
||||
|
@ -269,7 +269,7 @@ RunTest (TestEntry *test, gfxContext *ctx) {
|
||||
}
|
||||
|
||||
gfxFontTestStore::NewStore();
|
||||
textRun->Draw(ctx, gfxPoint(0,0), gfxFont::GLYPH_FILL, 0, length, nullptr, nullptr, nullptr);
|
||||
textRun->Draw(ctx, gfxPoint(0,0), DrawMode::GLYPH_FILL, 0, length, nullptr, nullptr, nullptr);
|
||||
gfxFontTestStore *s = gfxFontTestStore::CurrentStore();
|
||||
|
||||
if (!test->Check(s)) {
|
||||
|
27
gfx/thebes/DrawMode.h
Normal file
27
gfx/thebes/DrawMode.h
Normal file
@ -0,0 +1,27 @@
|
||||
/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#ifndef DrawMode_h
|
||||
#define DrawMode_h
|
||||
|
||||
#include "mozilla/TypedEnum.h"
|
||||
|
||||
// Options for how the text should be drawn
|
||||
MOZ_BEGIN_ENUM_CLASS(DrawMode, int)
|
||||
// GLYPH_FILL and GLYPH_STROKE draw into the current context
|
||||
// and may be used together with bitwise OR.
|
||||
GLYPH_FILL = 1,
|
||||
// Note: using GLYPH_STROKE will destroy the current path.
|
||||
GLYPH_STROKE = 2,
|
||||
// Appends glyphs to the current path. Can NOT be used with
|
||||
// GLYPH_FILL or GLYPH_STROKE.
|
||||
GLYPH_PATH = 4,
|
||||
// When GLYPH_FILL and GLYPH_STROKE are both set, draws the
|
||||
// stroke underneath the fill.
|
||||
GLYPH_STROKE_UNDERNEATH = 8
|
||||
MOZ_END_ENUM_CLASS(DrawMode)
|
||||
|
||||
#endif
|
||||
|
22
gfx/thebes/GraphicsFilter.h
Normal file
22
gfx/thebes/GraphicsFilter.h
Normal file
@ -0,0 +1,22 @@
|
||||
/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#ifndef GraphicsFilter_h
|
||||
#define GraphicsFilter_h
|
||||
|
||||
#include "mozilla/TypedEnum.h"
|
||||
|
||||
MOZ_BEGIN_ENUM_CLASS(GraphicsFilter, int)
|
||||
FILTER_FAST,
|
||||
FILTER_GOOD,
|
||||
FILTER_BEST,
|
||||
FILTER_NEAREST,
|
||||
FILTER_BILINEAR,
|
||||
FILTER_GAUSSIAN,
|
||||
FILTER_SENTINEL
|
||||
MOZ_END_ENUM_CLASS(GraphicsFilter)
|
||||
|
||||
#endif
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user